【动手学深度学习】多层感知机之权重衰减研究详情

目录

🌊1. 研究目的

🌊2. 研究准备

🌊3. 研究内容

🌍3.1 多层感知机权重衰减

🌍3.2 基础练习

🌊4. 研究体会


🌊1. 研究目的

  • 防止过拟合:权重衰减和暂退法都是用来控制模型的复杂度,防止模型在训练集上过拟合;
  • 提高模型泛化能力:通过在训练过程中应用权重衰减或暂退法,可以限制模型对训练数据的过度依赖,从而提高模型在未见过的测试数据上的泛化能力;
  • 研究正则化效果:权重衰减和暂退法都可以看作是对模型的正则化约束,通过实验可以研究不同的正则化方法对于模型训练和性能的影响;
  • 了解特征选择:通过应用权重衰减或暂退法,可以观察到一些权重变得非常小或接近于零。

🌊2. 研究准备

  • 根据GPU安装pytorch版本实现GPU运行研究代码;
  • 配置环境用来运行 Python、Jupyter Notebook和相关库等相关库。

🌊3. 研究内容

启动jupyter notebook,使用新增的pytorch环境新建ipynb文件,为了检查环境配置是否合理,输入import torch以及torch.cuda.is_available() ,若返回TRUE则说明研究​​​​​​​环境配置正确,若返回False但可以正确导入torch则说明pytorch配置成功,但研究运行是在CPU进行的,结果如下:


🌍3.1 多层感知机权重衰减

(1)使用jupyter notebook新增的pytorch环境新建ipynb文件,完成基本数据操作的研究代码与练习结果如下:

导入必要库及模型:

%matplotlib inline
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 = 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)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()net, loss = lambda X: d2l.linreg(X, w, b), d2l.squared_lossnum_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:# 增加了L2范数惩罚项,# 广播机制使l2_penalty(w)成为一个长度为batch_size的向量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)

简洁实现

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)

train_concise(3)


🌍3.2 基础练习

1.在本节的估计问题中使用λ的值进行实验。绘制训练和测试精度关于λ的函数。观察到了什么?

根据提供的代码,可以看出train_concise函数用于训练一个具有正则化的线性回归模型,并绘制训练和测试精度关于正则化参数λ的函数。

为了实验不同的λ值,可以调用train_concise函数,并将不同的λ值作为参数传递给它。在这种情况下,已经提供了两个示例:train_concise(0)和train_concise(3)。

调用train_concise(0)表示没有正则化,而调用train_concise(3)表示使用正则化参数λ的值为3。你可以尝试不同的λ值并观察结果。

以下是绘制训练和测试精度关于λ的函数的代码示例:

import torch
import torch.nn as nn
import matplotlib.pyplot as pltdef 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)train_accuracy = []test_accuracy = []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()train_acc = evaluate_accuracy(net, train_iter)test_acc = evaluate_accuracy(net, test_iter)train_accuracy.append(train_acc)test_accuracy.append(test_acc)print('w的L2范数:', net[0].weight.norm().item())return train_accuracy, test_accuracydef evaluate_accuracy(net, data_iter):correct = 0total = 0for X, y in data_iter:output = net(X)predicted = (output > 0.5).float()correct += (predicted == y).sum().item()total += y.size(0)return correct / totaldef plot_accuracy_lambda(lambda_values):for lambda_val in lambda_values:train_accuracy, test_accuracy = train_concise(lambda_val)plt.plot(range(len(train_accuracy)), train_accuracy, label='Train Accuracy (lambda={})'.format(lambda_val))plt.plot(range(len(test_accuracy)), test_accuracy, label='Test Accuracy (lambda={})'.format(lambda_val))plt.xlabel('Epochs')plt.ylabel('Accuracy')plt.legend()plt.show()# 定义 num_inputs, train_iter, test_iter,这些变量应该在你的代码中有定义
lambda_values = [0, 0.5, 1, 2, 3, 4, 5]
plot_accuracy_lambda(lambda_values)

在上述代码中,lambda_values列表包含了不同的λ值。train_concise函数的输出被修改为返回训练和测试的精度。plot_accuracy_lambda函数使用这些值来绘制训练和测试精度关于λ的函数图像。

