《动手学深度学习》(PyTorch版)代码注释 - 8 【Weight_decay_with_zero】

说明

本博客代码来自开源项目:《动手学深度学习》(PyTorch版)
并且在博主学习的理解上对代码进行了大量注释,方便理解各个函数的原理和用途

配置环境

使用环境:python3.8
平台:Windows10
IDE:PyCharm

此节说明

此节对应书本上3.12节
此节功能为:权重衰减的从零实现
由于此节相对复杂,代码注释量较多

代码

# 本书链接https://tangshusen.me/Dive-into-DL-PyTorch/#/chapter03_DL-basics/3.12_weight-decay?id=_3123-%e4%bb%8e%e9%9b%b6%e5%bc%80%e5%a7%8b%e5%ae%9e%e7%8e%b0
# 3.12 权重衰减从零实现
#注释:黄文俊
#邮箱:hurri_cane@qq.com
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
import numpy as np
import sys
sys.path.append("..")
import d2lzh_pytorch as d2l


#定义总体样本数据
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为训练时的输入特征,其包含n_train个样本,即20个
#test_features为检测时的输入特征,其包含n_test个样本,即100个
#可以看到训练样本远少于测试样本,这样容易导致过拟合,下面会通过权重衰减的方法来抑制过拟合
train_features, test_features = features[:n_train, :], features[n_train:, :]
train_labels, test_labels = labels[:n_train], labels[n_train:]


#batch_size为小批量读取的数量
batch_size, num_epochs, 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, shuffle=True)
"""
    torch.utils.data.DataLoader()解释:
    批训练,把数据变成一小批一小批数据进行训练。
    DataLoader就是用来包装所使用的数据,每次抛出一批数据
    从数据库(dataset)中每次抽出batch size个(1个)样本
"""

#从零开始实现权重衰减
def init_params():
    w = torch.randn((num_inputs, 1), requires_grad=True)
    b = torch.zeros(1, requires_grad=True)
    return [w, b]

def l2_penalty(w):
    # print((w**2).sum() / 2)
    return (w**2).sum() / 2


def fit_and_plot(lambd):
    w, b = init_params()
    train_ls, test_ls = [], []
    # times_sum = 0     #记录次数,Debug时用
    for _ in range(num_epochs):
        for X, y in train_iter:
            # times_sum += 1
            # l2_penalty(w)为添加了L2范数惩罚项
            # net(X, w, b)为求X×w+b,即代入参数求模型输出
            # loss求的是模型输出和训练的label(标签)之间的方差
            l = loss(net(X, w, b), y) + lambd * l2_penalty(w)
            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)
        # print(times_sum)
        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())
        #上述循环for _ in range(num_epochs):走完后
        #train_ls的长度为100;test_ls长度也为100
        #之所以都为100,是因为我们设定的num_epochs(迭代次数)为100
        #train_ls和test_ls每个元素表示,在一个迭代后,训练集和测试集的模型偏差大小。
    d2l.semilogy(range(1, num_epochs + 1), train_ls, 'epochs', 'loss',
                 range(1, num_epochs + 1), test_ls, ['train', 'test'])

    print('L2 norm of w:', w.norm().item())


# fit_and_plot(lambd=0)

fit_and_plot(lambd=3)



plt.show()



print("*"*30)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hurri_cane

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值