pytorch学习——正则化技术——权重衰减

news2024/10/6 16:22:37

一、概念介绍

 

        权重衰减(Weight Decay)是一种常用的正则化技术,它通过在损失函数中添加一个惩罚项来限制模型的复杂度,从而防止过拟合。 

        在训练参数化机器学习模型时, 权重衰减(weight decay)是最广泛使用的正则化的技术之一, 它通常也被称为L2正则化。

1.1理解:

权重衰减(weight_decay)本质上是一个L2正则化系数

那什么是参数的正则化?从我的理解上,就是让参数限定在一定范围,目的是为了不让模型对训练集过拟合。

注:应对过拟合最好的方法还是扩大有效样本(但成本过高)

1.2如何控制模型容量?

1.将模型变得比较小,减少里面参数的数量

2.缩小参数的取值范围

注:权重衰退就是通过限制参数的取值来实现

1.3硬性限制

即使得w的每个项的平方都小于θ这个值,最强情况下就是θ等于0,即所有w都等于0

1.4柔性限制

 即损失函数后面加了一个非负项,为了使损失函数最小化,就得使得后面项足够小——起到限制w的作用,相比于硬性限制,柔性限制并没有将w的值限制在一个固定范围内。

1.5图解对最优解的影响

 

 上式为不加限制条件的最优解,即图中的绿色中心点,但该点会使得||w||^2这一项较大,其和并不是最优解。

而加上限制的最优点即为图中两曲线的交叉点

1.6更新参数法则

 

 1.7总结

   ~权重衰减是通过L2正则项使得模型参数不会过大,从而控制复杂度

   ~正则项权重是控制模型复杂度的超参数

二、示例演示

2.1模型构造

生成公式如下:

# 导入需要的库
import torch
from torch import nn
from d2l import torch as d2l

# 定义训练和测试数据集的大小,输入特征的维度和批次大小
n_train, n_test, num_inputs, batch_size = 20, 100, 200, 5

# 定义真实的权重true_w和偏差true_b,并将其初始化为0.01和0.05
true_w, true_b = torch.ones((num_inputs, 1)) * 0.01, 0.05

# 使用d2l.synthetic_data函数生成训练数据train_data和测试数据test_data
# 生成的数据是通过真实的权重和偏差加上一些噪声生成的
train_data = d2l.synthetic_data(true_w, true_b, n_train)
test_data = d2l.synthetic_data(true_w, true_b, n_test)

# 使用d2l.load_array函数将训练数据train_data和测试数据test_data
# 转换为数据迭代器train_iter和test_iter
train_iter = d2l.load_array(train_data, batch_size)
test_iter = d2l.load_array(test_data, batch_size, is_train=False)

2.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]
# 初始化模型参数w和b
# w的形状为(num_inputs, 1),从正态分布中随机生成
# b初始化为0
# 参数需要计算梯度,requires_grad参数被设置为True
# 返回一个包含w和b的列表

2.3定义L2范数

def l2_penalty(w):
    return torch.sum(w.pow(2)) / 2

2.4定义训练代码实现

        下面的代码将模型拟合训练数据集,并在测试数据集上进行评估。

函数的具体实现如下:

  1. 首先通过init_params()函数初始化模型参数w和b。

  2. 定义net函数为线性回归模型,loss为平方损失函数。

  3. 设置训练的轮数num_epochs和学习率lr,同时创建一个可视化工具animator,用于可视化训练过程中的损失值。

  4. 在每个epoch中,遍历训练数据集train_iter,对每个小批量数据(X, y)进行如下操作:

    • 计算模型的输出net(X),并计算损失函数loss(net(X), y)。

    • 加上L2范数惩罚项lambd * l2_penalty(w),其中l2_penalty(w)为权重w的L2范数。

    • 对损失函数进行反向传播,并使用SGD来更新模型参数w和b。

  5. 每5个epoch,计算训练集和测试集上的损失值,并使用animator将损失值可视化。

  6. 训练结束后,输出模型参数w的L2范数。

# 带有L2正则化的线性回归训练过程
# lambd表示L2正则化的强度

# 初始化模型参数w和b
w, b = init_params()

# 定义线性回归模型net和平方损失函数loss
net, loss = lambda X: d2l.linreg(X, w, b), d2l.squared_loss

# 设置训练的轮数num_epochs和学习率lr
# 创建一个可视化工具animator,用于可视化训练过程中的损失值
num_epochs, lr = 100, 0.003
animator = d2l.Animator(xlabel='epochs', ylabel='loss', yscale='log',
                        xlim=[5, num_epochs], legend=['train', 'test'])

# 在每个epoch中,遍历训练数据集train_iter,对每个小批量数据(X, y)进行如下操作:
for epoch in range(num_epochs):
    for X, y in train_iter:
        # 计算模型的输出net(X),并计算损失函数loss(net(X), y)
        # 加上L2范数惩罚项lambd * l2_penalty(w),其中l2_penalty(w)为权重w的L2范数
        # 对损失函数进行反向传播,并使用SGD来更新模型参数w和b
        l = loss(net(X), y) + lambd * l2_penalty(w)
        l.sum().backward()
        d2l.sgd([w, b], lr, batch_size)

    # 每5个epoch,计算训练集和测试集上的损失值,并使用animator将损失值可视化
    if (epoch + 1) % 5 == 0:
        animator.add(epoch + 1, (d2l.evaluate_loss(net, train_iter, loss),
                                 d2l.evaluate_loss(net, test_iter, loss)))