通过调用plot_accuracy_lambda(lambda_values),可以观察到不同λ值对训练和测试精度的影响。

2.使用验证集来找到最佳值λ。它真的是最优值吗?这有关系吗?

使用验证集来找到最佳正则化参数λ是一种常见的模型选择方法。在训练过程中,可以尝试不同的λ值,并使用验证集来评估模型在不同λ值下的性能。最终,选择在验证集上性能最好的λ值作为模型的最终正则化参数。

然而,需要注意的是,通过验证集来选择最佳λ并不一定意味着这是绝对最优的值。这是因为验证集是从训练数据中独立出来的,使用它来估计模型在未见过的数据上的泛化能力。因此,验证集中的性能评估并不总是能够完全反映模型在真实数据上的表现。

过度依赖验证集来选择最佳参数可能导致过拟合验证集的问题,也称为“验证集泄漏”。简单来说,当我们反复调整模型或超参数,直到在验证集上得到理想结果时,可能会选择那些在验证集上仅仅是运气好的模型,而这些模型未必在真实数据上表现优秀。

为了解决验证集泄漏的问题,通常采用交叉验证的方法。交叉验证将数据集划分为多个不相交的子集,并多次训练模型,每次使用一个不同的子集作为验证集,其他子集作为训练集。这样可以得到更稳健的性能评估,并减少验证集泄漏的影响。

另外,最终模型的性能并不仅仅取决于正则化参数λ。其他因素,如模型的复杂性、训练数据的质量和数量等,也会影响最终的模型性能。因此,在选择λ时,应该将它作为一个超参数,同时考虑其他超参数和模型选择中的不确定性。

3.如果我们使用$ \sum _ { i } | \omega _ { i } |$作为我们选择的惩罚($ L _ { 1 }$正则化),那么更新方程会是什么样子?

如果使用L1正则化(使用L1范数作为惩罚项),则更新方程会发生变化。正则化项被添加到损失函数中,以对权重进行约束。

在标准的梯度下降算法中,我们通过在梯度更新中加入正则化项来实现L1正则化。更新方程如下:

$ \omega i \leftarrow \omega i - \eta ^ { * } ( \partial L / \partial \omega i + \lambda ^ { * } \sin ( \omega i ) )$

其中:

ω𝑖 是权重的第i个元素 𝜂 是学习率(控制更新的步长) 𝜆 是L1正则化参数(控制正则化的强度) 𝐿 是损失函数 ∂𝐿/∂ω𝑖 是损失函数关于权重ω𝑖的梯度 sign(ω𝑖) 是ω𝑖的符号函数(正数为1,负数为-1,零为0) 更新方程的第二项 𝜆 * sign(ω𝑖) 是L1正则化的关键部分。它对权重进行约束,使得某些权重变为零,从而实现特征选择和稀疏性。

需要注意的是,L1正则化会导致权重稀疏化,即某些权重变为零。这对于特征选择和模型解释性非常有用,可以通过选择重要的特征来提高模型的泛化能力。

更新方程的具体实现可能因使用的深度学习框架而有所不同,但基本的思想是相同的。

4.我们知道$ | | w ^ { 2 } | | w ^ { T } w $。能找到类似的矩阵方程吗(见 2.3.10节 中的Frobenius范数)?

在2.3.10节中,Frobenius范数被定义为矩阵的元素平方和的平方根,即 ||𝑊||_F = sqrt(∑𝑖∑𝑗𝑤_𝑖𝑗^2) ,其中𝑤_𝑖𝑗是矩阵𝑊的元素。

如果希望使用Frobenius范数作为惩罚项来约束权重𝑊,我们可以修改更新方程来实现。对于𝑊的更新方程,可以使用以下形式:

$ W \leftarrow W - \eta ^ { * } ( d L / d W + \lambda ^ { * } W )$

其中:

𝑊 是权重矩阵 𝜂 是学习率(控制更新的步长) 𝜆 是Frobenius范数的正则化参数(控制正则化的强度) 𝐿 是损失函数 𝑑𝐿/𝑑𝑊 是损失函数关于𝑊的梯度 更新方程的第二项 𝜆 * 𝑊 是Frobenius正则化的关键部分。它对权重矩阵𝑊进行约束,使得权重的大小受到限制。

