文章目錄
- 1. nn.Module
- 2. nn.functional
- 2.1 基本用法
- 2.2 常用函數
- 3. nn.Module 與 nn.functional
- 3.1 主要區別
- 3.2 具體樣例:nn.ReLU() 與 F.relu()
- 參考資料
1. nn.Module
在PyTorch中,nn.Module 類扮演著核心角色,它是構建任何自定義神經網絡層、復雜模塊或完整神經網絡架構的基礎構建塊。通過繼承 nn.Module 并在其子類中定義模型結構和前向傳播邏輯(forward() 方法),開發者能夠方便地搭建并訓練深度學習模型。
關于 nn.Module
的更多介紹可以參考博客:PyTorch之nn.Module、nn.Sequential、nn.ModuleList使用詳解
這里,我們基于nn.Module
創建一個簡單的神經網絡模型,實現代碼如下:
import torch
import torch.nn as nnclass MyModel(nn.Module):def __init__(self, input_size, hidden_size, output_size):super(MyModel, self).__init__()self.layer1 = nn.Linear(input_size, hidden_size)self.layer2 = nn.Linear(hidden_size, output_size)def forward(self, x):x = torch.relu(self.layer1(x))x = self.layer2(x)return x
2. nn.functional
nn.functional
是PyTorch中一個重要的模塊,它包含了許多用于構建神經網絡的函數。與 nn.Module
不同,nn.functional
中的函數不具有可學習的參數。這些函數通常用于執行各種非線性操作、損失函數、激活函數等。
2.1 基本用法
如何在神經網絡中使用nn.functional?
在PyTorch中,你可以輕松地在神經網絡中使用 nn.functional
函數。通常,你只需將輸入數據傳遞給這些函數,并將它們作為網絡的一部分。
以下是一個簡單的示例,演示如何在一個全連接神經網絡中使用ReLU激活函數:
import torch.nn as nn
import torch.nn.functional as Fclass MyModel(nn.Module):def __init__(self):super(MyModel, self).__init__()self.fc1 = nn.Linear(64, 128)self.fc2 = nn.Linear(128, 10)def forward(self, x):x = F.relu(self.fc1(x))x = self.fc2(x)return x
在上述示例中,我們首先導入nn.functional 模塊,然后在網絡的forward 方法中使用F.relu 函數作為激活函數。
nn.functional
的主要優勢是它的計算效率和靈活性,因為它允許你以函數的方式直接調用這些操作,而不需要創建額外的層。
2.2 常用函數
(1)激活函數
激活函數是神經網絡中的關鍵組件,它們引入非線性性,使網絡能夠擬合復雜的數據。以下是一些常見的激活函數:
- ReLU(Rectified Linear Unit)
ReLU是一種簡單而有效的激活函數,它將輸入值小于零的部分設為零,大于零的部分保持不變。它的數學表達式如下:
output = F.relu(input)
- Sigmoid
Sigmoid函數將輸入值映射到0和1之間,常用于二分類問題的輸出層。它的數學表達式如下:
output = F.sigmoid(input)
- Tanh(雙曲正切)
Tanh函數將輸入值映射到-1和1之間,它具有零中心化的特性,通常在循環神經網絡中使用。它的數學表達式如下:
output = F.tanh(input)
(2)損失函數
損失函數用于度量模型的預測與真實標簽之間的差距。PyTorch的nn.functional 模塊包含了各種常用的損失函數,例如:
- 交叉熵損失(Cross-Entropy Loss)
交叉熵損失通常用于多分類問題,計算模型的預測分布與真實分布之間的差異。它的數學表達式如下:
loss = F.cross_entropy(input, target)
- 均方誤差損失(Mean Squared Error Loss)
均方誤差損失通常用于回歸問題,度量模型的預測值與真實值之間的平方差。它的數學表達式如下:
loss = F.mse_loss(input, target)
- L1 損失
L1損失度量預測值與真實值之間的絕對差距,通常用于稀疏性正則化。它的數學表達式如下:
loss = F.l1_loss(input, target)
(3)非線性操作
nn.functional 模塊還包含了許多非線性操作,如池化、歸一化等。
- 最大池化(Max Pooling)
最大池化是一種用于減小特征圖尺寸的操作,通常用于卷積神經網絡中。它的數學表達式如下:
output = F.max_pool2d(input, kernel_size)
- 批量歸一化(Batch Normalization)
批量歸一化是一種用于提高訓練穩定性和加速收斂的技術。它的數學表達式如下:
output = F.batch_norm(input, mean, std, weight, bias)
3. nn.Module 與 nn.functional
3.1 主要區別
nn.Module 與 nn.functional 的主要區別在于:
- nn.Module實現的layers是一個特殊的類,都是由class Layer(nn.Module)定義,會自動提取可學習的參數;
- nn.functional中的函數更像是純函數,由def function(input)定義。
注意:
- 如果模型有可學習的參數時,最好使用nn.Module。
- 激活函數(ReLU、sigmoid、Tanh)、池化(MaxPool)等層沒有可學習的參數,可以使用對應的functional函數。
- 卷積、全連接等有可學習參數的網絡建議使用nn.Module。
- dropout沒有可學習參數,但建議使用nn.Dropout而不是nn.functional.dropout。
3.2 具體樣例:nn.ReLU() 與 F.relu()
nn.ReLU() :
import torch.nn as nn
'''
nn.ReLU()
F.relu():
import torch.nn.functional as F
'''
out = F.relu(input)
其實這兩種方法都是使用relu激活,只是使用的場景不一樣,F.relu()是函數調用,一般使用在foreward函數里。而nn.ReLU()是模塊調用,一般在定義網絡層的時候使用。
當用print(net)輸出時,nn.ReLU()會有對應的層,而F.ReLU()是沒有輸出的。
import torch.nn as nn
import torch.nn.functional as Fclass NET1(nn.Module):def __init__(self):super(NET1, self).__init__()self.conv = nn.Conv2d(3, 16, 3, 1, 1)self.bn = nn.BatchNorm2d(16)self.relu = nn.ReLU() # 模塊的激活函數def forward(self, x):out = self.conv(x)x = self.bn(x)out = self.relu()return outclass NET2(nn.Module):def __init__(self):super(NET2, self).__init__()self.conv = nn.Conv2d(3, 16, 3, 1, 1)self.bn = nn.BatchNorm2d(16)def forward(self, x):x = self.conv(x)x = self.bn(x)out = F.relu(x) # 函數的激活函數return outnet1 = NET1()
net2 = NET2()
print(net1)
print(net2)
參考資料
- PyTorch的nn.Module類的詳細介紹
- PyTorch
nn.functional
模塊詳解:探索神經網絡的魔法工具箱 - pytorch:F.relu() 與 nn.ReLU() 的區別