# 训练结束后,输出模型参数w的L2范数
print('w的L2范数是:', torch.norm(w).item())

 2.5训练结果展示

        在这段代码中,lambd是一个超参数,表示L2正则化的强度。在每个小批量数据的损失函数中,会加上L2范数惩罚项,以控制模型的复杂度和防止过拟合。L2正则化的强度由超参数lambd控制,lambd越大,模型的复杂度就越小,对训练数据的拟合程度就越差,但是可以更好地控制过拟合。反之,lambd越小,模型的复杂度就越大,对训练数据的拟合程度就越好,但是可能会过拟合。在模型训练过程中,我们通常会使用交叉验证等技术来选择最优的超参数lambd。

2.5.1忽略正则化直接训练

        其中用lambd = 0禁用权重衰减后运行这个代码。 注意,虽然训练误差有了减少,但测试误差没有减少, 这意味着出现了严重的过拟合。

 2.5.2使用权重衰减

        下面,我们使用权重衰减来运行代码。 注意,在这里训练误差增大,但测试误差减小。 得到预期效果。

 三.简洁实现代码

# 导入需要的库
import torch
from torch import nn
from d2l import torch as d2l

def train_concise(wd):
    # 定义训练和测试数据集的大小,输入特征的维度和批次大小
    n_train, n_test, num_inputs, batch_size = 20, 100, 200, 5

    # 使用nn.Sequential定义了一个单层全连接神经网络net
    # 并将其参数使用param.data.normal_()方法初始化为随机值
    net = nn.Sequential(nn.Linear(num_inputs, 1))
    for param in net.parameters():
        param.data.normal_()

    # 使用nn.MSELoss定义平方损失函数loss
    # 该损失函数的reduction参数设置为'none',表示不对损失值进行降维
    loss = nn.MSELoss(reduction='none')

    # 设置训练的轮数num_epochs和学习率lr
    # 使用torch.optim.SGD定义一个优化器trainer,该优化器的参数包括网络的权重和偏差,以及权重衰减系数wd
    num_epochs, lr = 100, 0.003
    trainer = torch.optim.SGD([
        {"params":net[0].weight,'weight_decay': wd},
        {"params":net[0].bias}], lr=lr)

    # 创建一个可视化工具animator,用于可视化训练过程中的损失值
    animator = d2l.Animator(xlabel='epochs', ylabel='loss', yscale='log',
                            xlim=[5, num_epochs], legend=['train', 'test'])

    # 在每个epoch中,遍历训练数据集train_iter,对每个小批量数据(X, y)进行如下操作:
    for epoch in range(num_epochs):
        for X, y in train_iter:
            # 将优化器trainer的梯度清零
            # 计算模型的输出net(X),并计算损失函数loss(net(X), y)
            # 对损失函数进行反向传播,并使用优化器trainer来更新模型参数
            trainer.zero_grad()
            l = loss(net(X), y)
            l.mean().backward()
            trainer.step()
        # 每5个epoch,计算训练集和测试集上的损失值,并使用animator将损失值可视化。
            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)    #lambd设置为0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/817032.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaEE初阶】Servlet(四) Cookie Session

文章目录 1. Cookie && Session1.1 Cookie && Session1.2 Servlet会话管理操作 1. Cookie && Session 1.1 Cookie && Session Cookie是什么? Cookie是浏览器提供的持久化存储数据的机制.Cookie从哪里来? Cookie从服务器返回给浏览器. 服务…

生产中出现CPU或者内存飙升如何进行解决

文章目录 定位CPU标高内存问题JVM参数工具 定位CPU标高 方法1: 1-启动:java -jar 2_cpu-0.0.1-SNAPSHOT.jar 8 > log.file 2>&1 & 2-一般来说,应用服务器通常只部署了java应用,可以top一下先确认,是否是…

Java 错误异常介绍(Exceptions)

1、异常介绍 异常是程序执行期间发生的意外事件。它影响程序指令流,从而导致程序异常终止。 发生异常的原因有很多。其中包括: 无效的用户输入 设备故障 网络连接丢失 物理限制(磁盘内存不足) 代码错误 打开一个不可用的文…

第四章:C语言的条件分支控制结构

文章目录 1、分支控制if..else...2、分支控制if..else if...else...(嵌套)3、Switch4、goto 1、分支控制if…else… 标准格式:if{}else{} {}里面的语句表示条件是否成立再决定是否执行 2、分支控制if…else if…else…(嵌套) 标准格式:if{}else if{}…

无人机调试笔记——常见参数

无人机的PID调试以及速度相关参数 1、Multicopter Position Control主要是用来设置无人机的各种速度和位置参数。调试顺序是先调试内环PID,也就是无人机的速度闭环控制,确认没有问题后再进行外环位置控制,也就是定点模式控制。 2、调试的时…