需要注意的是,Frobenius正则化并不会导致权重的稀疏性,它主要用于控制权重的大小。相比于L1正则化和L2正则化,Frobenius正则化在深度学习中的应用相对较少,通常更常见的是使用L1正则化或L2正则化来约束权重。

5.回顾训练误差和泛化误差之间的关系。除了权重衰减、增加训练数据、使用适当复杂度的模型之外,还能想出其他什么方法来处理过拟合?

除了权重衰减、增加训练数据和使用适当复杂度的模型之外,还有一些其他方法可以处理过拟合问题。以下是一些常见的方法:

  • 早停(Early Stopping):在训练过程中,通过监测验证误差的变化,当验证误差不再下降或开始上升时,及时停止训练,防止过拟合。这可以通过保存在训练过程中得到的最佳模型来实现。
  • 数据增强(Data Augmentation):通过对训练数据进行随机变换或扩增,生成新的训练样本。例如,图像分类任务中的随机裁剪、翻转、旋转、缩放等操作可以增加数据的多样性,减少过拟合的风险。
  • Dropout:在训练过程中,以一定的概率随机将神经元的输出置为零,从而随机地丢弃一些神经元,减少神经网络的复杂性。Dropout可以减少神经网络中神经元之间的依赖关系,有助于防止过拟合。
  • 正则化方法:除了权重衰减,还有其他正则化方法可以应用于神经网络。例如,L1正则化、L2正则化、弹性网络(Elastic Net)等,它们通过在损失函数中添加额外的正则化项,限制模型参数的大小,减少过拟合的风险。
  • 模型集成(Model Ensemble):将多个模型的预测结果进行集成,可以通过投票、平均等方式得到最终的预测结果。模型集成可以减少模型的方差,提高模型的泛化能力。
  • 正交化(Orthogonalization):将模型的学习过程分解为两个独立的步骤,一步用于优化训练数据上的训练误差,另一步用于优化验证数据上的泛化误差。这种方法可以帮助确保模型不仅仅是过拟合训练数据,而是能够在未见过的数据上表现良好。

这些方法可以单独使用,也可以结合使用,具体取决于数据和模型的特点。在实际应用中,需要根据具体问题和数据集的特点来选择适合的方法来处理过拟合问题。

6.在贝叶斯统计中,我们使用先验和似然的乘积,通过公式P(w|x)正比于P(x|w)P(x)得到后验。如何得到带正则化的P(w)

在贝叶斯统计中,通常使用正则化项来引入先验概率P(w)。正则化项对参数w的取值进行限制,有助于防止过拟合,特别是在数据较少或特征较多的情况下。

假设我们的模型是一个参数为w的概率模型,数据为x。在贝叶斯统计中,要求参数w的后验概率P(w|x),即给定数据x条件下参数w的概率分布。根据贝叶斯定理,后验概率可以表示为:

P(w|x) ∝ P(x|w) * P(w)

其中,P(x|w)是似然函数,表示在给定参数w下观测数据x的概率;P(w)是先验概率,表示在未观测数据之前参数w的概率分布。

为了引入正则化项,我们可以假设参数w的先验概率P(w)服从某种特定分布,通常我们会选择一个具有特定性质的分布,比如高斯分布。例如,对于L2正则化,我们可以假设参数w的先验概率P(w)服从一个高斯分布,即:

P(w) = N(0, λ^2 * I)

其中,N(0, λ^2 * I)表示均值为0,方差为λ^2的多元高斯分布,I是单位矩阵。

对于L1正则化,我们可以假设参数w的先验概率P(w)服从一个拉普拉斯分布,即:

P(w) = Laplace(0, λ)

其中,Laplace(0, λ)表示均值为0,尺度参数为λ的拉普拉斯分布。

在引入正则化项后,求解参数w的后验概率P(w|x)时,需要将先验概率P(w)乘以似然函数P(x|w),然后归一化,以得到正确的后验概率分布。具体求解过程可以使用贝叶斯推断方法,如马尔可夫链蒙特卡洛(MCMC)等。

总结:在贝叶斯统计中,通过引入正则化项,可以在参数估计过程中考虑先验信息,对参数进行约束,有助于改善模型的泛化能力和鲁棒性。


