权重衰减

关于权重衰减可以看一下我贴上来的的笔记权重衰减
下面时使用高维线性模型来进行权重衰减的实现的jupyter代码

#%%
'''
验证权重衰减的高纬线性回归实验
'''
%matplotlib inline
import torch
import torch.nn as nn
import numpy as np
import sys
sys.path.append("..")
import dlzh.d2lzh_pytorch as d2l

#%%
'''
标签生成函数为 y=0.05+sum(0.01x_i)+noise
其中噪声项noise服从均值为0,标准差为0。01的正态分布
这里为了形成过拟合的情况,所以训练数据集变少设置为20
设置维度为200
'''
n_train,n_test,num_inputs=20,100,200
true_w, true_b = torch.ones(num_inputs, 1) * 0.01, 0.05
features = torch.randn((n_train + n_test, num_inputs))
labels = torch.matmul(features, true_w) + true_b
labels += torch.tensor(np.random.normal(0, 0.01,size=labels.size()), dtype=torch.float)
train_features, test_features = features[:n_train, :],features[n_train:, :]
train_labels, test_labels = labels[:n_train], labels[n_train:]
#%%

'''1. 首先随机初始化模型参数'''
#定义随机初始化模型参数的函数,该函数为每个参数附上梯度
def init_params():
    w=torch.randn((num_inputs,1),requires_grad=True)
    b=torch.zeros(1,requires_grad=True)
    return [w,b]

#%%

'''2. 定义L2范数的惩罚项'''
#这里没有采用矩阵的乘法,因为矩阵的乘法该是多少行多少列实在是太麻烦了
def l2_penalty(w):
    return (w**2).sum()/2


#%%

'''3. 定义和训练模型'''
batch_size,num_enpochs,lr=1,100,0.003
net,loss=d2l.linreg,d2l.squared_loss

dataset=torch.utils.data.TensorDataset(train_features,train_labels)
train_iter=torch.utils.data.DataLoader(dataset,batch_size=batch_size,shuffle=True)

#训练模型,这里唯一的参数就是惩罚项的lamdb参数
def fit_and_plot(lambd):
    w,b=init_params()
    #用来记录训练误差和测试误差
    train_ls,test_ls=[],[]
    for _ in range(num_enpochs):
        for X,y in train_iter:
            y_pre=net(X,w,b)
            l=loss(y_pre,y)+lambd*l2_penalty(w)
            #这里求和是为了后面的反向传播方便,因为使用backward()函数最好是一个值而不是一个tensor
            l=l.sum()
            
            if w.grad is not None:
                w.grad.data.zero_()
                b.grad.data.zero_()
            l.backward()
            d2l.sgd([w,b],lr,batch_size)
        train_ls.append(loss(net(train_features,w,b),train_labels).mean().item())
        test_ls.append(loss(net(test_features,w,b),test_labels).mean().item())
    d2l.semilogy(range(1, num_enpochs + 1), train_ls, 'epochs',
                 'loss',range(1, num_enpochs + 1), test_ls, ['train','test'])
    print('L2 norm of w:', w.norm().item())
#%%
#当不设置lamda参数时
fit_and_plot(0)


#%%

#将lamda参数设置为5的时候
fit_and_plot(5)

这里有几个function用到了自己写的一个库中的function,我把用到的贴上来大家看一下

#这个函数时批量梯度优化函数
def sgd(params, lr, batch_size):
    for param in params:
        param.data -= lr * param.grad / batch_size  # 注意这里更改param时用的param.data
#线性模型
def linreg(X, w, b):
    return torch.mm(X, w) + b
# 平方loss function
def squared_loss(y_hat, y):
    # 注意这里返回的是向量, 另外, pytorch里的MSELoss并没有除以 2
    return ((y_hat - y.view(y_hat.size())) ** 2) / 2

最后一个semilogy是一个画图函数就不贴啦,大家可以自己画自己喜欢的~

发布了36 篇原创文章 · 获赞 3 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/tyro_blog/article/details/104440547