CentOS7.3 安装 docker

亲测、截图 阿里云服务器 文章目录 更新源2345 启动开机自启 更新源 sudo yum update -y2 sudo yum install -y yum-utils device-mapper-persistent-data lvm23 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo4 sudo yum …

一款介于无代码和低代码之间的数据可视化平台

一、前言 随着企业数字化拉开序幕,低代码( Low Code Development)开发的概念开始火起来,即用少量的代码就能开发复杂的业务系统。然后更进一步,由此又催生出一个新的概念:无代码开发( No Code Development)。 低代码和无代码开发平…

【C++从0到王者】第十四站:list基本使用及其介绍

文章目录 一、list基本介绍二、list基本使用1.尾插头插接口使用2.insert接口使用3.查找某个值所在的位置4.erase接口使用以及迭代器失效5.reverse6.sort7.merge8.unique9.remove11.splice 三、list基本使用完整代码 一、list基本介绍 如下所示,是库里面对list的基本…

自然语言处理学习笔记(一)————概论

目录 1.自然语言处理概念 2.自然语言与编程语言的比较 (1)词汇量: (2)结构化: (3)歧义性: (4)容错性: (5&#xff0…

【143. 重排链表】

来源:力扣(LeetCode) 描述: 给定一个单链表 L 的头节点 head ,单链表 L 表示为: L0 → L1 → … → Ln - 1 → Ln 请将其重新排列后变为: L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 不…

Redis (一)消息订阅和发送测试

〇、redis 配置 1、概况 本文基于 Ubuntu20.04 云服务器配置Redis,且在本地进行 Redis 测试。 2、目录概况 一、配置文件 位于 /config/app.yml 中,目的用于 Redis 初始化: redis:addr: "39.104.**.28:6379"password: "p…

盛元广通实验室教学仪器设备综合信息管理系统LIMS

实验室作为学生以及教师进行科研教学环境,对于实验室设备的使用情况、维护、借还、台账管理、盘点、报废等需要得到有效的管理,以促进科研教学工作的高质量开展,介于传统手动管理方式越发不能满足现代科研的飞速发展需要,实验室的…

【element-plus】 table表格每行圆角解决方案 element也通用

系列文章目录 【Vue3ViteTselement-plus】使用tsx实现左侧栏菜单无限层级封装 前言 我们在使用element-plus或element 的table时是否有时UI给到的UI效果是如下面这样的,但是我们翻遍了组件库的文档 调整了很多次样式 发现在 左右侧栏固定的时候 普通的方法是完全…

二阶阻尼弹簧系统的simulink仿真(s函数)

文章目录 前言一.非线性反步法1.原系统对应的s函数脚本文件(仅修改模板的初始化函数、导数函数和输出函数三个部分)2.控制器对应的s函数脚本文件(仅修改模板的初始化函数和输出函数两个部分)3.其他参数脚本文件4.输入5.输出&#…

【Git系列】分支操作

🐳分支操作 🧊1. 什么是分支🧊2. 分支的好处🧊3. 分支操作🪟3.1 查看分支🪟3.2 创建分支🪟3.3 切换分支 🧊4. 分支冲突🪟4.1 环境准备🪟4.2 分支冲突演示 &am…

NPP及碳源、碳汇模拟,python蒸散发与植被总初级生产力估算

CASA模型是一个基于过程的遥感模型(Potteret al,1993;Potter et al,1994),耦合了生态系统生产力和土壤碳、氮通量,由网格化的全球气候、辐射、土壤和遥感植被指数数据集驱动。模型包括土壤有机物、微量气体通量、养分利…

DelphiZXingQRCode 库:轻松集成二维码生成功能到 Delphi 项目中

一、下载地址:GitHub - foxitsoftware/DelphiZXingQRCode: Delphi port of QR Code functionality from ZXing, a barcode image processing library. 二、使用步骤: 1)引用单元文件。 //引用单元 usesDelphiZXIngQRCode2)编写…

AD21 PCB设计的高级应用(五)模块复用的操作

(五)模块复用的操作 1.利用Room实现相同模块复用2.复制粘贴功能实现模块复用 1.利用Room实现相同模块复用 本小节介绍 Altium Designer 两种常用模块复用方法:一种是利用 Room 实现相同模块复用,另一种是利用复制粘贴功能实现。 1.利用Room实现相同模块…

《面试1v1》Kafka的ack机制

🍅 作者简介:王哥,CSDN2022博客总榜Top100🏆、博客专家💪 🍅 技术交流:定期更新Java硬核干货,不定期送书活动 🍅 王哥多年工作总结:Java学习路线总结&#xf…

数组的使用(逆序、冒泡)

内存连续数据类型相同从0开始索引 找出数组中的最大值 #include <iostream> #include <stdlib.h> //随机数所在文件 using namespace std;int main() {int arr[5]{104,134,145,129,89};//初始化没有填的为0 int max0;for(int i0;i<5;i){if(arr[i]>max){ma…