🌊4. 研究体会

通过这次研究​​​​​​​,我深入学习了多层感知机,解决了分类和回归等问题。在本次实验中,使用Python编写了多层感知机模型,并分别应用了权重衰减和暂退法来观察它们对模型性能的影响。

首先,实现了一个简单的多层感知机模型,包括输入层、隐藏层和输出层。为了进行实验,选择了一个经典的分类问题数据集,并将其划分为训练集和测试集。接着定义了损失函数和优化器,并使用反向传播算法来更新模型的权重和偏置。

接下来,开始尝试权重衰减技术。在训练过程中,我引入了一个权重衰减项,它会惩罚大的权重值。通过调整权重衰减系数,我观察到模型在训练集和测试集上的表现。实验结果显示,适当的权重衰减可以有效减少过拟合,提高模型的泛化能力。

通过本次实验,我深刻理解了权重衰减对于多层感知机模型的重要性和影响。权重衰减技术可以通过惩罚大的权重值来控制模型的复杂度,防止过拟合;而暂退法技术可以通过逐渐减小学习率来提高模型的稳定性和收敛速度。

通过观察模型的权重变化,我发现权重衰减对特征选择起到了一定的作用。在应用权重衰减后,一些权重值会趋近于零或变得非常小,这意味着这些特征对于模型的决策贡献较小。因此,可以根据权重的大小进行特征选择,从而提高模型的解释性和效果。

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

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

相关文章

北大、腾讯强推!DynamiCrafter WebUI 在线教程,无需逐帧记录即可图片变视频

从史前时期开始,人类的祖先就曾以石为笔,在洞穴的石壁描绘出一系列野牛奔跑的分析图,壁画上的动物被叠加了多条腿,用来表现连贯的动作,这或许便是动态视频的最早雏形。 被焚之城的山羊陶碗 时光流转,最初&…

sqli-labs 靶场闯关基础准备、学习步骤、SQL注入类型,常用基本函数、获取数据库元数据

Sqli-labs的主要作用是帮助用户学习如何识别和利用不同类型的SQL注入漏洞,并了解如何修复和防范这些漏洞。 它提供了多个不同的漏洞场景,每个场景都代表了一个特定类型的SQL注入漏洞。 用户可以通过攻击这些场景来学习和实践漏洞利用技术,以及…

【数据结构】二叉树-堆

目录 一.树概念及性质 二.二叉树的概念与实现 三.堆的概念和结构 四.堆的实现 1.向下调整算法 2. 堆的创建 3.向上调整算法 4.堆的删除 五.堆排序 六.堆-源码 一.树概念及性质 树是一种非线性的数据结构,它是由数个节点组成的具有层次关系的集合。之所以叫…

干货 | SDR RFSoC技术框图大放送(附资源)

软件无线电(SDR) 本文参考《Software Defined Radio with Zynq UltraScale RFSoc》,全文共744页。需要的可以给公众号 迪普微科技 发送“SDR”。

【力扣】矩阵中的最长递增路径

一、题目描述 二、解题思路 1、先求出以矩阵中的每个单元格为起点的最长递增路径 题目中说,对于每个单元格,你可以往上,下,左,右四个方向移动。那么以一个单元格为起点的最长递增路径就是:从该单元格往上…

SpringBoot项目启动后访问网页显示“Please sign in“

SpringBoot启动类代码如下 SpringBoot项目启动后访问网页显示"Please sign in",如图 这是一个安全拦截页面,即SpringSecurity认证授权页面,因为SecurityAutoConfiguration是Spring Boot提供的安全自动配置类,也就是说它…

城规跨考地信:你需要知道的几件事

24考研结束,25地信考研的小伙伴也开始准备。 在这期间发现一个现象,城规跨考GIS的讨论度非常高。 对这一点,我并不感到意外,因为随着地产行业的节节败退,很多单位不需要那么多规划人和建筑人,乃至土木人。…

SpringCloud 微服务中网关如何记录请求响应日志?

在基于SpringCloud开发的微服务中,我们一般会选择在网关层记录请求和响应日志,并将其收集到ELK中用作查询和分析。 今天我们就来看看如何实现此功能。 日志实体类 首先我们在网关中定义一个日志实体,用于组装日志对象 Data public class …

