Pytorch系列:(九)正則與常用歸一化


L1 & L2

L1正則

L1正則算法如下:

\[||x||_1 = \sum_i^n|x_i| \]

其中\(|x_i|\)表示絕對值。

在Pytorch 中,沒有自帶L1正則方法,所以需要手動寫

reg_loss = 0
for param in model.parameters():
    reg_loss += torch.sum(torch.abs(param))
    
loss = criteon(logits,target) 
loss = loss + 0.01 * reg_loss

optimizer.zero_grad()
loss.backward()
optimizer.step()
  

L2正則

L2正則計算方法如下:

\[||x||_2 = \sqrt{\sum_i^n x_i^2} \]

在pytorch中,優化器中再帶L2正則,使用方法如下:直接設定weight_decay 參數即可。

optim = torch.optim.SGD(net.parameters(), lr = 0.0001, momentum = 0.8, weight_decay=1e-2)

模型中常用四種歸一化

在前向傳播過程中,模型的數據會出現分布偏移,使用歸一化可以將偏移進行校正,對中間輸出的值進行歸一化。好處是可以加速模型收斂,而且不用精心設計權重初始化。

BatchNorm

BatchNorm 計算法方法如下:

\[\begin{align*} \mu_B &= \frac{1}{m}\sum_{i=1}^nx_i \\ \sigma_B^2 &= \frac{1}{m}\sum_{i=1}^m(x_i-\mu_B)^2 \\ \hat x_i &=\frac{x_i-\mu_B}{\sqrt{\sigma_B^2+\epsilon}} \\ y_i &= \gamma \hat x_i + \beta = BN_{\gamma,\beta}(x_i) \end{align*} \]

在pytorch中,Batch Normalization 模塊一般放置在激活函數前面。其函數如下:

nn.BatchNorm1d()
nn.BatchNorm2d()
nn.BatchNorm3d()

參數:

num_feature: 樣本的特征數量

eps: 分母修正項

momentum: 指數加權平均,用於計算均值方差

affine: 是否要進行affine transform ,意思是是否計算 \(y_i = \gamma \hat x_i + \beta\)

track_running_stats: 表示是否估計新的均值和方差,如果是訓練階段,會計算每一個batch的的均值和方差,如果是測試階段,均值和方差是固定的。

Batch中的主要屬性:

running_mean:均值

running_var:方差

weight: affine transform 中的 gamma, 既\(\gamma\)

bias : affine transform中的beta, 既\(\beta\)

需要注意的是,如果設置了momentum,那么均值的計算會考慮上次的均值

\[\begin{align*} running\_mean &= (1-momentum)*pre\_running\_mean + momentum* \mu_B \\ running\_var &=(1-momentum)*pre\_running\_var+momentum*\sigma_B^2 \end{align*} \]

BatchNorm 的核心是,對於每一個batch的數據,假設有N個特征,這個N個特征中,對應位置的特征,會被BatchNorm放到一起計算,對於1D,2D,和3D ,唯一的區別就是計算的時候,特征的維度。具體來說:

# 這里每一個特征維度是1維,尺寸為N 
input(BatchNorm1D) : ( batch , num_features, 1*N)

# 這里每一個特征的維度是2維度,常用於圖像,對應featrue map的長和寬
input(BatchNorm2D) : ( batch , num_features, width, height) 
# 這里每一個特征的維度是3維度,常用語3位數據,可以理解為多個圖像,
# 既num_of_wh個圖像
input: (batch, num_features, width, height, num_of_wh) 

Layer Normalization

Layer Normalization 主要是針對於1維變長序列數據,例如,在自然語言處理中,每一個batch中,句子的長度不一樣,這個時候,Layer Normalization就可以用於這種情況,LayerNorm主要計算的是一個batch中,每一個句子自己去做計算,也就是說,每一個樣本中,N個特征自己去計算均值和方差,而不是batch之間去計算。 對應於CNN的話,假設每個batch,有N個feature map,然后LayerNorm就是計算每個Batch里面,這個N個feature_map的均值和方差。

Pytorch中對應得LayerNorm函數如下:

nn.LayerNorm()

參數:

normalized_shape: 每一層的形狀,也就是長度

eps: 分母修正項

elementwise_affine: 是否需要affine transform

LayerNorm 計算和BatchNorm計算基本一樣,區別是,LayerNorm 不是跨batch進行計算的,因此,也就不再有running_mean 和 runing_var了。

在使用的時候,Layer需要注意的是,設置normalized_shape, 其實就是設置特征的尺寸,這個和BatchNorm不同,BatchNorm主要設置的是特征的個數。另外,這里的LayerNorm也可以處理不同維度特征,只需要設置特征的尺寸就可以了。具體使用方式如下:

# input 1D : (batch, seq_len, N)  主要針對序列數據,每句話長度為seq_len,維度為N,這個時候
# LayerNorm需要將normalized_shape設置成N
layer_norm = nn.LayerNorm((N),eps=0.0001,elementwise_affine=True)


# input2D : (batch, num, width, height) 主要針對圖像數據,有num個feature map,
# 尺寸為(width, height)
layer_norm  = nn.LayerNorm((width,height),eps=0.0001,elementwise_affine=True)

# input3D : (batch, num, width, height, num_of_wh)
layer_norm = nn.LayerNorm((width,height,num_of_wh),eps=0.0001,elementwise_affine=True)

Group Normalization

第三個是Group Normalization,這里的batch是2,所以估計的均值方差都很小,所以就可以考慮用特征來求均值方差,這個的gamma和beta還是對應於特征數

Group Normalization和LayerNorm比較相似,只不過,LayerNrom使用所有特征進行計算的,而Group是對特征進行分組計算。

pytorch中對應的函數,這里的num_channels對應的是特征數

nn.GroupNorm()

參數:

num_groups: 分組的個數

num_channels: 通道數,也可以理解為特征的個數

eps : 分母修正項

affine: 是否需要計算affine transform

需要注意的是,這里也不會計算running_mean 和 running_var.

Instance Normalization

Instance Normalization計算方式如下所示,每一個樣本有三個特征,每一個特征自己去計算一個均值方差,所以稱為instance Normalization,這個主要用於風格遷移任務中。從卷積網絡的角度來理解,就是每一個feature map 自己單獨計算均值和方差,這里需要注意的是,輸入的參數和BatchNorm一樣,也是輸入特征數量,每一個特征單獨計算的時候,也會加權之前對應位置特征的均值和方差。具體的用法和BatchNorm 一樣。

nn.InstanceNorm()

參數:這和上面的BatchNorm參數是一樣的

num_features: 樣本中有多少特征

eps: 分母修正項

momentum: 指數加權計算均值方差

affine: 是否進行affine transofrm

track_running_stats: 是否重新計算均值方差。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM