12.權重衰退(與課程對應)
目錄
一、權重衰退
1、使用均方范數作為硬性限制
2、使用均方范數作為柔性限制(通常這么做)
3、演示對最優解的影響
4、參數更新法則
5、總結
二、代碼實現+從零實現
三、代碼實現+簡介實現
一、權重衰退
1、使用均方范數作為硬性限制
? ? ? ? (1)通過限制參數值的選擇范圍來控制模型容量
? ? ? ? ?????????????????
subject to?
????????????????通常不限制便宜b(限不限制都差不多)
????????????????小的意味著更強的正則項
2、使用均方范數作為柔性限制(通常這么做)
????????(1)對每個,都可以找到
使得之前的目標函數等價于下面
? ? ? ? ? ? ? ? ? ? ? ? min?
? ? ? ? ? ? ? ? 可以通過拉格朗日乘子來證明
? ? ? ? (2)超參數控制了正則項的重要程度
????????????????=0:無作用
????????????????,?
3、演示對最優解的影響
4、參數更新法則
(1)計算梯度
????????
(2)時間t更新參數
????????
? ? ? ? 通常,在深度學習中通常叫做權重衰退
5、總結
(1)權重衰退通過L2正則項使得模型參數不會過大,從而控制模型復雜度
(2)正則項權重是控制模型復雜度的超參數
二、代碼實現+從零實現
1、生成數據集:訓練集越小,越容易過擬合;特征維度200
n_train, n_test, num_inputs, batch_size = 20, 100, 200, 5
true_w, true_b = torch.ones((num_inputs, 1)) * 0.01, 0.05
train_data = d2l.synthetic_data(true_w, true_b, n_train)
train_iter = d2l.load_array(train_data, batch_size)
test_data = d2l.synthetic_data(true_w, true_b, n_test)
test_iter = d2l.load_array(test_data, batch_size, is_train=False)
2、初始化模型參數
def init_params():w = torch.normal(0, 1, size=(num_inputs, 1), requires_grad=True)b = torch.zeros(1, requires_grad=True)return [w, b]
?3、定義L2范數懲罰
def l2_penalty(w):return torch.sum(w.pow(2)) / 2
?4、定義訓練代碼實現
def train(lambd):w, b = init_params() # 初始化權重net, loss = lambda X: d2l.linreg(X, w, b), d2l.squared_loss # 模型,損失num_epochs, lr = 100, 0.003animator = d2l.Animator(xlabel='epochs', ylabel='loss', yscale='log',xlim=[5, num_epochs], legend=['train', 'test']) # 繪制for epoch in range(num_epochs):for X, y in train_iter:l = loss(net(X), y) + lambd * l2_penalty(w)l.sum().backward()d2l.sgd([w, b], lr, batch_size)if (epoch + 1) % 5 == 0:animator.add(epoch + 1, (d2l.evaluate_loss(net, train_iter, loss),d2l.evaluate_loss(net, test_iter, loss)))print('w的L2范數是:', torch.norm(w).item())
?5、忽略正則化直接訓練
train(lambd=0)
d2l.plt.show()
6、使用權重衰減
train(lambd=3)
d2l.plt.show()
7、完整代碼?
import torch
from torch import nn
from d2l import torch as d2l# 權重衰退:從零實現
# 1、生成數據集:訓練集越小,越容易過擬合;特征維度200
n_train, n_test, num_inputs, batch_size = 20, 100, 200, 5
true_w, true_b = torch.ones((num_inputs, 1)) * 0.01, 0.05
train_data = d2l.synthetic_data(true_w, true_b, n_train)
train_iter = d2l.load_array(train_data, batch_size)
test_data = d2l.synthetic_data(true_w, true_b, n_test)
test_iter = d2l.load_array(test_data, batch_size, is_train=False)# 2、初始化模型參數
def init_params():w = torch.normal(0, 1, size=(num_inputs, 1), requires_grad=True)b = torch.zeros(1, requires_grad=True)return [w, b]# 3、定義L2范數懲罰
def l2_penalty(w):return torch.sum(w.pow(2)) / 2# 4、定義訓練代碼實現
def train(lambd):w, b = init_params() # 初始化權重net, loss = lambda X: d2l.linreg(X, w, b), d2l.squared_loss # 模型,損失num_epochs, lr = 100, 0.003animator = d2l.Animator(xlabel='epochs', ylabel='loss', yscale='log',xlim=[5, num_epochs], legend=['train', 'test']) # 繪制for epoch in range(num_epochs):for X, y in train_iter:l = loss(net(X), y) + lambd * l2_penalty(w)l.sum().backward()d2l.sgd([w, b], lr, batch_size)if (epoch + 1) % 5 == 0:animator.add(epoch + 1, (d2l.evaluate_loss(net, train_iter, loss),d2l.evaluate_loss(net, test_iter, loss)))print('w的L2范數是:', torch.norm(w).item())# 忽略正則化直接訓練
train(lambd=0)
d2l.plt.show()# 使用權重衰減
train(lambd=3)
d2l.plt.show()
三、代碼實現+簡介實現
1、生成數據集:訓練集越小,越容易過擬合;特征維度200
n_train, n_test, num_inputs, batch_size = 20, 100, 200, 5
true_w, true_b = torch.ones((num_inputs, 1)) * 0.01, 0.05
train_data = d2l.synthetic_data(true_w, true_b, n_train)
train_iter = d2l.load_array(train_data, batch_size)
test_data = d2l.synthetic_data(true_w, true_b, n_test)
test_iter = d2l.load_array(test_data, batch_size, is_train=False)
2、權重衰退+簡潔實現
def train_concise(wd):net = nn.Sequential(nn.Linear(num_inputs, 1))for param in net.parameters():param.data.normal_()loss = nn.MSELoss(reduction='none')num_epochs, lr = 100, 0.003# 偏置參數沒有衰減trainer = torch.optim.SGD([{"params":net[0].weight, 'weight_decay': wd},{"params":net[0].bias}], lr=lr)animator = d2l.Animator(xlabel='epochs', ylabel='loss', yscale='log',xlim=[5, num_epochs], legend=['train', 'test'])for epoch in range(num_epochs):for X, y in train_iter:trainer.zero_grad()l = loss(net(X), y)l.mean().backward()trainer.step()if (epoch + 1) % 5 == 0:animator.add(epoch + 1,(d2l.evaluate_loss(net, train_iter, loss),d2l.evaluate_loss(net, test_iter, loss)))print('w的L2范數:', net[0].weight.norm().item())
?3、忽略正則化直接訓練
train_concise(0)
d2l.plt.show()
?4、使用權重衰減
train_concise(3)
d2l.plt.show()
5、完整代碼?
import torch
from matplotlib.pyplot import xlabel
from torch import nn
from d2l import torch as d2l# 生成數據集:訓練集越小,越容易過擬合;特征維度200
n_train, n_test, num_inputs, batch_size = 20, 100, 200, 5
true_w, true_b = torch.ones((num_inputs, 1)) * 0.01, 0.05
train_data = d2l.synthetic_data(true_w, true_b, n_train)
train_iter = d2l.load_array(train_data, batch_size)
test_data = d2l.synthetic_data(true_w, true_b, n_test)
test_iter = d2l.load_array(test_data, batch_size, is_train=False)# 權重衰退+簡潔實現
def train_concise(wd):net = nn.Sequential(nn.Linear(num_inputs, 1))for param in net.parameters():param.data.normal_()loss = nn.MSELoss(reduction='none')num_epochs, lr = 100, 0.003# 偏置參數沒有衰減trainer = torch.optim.SGD([{"params":net[0].weight, 'weight_decay': wd},{"params":net[0].bias}], lr=lr)animator = d2l.Animator(xlabel='epochs', ylabel='loss', yscale='log',xlim=[5, num_epochs], legend=['train', 'test'])for epoch in range(num_epochs):for X, y in train_iter:trainer.zero_grad()l = loss(net(X), y)l.mean().backward()trainer.step()if (epoch + 1) % 5 == 0:animator.add(epoch + 1,(d2l.evaluate_loss(net, train_iter, loss),d2l.evaluate_loss(net, test_iter, loss)))print('w的L2范數:', net[0].weight.norm().item())# 忽略正則化直接訓練
train_concise(0)
d2l.plt.show()# 使用權重衰減
train_concise(3)
d2l.plt.show()
如果此文章對您有所幫助,那就請點個贊吧,收藏+關注 那就更棒啦,十分感謝!!!