#coding=utf-8
import torch
from torch import nn
from d2l import torch as d2l
#生成人工数据集
n_train,n_test,num_inputs,batch_size=20,100,200,5
#torch.ones(num_inputs,1)生成全为1的(num_inputs,1)形状的张量
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 init_params():
w=torch.normal(0,1,size=(num_inputs,1),requires_grad=True)
#创建形状为(1,)的全零张量,并且进行梯度跟踪
b=torch.zeros(1,requires_grad=True)
return [w,b]
#定义L2范数惩罚
def l2_penalty(w):
return torch.sum(w.pow(2))/2
#训练代码实现
def train(lambd):
w,b=init_params()
#lambda x,是一种匿名函数,使用在只需要定义一次函数的地方
net ,loss=lambda x:d2l.linreg(x,w,b),d2l.squared_loss
num_epochs,lr=100,0.03
#创建动态图
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:
#with torch.enable_grad():
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)
train(lambd=3)
lambd=0时,没有加入权重衰减
lambd=3时,是加入了权重衰减
关于权重衰减原理的介绍可以参考此篇博客:权重衰减weight_decay参数从入门到精通-优快云博客