【深度學習pytorch】正則化


正則化的基本概念之前博客已有記錄, 這里僅對正則化的實現做一點介紹

 

權重衰減(weight decay)

模型的復雜性——如何衡量函數與0的距離——Lp范數

L2正則化線性模型構成經典的嶺回歸(ridge regression)算法, L1正則化線性回歸通常被稱為套索回歸(lasso regression)。實踐中多使用L2范數。

使用L2范數的一個原因是它對權重向量的大分量施加了巨大的懲罰, 這使得學習算法偏向於在大量特征上均勻分布權重的模型。

在實踐中,這可能使它們對單個變量中的觀測誤差更為穩定。 相比之下,L1懲罰會導致模型將權重集中在一小部分特征上, 而將其他權重清除為零。 

 

L2正則化線性模型,使用驗證數據擬合:

                                                

L2正則化回歸的小批量隨機梯度下降更新如下式:

         

 

從零實現

將線性模型從零實現的損失函數做一些修改即可

 

簡潔實現

線性模型從零實現的優化算法需要修改:

trainer = torch.optim.SGD([
    {"params":net[0].weight,'weight_decay': wd},
    {"params":net[0].bias}], lr=lr)

在實例化優化器時直接通過weight_decay指定weight decay超參數。

默認情況下,PyTorch同時衰減權重和偏移。 這里只為權重設置了weight_decay,所以偏置參數b不會衰減。

 

暫退法(dropout)

模型簡單性的另一個角度是平滑性,即函數不應該對其輸入的微小變化敏感。

在訓練過程中,在計算后續層之前向網絡的每一層注入噪聲。 當訓練一個有多層的深層網絡時,注入噪聲只會在輸入-輸出映射上增強平滑性。 這個想法被稱為暫退法(dropout)。

暫退法在前向傳播過程中,計算每一內部層的同時注入噪聲,這已經成為訓練神經網絡的常用技術。 這種方法之所以被稱為暫退法,因為我們從表面上看是在訓練過程中丟棄(drop out)一些神經元。 在整個訓練過程的每一次迭代中,標准暫退法包括在計算下一層之前將當前層中的一些節點置零。

                   

 

 從零實現

import torch
from torch import nn
from d2l import torch as d2l


def dropout_layer(X, dropout):
    assert 0 <= dropout <= 1
    if dropout == 1:
        return torch.zeros_like(X)
    if dropout == 0:
        return X
    mask = (torch.rand(X.shape) > dropout).float()
    return mask * X / (1.0 - dropout)

num_inputs, num_outputs, num_hiddens1, num_hiddens2 = 784, 10, 256, 256
dropout1, dropout2 = 0.2, 0.5
class Net(nn.Module): def __init__(self, num_inputs, num_outputs, num_hiddens1, num_hiddens2, is_training = True): super(Net, self).__init__() self.num_inputs = num_inputs self.training = is_training self.lin1 = nn.Linear(num_inputs, num_hiddens1) self.lin2 = nn.Linear(num_hiddens1, num_hiddens2) self.lin3 = nn.Linear(num_hiddens2, num_outputs) self.relu = nn.ReLU() def forward(self, X): H1 = self.relu(self.lin1(X.reshape((-1, self.num_inputs)))) if self.training == True: H1 = dropout_layer(H1, dropout1) H2 = self.relu(self.lin2(H1)) if self.training == True: H2 = dropout_layer(H2, dropout2) out = self.lin3(H2) return out net = Net(num_inputs, num_outputs, num_hiddens1, num_hiddens2)
num_epochs, lr, batch_size = 10, 0.5, 256 loss = nn.CrossEntropyLoss(reduction='none') train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size) trainer = torch.optim.SGD(net.parameters(), lr=lr) d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

簡潔實現

net = nn.Sequential(nn.Flatten(),
        nn.Linear(784, 256),
        nn.ReLU(),
        nn.Dropout(dropout1),
        nn.Linear(256, 256),
        nn.ReLU(),
        nn.Dropout(dropout2),
        nn.Linear(256, 10))

def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)

net.apply(init_weights)

trainer = torch.optim.SGD(net.parameters(), lr=lr) d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

 


免責聲明!

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



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