使用Java apache commons包五分钟搞定NCR解析(内附源码)

在网上看到很多关于解析NCR(Numeric Character Reference)字符串的java实现,核心都是通过自定义正则表达式来解析,其实org.apache.commons 已经为我们提供了jar包 解决该问题,非常的方便!在这里我就来简单分享一下具体实现方法&am…

这就是英伟达 CEO 黄仁勋所说的人工智能“下一波浪潮”|TodayAI

在台湾一年一度的科技展 COMPUTEX 开幕前的周日,英伟达(Nvidia)首席执行官黄仁勋(Jensen Huang)表示,机器人和“理解物理定律的 AI”将成为下一波技术浪潮。他指出,英伟达目前正在推动生成式人工…

MyBatis核心对象

MyBatis核心类对象主要有俩个: 1:对相关配置文件信息进行封装的Configuration对象 2:用来执行数据库操作的Executor对象。 核心对象----存储类对象Configuration Configuration对象主要有三个作用: 1:封装MyBatis…

Pulsar 社区周报 | No.2024-05-30 | BIGO 百页小册《Apache Pulsar 调优指南》

“ 各位热爱 Pulsar 的小伙伴们,Pulsar 社区周报更新啦!这里将记录 Pulsar 社区每周的重要更新,每周发布。 ” BIGO 百页小册《Apache Pulsar 调优指南》 Hi,Apache Pulsar 社区的小伙伴们,社区 2024 上半年度的有奖问…

AIGC和ChatGPT有什么区别?

AIGC和ChatGPT有什么区别? 首先先解释一下它们各自的概念 什么是AIGC AIGC,全称为Artificial Intelligence Generated Content,中文译为人工智能生成内容。这是一种利用人工智能技术自动生成内容的生产方式。例如,它可以创作出各种形式的内…

基于PHP+MySQL组合开发的同城便民小程序源码系统 房产出租+求职招聘+相亲交友 带完整的安装代码包以及搭建教程

系统概述 在当今信息化高速发展的时代,同城便民小程序已成为城市居民日常生活中不可或缺的一部分。为了满足广大用户的需求,小编给大家分享一款基于PHPMySQL组合开发的同城便民小程序源码系统。该系统集房产出租、求职招聘、相亲交友等多功能于一体&…

微信小程序使用echarts

思路 五个tab公用一个柱状图组件切换tab以及切换时间改变数据,传入子组件,子组件监听数据重新更新点击柱状图显示具体数值每个时间点有两个柱子(高压和低压),柱状图显示高压的最大值到最小值的范围除了血压其余只有一…

Python采集数据处理:利用Pandas进行组排序和筛选

概述 在现代数据处理和分析中,网络爬虫技术变得越来越重要。通过网络爬虫,我们可以自动化地从网页上收集大量的数据。然而,如何高效地处理和筛选这些数据是一个关键问题。本文将介绍如何使用Python的Pandas库对采集到的数据进行组排序和筛选…

基于SpringBoot+Vue研究生志愿填报辅助系统设计和实现(源码+LW+调试文档+讲解等)

💗博主介绍:✌全网粉丝1W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,还…

mp公共字段自动注入

目录 一 什么是公共字段自动注入 二 使用mp实现公共字段自动注入 1.实现步骤 ①导入mp相关依赖 ② 在实体类上给相关字段加上 TableField()注解 ③自定义元数据对象处理器 2.实现原理 一 什么是公共字段自动注入 我们平时在执行更新或者是插入数据功能的时候,…

智绘“水蓝图”,宏电亮相第4届中国(山东)水利科技与生态建设博览会

5月23-25日,第4届中国(山东)水利科技与生态建设博览会在济南黄河国际会展中心成功召开。展会以“人水和谐,生态山东”为主题,围绕智慧水利建设、水环境治理、水生态保护等领域,展示当下水利行业的新技术、新…

红酒:如何正确地储存红酒

云仓酒庄雷盛红酒,以其优良的品质和丰富的口感,深受广大消费者的喜爱。然而,要想让这些美酒能够长时间保持良好的状态,正确的储存方式是必不可少的。下面,云仓酒庄雷盛红酒将为您详细介绍如何正确地储存红酒。 一、合适…