【PyTorch】6.1 正则化之weight_decay
目錄
- 一、正則化與偏差-方差分解
- 1. 偏差和方差
- 2. L1正則和L2正則
- 二、PyTorch中的 L2 正則項 weight decay
- 1. L2 Regularization = weight decay(權值衰減)
任務簡介:
了解正則化中L1和L2(weight decay);了解dropout
詳細說明:
本節第一部分學習正則化的概念,正則化方法是機器學習(深度學習)中重要的方法,它目的在于減小方差。常用的正則化方法有L1和L2正則化,其中L2正則化又稱為weight decay。在pytorch的優化器中就提供了weight decay的實現,本節課將學習weight decay的pytorch實現。
本節第二部分學習深度學習中常見的正則化方法——Dropout,Dropout是簡潔高效的正則化方法,但需要注意其在實現過程中的權值數據尺度問題。本節將詳細學習pytorch中Dropout的實現細節。
一、正則化與偏差-方差分解
正則化:提高模型的泛化能力,降低過擬合的可能[1]^{[1]}[1]。
1. 偏差和方差
例:
很好的擬合了所有的訓練數據,但在驗證集的表現很差,嚴重過擬合。
2. L1正則和L2正則
從L1正則的示例圖中可以看出:當w1=0w^1=0w1=0 時,目標函數的值最小,此時w1w^1w1 這個權重在模型中不起作用,可以刪除,達到了權值稀疏的效果。
二、PyTorch中的 L2 正則項 weight decay
1. L2 Regularization = weight decay(權值衰減)
權值衰減 是一直以來經常被使用的一種抑制過擬合的方法。該方法通過在學習的過程中對大的權重進行懲罰,來抑制過擬合。很多過擬合原本就是因為權重參數取值過大才發生的。為損失函數加上權重的平方范數(L2 范數)。這樣一來,就可以抑制權重變大。λ\lambdaλ 是控制正則化強度的超參數。λ\lambdaλ 設置得越大,對大的權重施加的懲罰就越重[2]^{[2]}[2]。
測試代碼:
hello_pytorch_DIR = os.path.abspath(os.path.dirname(__file__)+os.path.sep+".."+os.path.sep+"..") sys.path.append(hello_pytorch_DIR)from tools.common_tools import set_seed from torch.utils.tensorboard import SummaryWriterset_seed(1) # 設置隨機種子 n_hidden = 200 max_iter = 2000 disp_interval = 200 lr_init = 0.01# ============================ step 1/5 數據 ============================ def gen_data(num_data=10, x_range=(-1, 1)):w = 1.5train_x = torch.linspace(*x_range, num_data).unsqueeze_(1)train_y = w*train_x + torch.normal(0, 0.5, size=train_x.size())test_x = torch.linspace(*x_range, num_data).unsqueeze_(1)test_y = w*test_x + torch.normal(0, 0.3, size=test_x.size())return train_x, train_y, test_x, test_ytrain_x, train_y, test_x, test_y = gen_data(x_range=(-1, 1))# ============================ step 2/5 模型 ============================ class MLP(nn.Module):def __init__(self, neural_num):super(MLP, self).__init__()self.linears = nn.Sequential(nn.Linear(1, neural_num),nn.ReLU(inplace=True),nn.Linear(neural_num, neural_num),nn.ReLU(inplace=True),nn.Linear(neural_num, neural_num),nn.ReLU(inplace=True),nn.Linear(neural_num, 1),)def forward(self, x):return self.linears(x)net_normal = MLP(neural_num=n_hidden) net_weight_decay = MLP(neural_num=n_hidden)# ============================ step 3/5 優化器 ============================ optim_normal = torch.optim.SGD(net_normal.parameters(), lr=lr_init, momentum=0.9) optim_wdecay = torch.optim.SGD(net_weight_decay.parameters(), lr=lr_init, momentum=0.9, weight_decay=1e-2)# ============================ step 4/5 損失函數 ============================ loss_func = torch.nn.MSELoss()# ============================ step 5/5 迭代訓練 ============================writer = SummaryWriter(comment='_test_tensorboard', filename_suffix="12345678") for epoch in range(max_iter):# forwardpred_normal, pred_wdecay = net_normal(train_x), net_weight_decay(train_x)loss_normal, loss_wdecay = loss_func(pred_normal, train_y), loss_func(pred_wdecay, train_y)optim_normal.zero_grad()optim_wdecay.zero_grad()loss_normal.backward()loss_wdecay.backward()optim_normal.step()optim_wdecay.step()if (epoch+1) % disp_interval == 0:# 可視化for name, layer in net_normal.named_parameters():writer.add_histogram(name + '_grad_normal', layer.grad, epoch)writer.add_histogram(name + '_data_normal', layer, epoch)for name, layer in net_weight_decay.named_parameters():writer.add_histogram(name + '_grad_weight_decay', layer.grad, epoch)writer.add_histogram(name + '_data_weight_decay', layer, epoch)test_pred_normal, test_pred_wdecay = net_normal(test_x), net_weight_decay(test_x)# 繪圖plt.scatter(train_x.data.numpy(), train_y.data.numpy(), c='blue', s=50, alpha=0.3, label='train')plt.scatter(test_x.data.numpy(), test_y.data.numpy(), c='red', s=50, alpha=0.3, label='test')plt.plot(test_x.data.numpy(), test_pred_normal.data.numpy(), 'r-', lw=3, label='no weight decay')plt.plot(test_x.data.numpy(), test_pred_wdecay.data.numpy(), 'b--', lw=3, label='weight decay')plt.text(-0.25, -1.5, 'no weight decay loss={:.6f}'.format(loss_normal.item()), fontdict={'size': 15, 'color': 'red'})plt.text(-0.25, -2, 'weight decay loss={:.6f}'.format(loss_wdecay.item()), fontdict={'size': 15, 'color': 'red'})plt.ylim((-2.5, 2.5))plt.legend(loc='upper left')plt.title("Epoch: {}".format(epoch+1))plt.show()plt.close()輸出:
可以看出沒有weight decay的曲線出現了過擬合的現象
進入tensorboard:
沒有L2正則化時,整個權值尺度變化不大
L2正則化后,整個權值的尺度不斷減小
在代碼optim_wdecay.step()設置斷點,step into:
在代碼的d_p.add_(weight_decay, p.data)進行權值衰減,其公式:d_p = d_p + p.data * weight_decay
在代碼p.data.add_(-group['lr'], d_p)進行梯度更新
參考資料:
[1] 百面機器學習 葫蘆娃 著 164頁 L1正則化與稀疏性
[2] 深度學習入門:基于Python的理論與實現 齋藤康毅 著 191頁 6.4正則化
總結
以上是生活随笔為你收集整理的【PyTorch】6.1 正则化之weight_decay的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nginx-反向代理
- 下一篇: 转 OpenGL核心技术之帧缓冲