模型層layers
深度學習模型一般由各種模型層組合而成。
torch.nn中內置了非常豐富的各種模型層。它們都屬于nn.Module的子類,具備參數管理功能。
例如:
nn.Linear, nn.Flatten, nn.Dropout, nn.BatchNorm2d
nn.Conv2d,nn.AvgPool2d,nn.Conv1d,nn.ConvTranspose2d
nn.Embedding,nn.GRU,nn.LSTM
nn.Transformer
如果這些內置模型層不能夠滿足需求,我們也可以通過繼承nn.Module基類構建自定義的模型層。
實際上,pytorch不區分模型和模型層,都是通過繼承nn.Module進行構建。
因此,我們只要繼承nn.Module基類并實現forward方法即可自定義模型層。
一,內置模型層
頭文件:
import numpy as np
import torch
from torch import nn
基礎層
nn.Linear:全連接層。參數個數 = 輸入層特征數× 輸出層特征數(weight)+ 輸出層特征數(bias)
nn.Flatten:壓平層,用于將多維張量樣本壓成一維張量樣本。
nn.BatchNorm1d:一維批標準化層。通過線性變換將輸入批次縮放平移到穩定的均值和標準差。可以增強模型對輸入不同分布的適應性,加快模型訓練速度,有輕微正則化效果。一般在激活函數之前使用。可以用afine參數設置該層是否含有可以訓練的參數。
nn.BatchNorm2d:二維批標準化層。
nn.BatchNorm3d:三維批標準化層。
nn.Dropout:一維隨機丟棄層。一種正則化手段。
nn.Dropout2d:二維隨機丟棄層。
nn.Dropout3d:三維隨機丟棄層。
nn.Threshold:限幅層。當輸入大于或小于閾值范圍時,截斷之。
nn.ConstantPad2d: 二維常數填充層。對二維張量樣本填充常數擴展長度。
nn.ReplicationPad1d: 一維復制填充層。對一維張量樣本通過復制邊緣值填充擴展長度。
nn.ZeroPad2d:二維零值填充層。對二維張量樣本在邊緣填充0值.
nn.GroupNorm:組歸一化。一種替代批歸一化的方法,將通道分成若干組進行歸一。不受batch大小限制,據稱性能和效果都優于BatchNorm。
nn.LayerNorm:層歸一化。較少使用。
nn.InstanceNorm2d: 樣本歸一化。較少使用。
卷積網絡相關層
nn.Conv1d:普通一維卷積,常用于文本。參數個數 = 輸入通道數×卷積核尺寸(如3)×卷積核個數 + 卷積核尺寸(如3)
nn.Conv2d:普通二維卷積,常用于圖像。參數個數 = 輸入通道數×卷積核尺寸(如3乘3)×卷積核個數 + 卷積核尺寸(如3乘3) 通過調整dilation參數大于1,可以變成空洞卷積,增大卷積核感受野。 通過調整groups參數不為1,可以變成分組卷積。分組卷積中不同分組使用相同的卷積核,顯著減少參數數量。 當groups參數等于通道數時,相當于tensorflow中的二維深度卷積層tf.keras.layers.DepthwiseConv2D。 利用分組卷積和1乘1卷積的組合操作,可以構造相當于Keras中的二維深度可分離卷積層tf.keras.layers.SeparableConv2D。
nn.Conv3d:普通三維卷積,常用于視頻。參數個數 = 輸入通道數×卷積核尺寸(如3乘3乘3)×卷積核個數 + 卷積核尺寸(如3乘3乘3) 。
nn.MaxPool1d: 一維最大池化。
nn.MaxPool2d:二維最大池化。一種下采樣方式。沒有需要訓練的參數。
nn.MaxPool3d:三維最大池化。
nn.AdaptiveMaxPool2d:二維自適應最大池化。無論輸入圖像的尺寸如何變化,輸出的圖像尺寸是固定的。 該函數的實現原理,大概是通過輸入圖像的尺寸和要得到的輸出圖像的尺寸來反向推算池化算子的padding,stride等參數。
nn.FractionalMaxPool2d:二維分數最大池化。普通最大池化通常輸入尺寸是輸出的整數倍。而分數最大池化則可以不必是整數。分數最大池化使用了一些隨機采樣策略,有一定的正則效果,可以用它來代替普通最大池化和Dropout層。
nn.AvgPool2d:二維平均池化。
nn.AdaptiveAvgPool2d:二維自適應平均池化。無論輸入的維度如何變化,輸出的維度是固定的。
nn.ConvTranspose2d:二維卷積轉置層,俗稱反卷積層。并非卷積的逆操作,但在卷積核相同的情況下,當其輸入尺寸是卷積操作輸出尺寸的情況下,卷積轉置的輸出尺寸恰好是卷積操作的輸入尺寸。在語義分割中可用于上采樣。
nn.Upsample:上采樣層,操作效果和池化相反。可以通過mode參數控制上采樣策略為"nearest"最鄰近策略或"linear"線性插值策略。
nn.Unfold:滑動窗口提取層。其參數和卷積操作nn.Conv2d相同。實際上,卷積操作可以等價于nn.Unfold和nn.Linear以及nn.Fold的一個組合。 其中nn.Unfold操作可以從輸入中提取各個滑動窗口的數值矩陣,并將其壓平成一維。利用nn.Linear將nn.Unfold的輸出和卷積核做乘法后,再使用 nn.Fold操作將結果轉換成輸出圖片形狀。
nn.Fold:逆滑動窗口提取層。
循環網絡相關層
nn.Embedding:嵌入層。一種比Onehot更加有效的對離散特征進行編碼的方法。一般用于將輸入中的單詞映射為稠密向量。嵌入層的參數需要學習。
nn.LSTM:長短記憶循環網絡層【支持多層】。最普遍使用的循環網絡層。具有攜帶軌道,遺忘門,更新門,輸出門。可以較為有效地緩解梯度消失問題,從而能夠適用長期依賴問題。設置bidirectional = True時可以得到雙向LSTM。需要注意的時,默認的輸入和輸出形狀是(seq,batch,feature), 如果需要將batch維度放在第0維,則要設置batch_first參數設置為True。
nn.GRU:門控循環網絡層【支持多層】。LSTM的低配版,不具有攜帶軌道,參數數量少于LSTM,訓練速度更快。
nn.RNN:簡單循環網絡層【支持多層】。容易存在梯度消失,不能夠適用長期依賴問題。一般較少使用。
nn.LSTMCell:長短記憶循環網絡單元。和nn.LSTM在整個序列上迭代相比,它僅在序列上迭代一步。一般較少使用。
nn.GRUCell:門控循環網絡單元。和nn.GRU在整個序列上迭代相比,它僅在序列上迭代一步。一般較少使用。
nn.RNNCell:簡單循環網絡單元。和nn.RNN在整個序列上迭代相比,它僅在序列上迭代一步。一般較少使用。
Transformer相關層
nn.Transformer:Transformer網絡結構。Transformer網絡結構是替代循環網絡的一種結構,解決了循環網絡難以并行,難以捕捉長期依賴的缺陷。它是目前NLP任務的主流模型的主要構成部分。Transformer網絡結構由TransformerEncoder編碼器和TransformerDecoder解碼器組成。編碼器和解碼器的核心是MultiheadAttention多頭注意力層。
nn.TransformerEncoder:Transformer編碼器結構。由多個 nn.TransformerEncoderLayer編碼器層組成。
nn.TransformerDecoder:Transformer解碼器結構。由多個 nn.TransformerDecoderLayer解碼器層組成。
nn.TransformerEncoderLayer:Transformer的編碼器層。
nn.TransformerDecoderLayer:Transformer的解碼器層。
nn.MultiheadAttention:多頭注意力層。
二,自定義模型層
如果Pytorch的內置模型層不能夠滿足需求,我們也可以通過繼承nn.Module基類構建自定義的模型層。
實際上,pytorch不區分模型和模型層,都是通過繼承nn.Module進行構建。
因此,我們只要繼承nn.Module基類并實現forward方法即可自定義模型層。
下面是Pytorch的nn.Linear層的源碼,我們可以仿照它來自定義模型層。
import torch
from torch import nn
import torch.nn.functional as Fclass Linear(nn.Module):__constants__ = ['in_features', 'out_features']def __init__(self, in_features, out_features, bias=True):super(Linear, self).__init__()self.in_features = in_featuresself.out_features = out_featuresself.weight = nn.Parameter(torch.Tensor(out_features, in_features))if bias:self.bias = nn.Parameter(torch.Tensor(out_features))else:self.register_parameter('bias', None)self.reset_parameters()def reset_parameters(self):nn.init.kaiming_uniform_(self.weight, a=math.sqrt(5))if self.bias is not None:fan_in, _ = nn.init._calculate_fan_in_and_fan_out(self.weight)bound = 1 / math.sqrt(fan_in)nn.init.uniform_(self.bias, -bound, bound)def forward(self, input):return F.linear(input, self.weight, self.bias)def extra_repr(self):return 'in_features={}, out_features={}, bias={}'.format(self.in_features, self.out_features, self.bias is not None)
linear = nn.Linear(20, 30)
inputs = torch.randn(128, 20)
output = linear(inputs)
print(output.size())