李沐《动手学深度学习》多层感知机 深度学习相关概念

系列文章

李沐《动手学深度学习》预备知识 张量操作及数据处理
李沐《动手学深度学习》预备知识 线性代数及微积分
李沐《动手学深度学习》线性神经网络 线性回归
李沐《动手学深度学习》线性神经网络 softmax回归
李沐《动手学深度学习》多层感知机 模型概念和代码实现

目录

  • 系列文章
  • 一、模型选择、欠拟合和过拟合
    • (一)训练误差和泛化误差
    • (二)模型选择:验证集
    • (三)欠拟合与过拟合
  • 二、过拟合的解决
    • (一)权重衰减:正则化
    • (二)暂退法dropout
  • 三、前向传播和反向传播
  • 四、数值稳定性和模型初始化
    • (一)梯度消失和梯度爆炸
    • (二)参数初始化
  • 五、环境和分布偏移
    • (一)分布偏移的类型
    • (二)分布偏移纠正
    • (三)学习问题的分类法
    • (四)机器学习中的公平、责任和透明度


教材:李沐《动手学深度学习》

一、模型选择、欠拟合和过拟合

(一)训练误差和泛化误差

  • 训练误差:模型在训练数据集上计算得到的误差;
  • 泛化误差:模型应用在同样从原始样本的分布中抽取的无限多数据样本时,模型误差的期望。

问题是,我们永远不能准确地计算出泛化误差。 这是因为无限多的数据样本是一个虚构的对象。 在实际中,我们只能通过将模型应用于一个独立的测试集来估计泛化误差, 该测试集由随机选取的、未曾在训练集中出现的数据样本构成。

倾向于影响模型泛化的因素:

  1. 可调整参数的数量:当可调整参数的数量(有时称为自由度)很大时,模型往往更容易过拟合;
  2. 参数采用的值:当权重的取值范围较大时,模型可能更容易过拟合;
  3. 训练样本的数量:训练样本达到一定数量时,模型可能出现过拟合。

(二)模型选择:验证集

在机器学习中,我们通常在评估几个候选模型后选择最终的模型。 这个过程叫做模型选择。为了确定候选模型中的最佳模型,我们通常会使用验证集。

  1. 为了避免过拟合测试数据的风险,通常会将数据分成三份:训练数据集、测试数据集、验证数据集。(实际应用时验证数据和测试数据之间的边界十分模糊。)
  2. 训练数据稀缺时,可能无法提供足够的数据来构成一个合适的验证集,这时可以采用K折交叉验证法
    • 将原始训练数据分成K个不重叠的子集;
    • 执行K次模型训练和验证,每次在K-1个子集上进行训练, 并在剩余的一个子集(在该轮中没有用于训练的子集)上进行验证;
    • 对K次实验的结果取平均来估计训练和验证误差。

(三)欠拟合与过拟合

  • 欠拟合:训练误差和验证误差都很严重, 但它们之间仅有一点差距;
  • 过拟合:训练误差明显低于验证误差;

是否过拟合或欠拟合可能取决于模型复杂性和可用训练数据集的大小。

二、过拟合的解决

(一)权重衰减:正则化

要保证权重向量比较小, 最常用方法是将其范数作为惩罚项加到最小化损失的问题中。 将原来的训练目标最小化训练标签上的预测损失, 调整为最小化预测损失和惩罚项之和:(其中 λ \lambda λ为正则化常数)
L ( w , b ) + λ 2 ∣ ∣ w ∣ ∣ 2 L(w,b)+\frac{\lambda}{2}||w||^2 L(w,b)+2λ∣∣w2
L2正则化回归的小批量随机梯度下降更新:
w ← ( 1 − η λ ) w − η ∣ B ∣ ∑ i ∈ B ∂ w l ( i ) ( w , b ) = w − η ∣ B ∣ ∑ i ∈ B x ( i ) ( w T x ( i ) + b − y ( i ) ) w\leftarrow (1-\eta\lambda)w-\frac{\eta}{|B|}\sum_{i\in B}\partial_{w}l^{(i)}(w,b)=w-\frac{\eta}{|B|}\sum_{i\in B}x^{(i)}(w^Tx^{(i)}+b-y^{(i)}) w(1ηλ)wBηiBwl(i)(w,b)=wBηiBx(i)(wTx(i)+by(i))

线性回归中w参数的随机梯度下降更新:
w ← w − η ∣ B ∣ ∑ i ∈ B ∂ w l ( i ) ( w , b ) = w − η ∣ B ∣ ∑ i ∈ B x ( i ) ( w T x ( i ) + b − y ( i ) ) w\leftarrow w-\frac{\eta}{|B|}\sum_{i\in B}\partial_{w}l^{(i)}(w,b)=w-\frac{\eta}{|B|}\sum_{i\in B}x^{(i)}(w^Tx^{(i)}+b-y^{(i)}) wwBηiBwl(i)(w,b)=wBηiBx(i)(wTx(i)+by(i))

权重衰减的从零开始代码实现:

  1. 定义L2范数惩罚:实现这一惩罚最方便的方法是对所有项求平方后并将它们求和
def l2_penalty(w):
    return torch.sum(w.pow(2)) / 2
  1. 将L2的平方惩罚添加到原始目标函数中
# 广播机制使l2_penalty(w)成为一个长度为batch_size的向量
l = loss(net(X), y) + lambd * l2_penalty(w)

权重衰减的简洁代码实现:
深度学习框架为了便于我们使用权重衰减, 将权重衰减集成到优化算法中,以便与任何损失函数结合使用。 在实例化优化器时可以直接通过weight_decay指定weight decay超参数。 默认情况下,PyTorch同时衰减权重和偏移。 这里只为权重设置了weight_decay,所以偏置参数b不会衰减。

 # 偏置参数没有衰减
 trainer = torch.optim.SGD([
 		{"params":net[0].weight,'weight_decay': wd},
 		{"params":net[0].bias}], lr=lr)

(二)暂退法dropout

暂退法:在前向传播过程中,计算每一内部层的同时注入噪声。

之所以被称为暂退法,是因为我们从表面上看是在训练过程中丢弃(drop out)一些神经元。 在整个训练过程的每一次迭代中,标准暂退法包括在计算下一层之前将当前层中的一些节点置零。

在标准暂退法正则化中,通过按保留(未丢弃)的节点的分数进行规范化来消除每一层的偏差。每个中间活性值 h h h 以暂退概率 p p p 由随机变量 h ′ h' h 替换(满足 E [ h ′ ] = h E[h']=h E[h]=h):
h ′ = { 0 概率为p h 1 − p 其他情况 h' = \begin{cases} 0 & \text{概率为p} \\ \frac{h}{1-p} & \text{其他情况} \end{cases} h={01ph概率为p其他情况
在这里插入图片描述
暂退法的从零开始代码实现:

  1. 定义dropout_layer 函数: 以dropout的概率丢弃张量输入X中的元素, 将剩余部分除以1.0-dropout。
def dropout_layer(X, dropout):
    assert 0 <= dropout <= 1
    # 在本情况中,所有元素都被丢弃
    if dropout == 1:
        return torch.zeros_like(X)
    # 在本情况中,所有元素都被保留
    if dropout == 0:
        return X
    mask = (torch.rand(X.shape) > dropout).float()
    return mask * X / (1.0 - dropout)
  1. 将暂退法应用于每个隐藏层的输出(在激活函数之后), 并为每一层分别设置暂退概率: 常见的技巧是在靠近输入层的地方设置较低的暂退概率。暂退法只在训练期间有效
dropout1, dropout2 = 0.2, 0.5#将第一个和第二个隐藏层的暂退概率分别设置为0.2和0.5

class Net(nn.Module):
    def __init__(self, num_inputs, num_outputs, num_hiddens1, num_hiddens2,
                 is_training = True):
        super(Net, self).__init__()
        self.num_inputs = num_inputs
        self.training = is_training
        self.lin1 = nn.Linear(num_inputs, num_hiddens1)
        self.lin2 = nn.Linear(num_hiddens1, num_hiddens2)
        self.lin3 = nn.Linear(num_hiddens2, num_outputs)
        self.relu = nn.ReLU()

    def forward(self, X):
        H1 = self.relu(self.lin1(X.reshape((-1, self.num_inputs))))
        # 只有在训练模型时才使用dropout
        if self.training == True:
            # 在第一个全连接层之后添加一个dropout层
            H1 = dropout_layer(H1, dropout1)
        H2 = self.relu(self.lin2(H1))
        if self.training == True:
            # 在第二个全连接层之后添加一个dropout层
            H2 = dropout_layer(H2, dropout2)
        out = self.lin3(H2)
        return out


net = Net(num_inputs, num_outputs, num_hiddens1, num_hiddens2)

暂退法的简洁代码实现:
对于深度学习框架的高级API,只需在每个全连接层之后添加一个Dropout层, 将暂退概率作为唯一的参数传递给它的构造函数。 在训练时,Dropout层将根据指定的暂退概率随机丢弃上一层的输出(相当于下一层的输入)。 在测试时,Dropout层仅传递数据

net = nn.Sequential(nn.Flatten(),
        nn.Linear(784, 256),
        nn.ReLU(),
        # 在第一个全连接层之后添加一个dropout层
        nn.Dropout(dropout1),
        nn.Linear(256, 256),
        nn.ReLU(),
        # 在第二个全连接层之后添加一个dropout层
        nn.Dropout(dropout2),
        nn.Linear(256, 10))

def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)

net.apply(init_weights);

三、前向传播和反向传播

  • 前向传播:在神经网络定义的计算图中按顺序计算和存储中间变量,它的顺序是从输入层到输出;
  • 反向传播:计算神经网络参数梯度的方法,根据微积分中的链式规则,按相反的顺序从输出层到输入层遍历网络。

在训练神经网络时,前向传播和反向传播相互依赖。 对于前向传播,我们沿着依赖的方向遍历计算图并计算其路径上的所有变量。 然后将这些用于反向传播,其中计算顺序与计算图的相反。

四、数值稳定性和模型初始化

(一)梯度消失和梯度爆炸

  • 梯度爆炸问题: 参数更新过大,破坏了模型的稳定收敛;
  • 梯度消失问题: 参数更新过小,在每次更新时几乎不会移动,导致模型无法学习。

sigmoid函数的梯度损失问题:

%matplotlib inline
import torch
from d2l import torch as d2l

x = torch.arange(-8.0, 8.0, 0.1, requires_grad=True)
y = torch.sigmoid(x)
y.backward(torch.ones_like(x))

d2l.plot(x.detach().numpy(), [y.detach().numpy(), x.grad.numpy()],
         legend=['sigmoid', 'gradient'], figsize=(4.5, 2.5))

当sigmoid函数的输入很大或是很小时,它的梯度都会消失。当反向传播通过许多层时,一旦有一层的梯度接近于0,整个乘积的梯度可能会消失。

在这里插入图片描述
梯度爆炸问题:
生成100个高斯随机矩阵,并将它们与某个初始矩阵相乘:

M = torch.normal(0, 1, size=(4,4))
print('一个矩阵 \n',M)
for i in range(100):
    M = torch.mm(M,torch.normal(0, 1, size=(4, 4)))

print('乘以100个矩阵后\n', M)

根据返回的结果可知,最终的矩阵乘积发生爆炸:
在这里插入图片描述

(二)参数初始化

  1. 随机初始化是保证在进行优化前打破对称性的关键;

假设一个简单的多层感知机有一个隐藏层和两个隐藏单元。 在这种情况下,我们可以对第一层的权重
进行重排列, 并且同样对输出层的权重进行重排列,可以获得相同的函数。 第一个隐藏单元与第二个隐藏单元没有什么特别的区别。 换句话说,我们在每一层的隐藏单元之间具有排列对称性。

  1. 默认初始化:不指定初始化方法, 框架将使用默认的随机初始化方法;
  2. Xavier初始化:通常从均值为0,方差 σ 2 = 2 n i n + n o u t \sigma^2=\frac{2}{n_{in}+n_{out}} σ2=nin+nout2的高斯分布中采样权重,也可以改为选择从均匀分布中抽取权重时的方差;
  3. Xavier初始化表明,对于每一层,输出的方差不受输入数量的影响,任何梯度的方差不受输出数量的影响。

五、环境和分布偏移

(一)分布偏移的类型

  1. 协变量偏移:输入分布发生变化了,但是标签函数(即条件分布 P ( y ∣ x ) P(y|x) P(yx)没有改变)

训练数据为:
在这里插入图片描述测试数据为:
在这里插入图片描述
训练集由真实照片组成,而测试集只包含卡通图片。 假设在一个与测试集的特征有着本质不同的数据集上进行训练, 如果没有方法来适应新的领域,可能会有麻烦。

  1. 标签偏移:标签边缘概率 P ( y ) P(y) P(y)发生了改变,但是类别条件分布 P ( x ∣ y ) P(x|y) P(xy)在不同领域之间保持不变。

根据症状来预测患者的疾病时,疾病的相对流行率会随着时间的推移而变化

  1. 概念偏移:标签的定义发生了变化。

(二)分布偏移纠正

  1. 经验风险与实际风险
    真实风险是从真实分布中抽取的所有数据的总体损失的预期。然而,这个数据总体通常是无法获得的。经验风险是训练数据的平均损失,用于近似真实风险。在实践中,我们进行经验风险最小化。
  2. 在相应的假设条件下,可以利用加权经验风险最小化在测试时检测并纠正协变量偏移和标签偏移。在测试时,不考虑这种偏移可能会成为问题。
  3. 概念偏移纠正
    • 使用新数据更新现有的网络权重,而不是从头开始训练。

(三)学习问题的分类法

  1. 批量学习:访问一组训练特征和标签 , 使用这些特性和标签训练。 然后部署此模型来对来自同一分布的新数据进行评分。
  2. 在线学习:首先观测到x, 然后我们得出一个估计值f(x), 只有当我们做到这一点后,我们才观测到y。 然后根据我们的决定,我们会得到奖励或损失。 在这个循环中,给定新的观测结果,我们会不断地改进我们的模型。
  3. 老虎机:受到限制的在线学习,即给定新的观测结果后我们可以采取的行动是有限的。
  4. 控制:环境会记住我们所做的事, 不一定是以一种对抗的方式,但它会记住,而且它的反应将取决于之前发生的事情。
  5. 强化学习:强调如何基于环境而行动,以取得最大化的预期利益。
  6. 考虑到环境:上述不同情况之间的一个关键区别是: 在静止环境中可能一直有效的相同策略, 在环境能够改变的情况下可能不会始终有效。

(四)机器学习中的公平、责任和透明度

当我们部署机器学习系统时, 不仅仅是在优化一个预测模型, 而通常是在提供一个会被用来(部分或完全)进行自动化决策的工具。 这些技术系统可能会通过其进行的决定而影响到每个人的生活。从考虑预测到决策的飞跃不仅提出了新的技术问题, 而且还提出了一系列必须仔细考虑的伦理问题。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Three.js 学习笔记之模型(学习中1.20更新) | 组 - 模型 - 几何体 - 材质

文章目录 模型 几何体 材质层级模型组- THREE.Group递归遍历模型树结构object3D.traverse() 模型点模型Points - 用于显示点线模型Line | LineLoop | LineSegments网格模型mesh - 三角形网格模型独有的属性与方法 几何体BufferGeometry缓冲类型几何体BufferGeometry - 基类创…

位运算的奇技淫巧

常见位运算总结&#xff1a; 1、基础位运算 左移<<运算 将二进制数向左移位操作&#xff0c;高位溢出则丢弃&#xff0c;低位补0。 右移>>运算 右移位运算中&#xff0c;无符号数和有符号数的运算并不相同。对于无符号数&#xff0c;右移之后高位补0&#xff…

SpringCloud Aliba-Sentinel【中篇】-从入门到学废【5】

&#x1f3b5;歌词分享&#x1f3b5; 岁月在墙上剥落看见小时候。 ——《东风破》 目录 &#x1f953;1.流控规则 &#x1f32d;2. 熔断规则 &#x1f9c8;3.热点规则 &#x1f9c2;4.系统规则 1.流控规则 1.资源名&#xff1a;唯一名称&#xff0c;默认请求路径 2.针对来…

【开源】基于JAVA语言的教学资源共享平台

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课程资源模块2.4 课程作业模块2.5 课程评价模块 三、系统设计3.1 用例设计3.2 类图设计3.3 数据库设计3.3.1 课程档案表3.3.2 课程资源表3.3.3 课程作业表3.3.4 课程评价表 四、系统展…

[AI]文心一言出圈的同时,NLP处理下的ChatGPT-4.5最新资讯

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言4.5key价格泄漏ChatGPT4.0使用地址ChatGPT正确打开方式最新功能语音助手存档…

SpringBoot项目中简单使用虚拟机Redis

目录 步骤大致如下&#xff1a; 一.在pom文件中加入redis依赖 二.在虚拟机上打开我们下载好的Redis。开启服务器端并获取虚拟机ip地址 三.在项目配置。 四&#xff1a;使用redis 测试 redis是一个以键值对存储的NoSQL。被数百万开发人员用作缓存、矢量数据库、文档数据库、…

beego项目部署与热更新

1.开发自己的第一个项目 这里我引用的是在线聊天室&#xff0c;参考源码是https://github.com/beego/samples/tree/master/WebIM 在源码的基础上重新开发&#xff0c;整理项目发布到了liu289747235/WebIM 推荐下载源码&#xff1a;https://gitee.com/myselfyou/web-im 在线…

kafka参数配置参考和优化建议 —— 筑梦之路

对于Kafka的优化&#xff0c;可以从以下几个方面进行思考和优化&#xff1a; 硬件优化&#xff1a;使用高性能的硬件设备&#xff0c;包括高速磁盘、大内存和高性能网络设备&#xff0c;以提高Kafka集群的整体性能。 配置优化&#xff1a;调整Kafka的配置参数&#xff0c;包括…

go语言(七)----slice的声明方式

1、声明方式一 //声明一个slice1是一个切片&#xff0c;但是并没有给slice分配空间var slice1 []intslice1 make([]int,3)2、声明方式二 声明一个slice切片&#xff0c;同时给slice分配空间&#xff0c;3个空间&#xff0c;初始化值是0var slice1 []int make([]int,3)3、声…

Docker:6种网络配置详解浅介

在Docker中&#xff0c;网络配置是一个重要的主题&#xff0c;因为容器需要与其他容器或外部网络进行通信。Docker提供了多种网络模式和配置选项&#xff0c;以便在不同的场景下满足用户的需求。 本文介绍这些网络模式的区别以及配置&#xff0c;相信看完以后你能够掌握Docker网…

基于springboot+vue养老院管理系统

摘要 这是一个基于Spring Boot 和 Vue.js 的养老院管理系统的项目。该系统旨在提供一套全面的解决方案&#xff0c;以简化养老院的日常管理任务&#xff0c;包括居民信息管理、员工调度、医疗服务追踪、财务管理等。通过结合后端的Spring Boot框架和前端的Vue.js框架&#xff0…

【LeetCode】每日一题 2024_1_20 按分隔符拆分字符串(模拟/库函数)

文章目录 随便聊聊时间题目&#xff1a;按分隔符拆分字符串题目描述代码与解题思路 随便聊聊时间 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01; 时隔半个月&#xff0c;LeetCode 每日一题重新开张&#xff0c;寒假学习&#xff0c;正式开始 题目&#xff1…

算法笔记(动态规划入门题)

1.找零钱 int coinChange(int* coins, int coinsSize, int amount) {int dp[amount 1];memset(dp,-1,sizeof(dp));dp[0] 0;for (int i 1; i < amount; i)for (int j 0; j < coinsSize; j)if (coins[j] < i && dp[i - coins[j]] ! -1)if (dp[i] -1 || dp[…

calloc与realloc和malloc的区别以及new

目录 calloc、realloc 和 malloc 三个函数的区别在于 更详细的示例代码 交叉使用 内存泄漏 悬空指针 内存重叠 new 的语法 使用 new 运算符在堆上创建学生对象的示例 new和malloc都可以用于在堆上分配内存 calloc、realloc 和 malloc 是 C/C 中用于动态内存分配的函…

链表的相交

链表的相交 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/intersection-of-tw…

【NVIDIA】Jetson Orin Nano系列:安装 Qt6、firefox、jtop、flameshot

1、使用命令安装 sudo apt install qtcreator sudo apt install qt6-* sudo apt install libqt6* sudo apt install qml-qt6 sudo apt install qmlscene-qt6 sudo apt install assistant-qt6 sudo apt install designer-qt62、启动 qtcreator 3、常用工具安装 sudo apt in…

ros2学习笔记-CLI工具,记录命令对应操作。

目录 环境变量turtlesim和rqt以初始状态打开rqt node启动节点查看节点列表查看节点更多信息命令行参数 --ros-args topic话题列表话题类型话题列表&#xff0c;附加话题类型根据类型查找话题名查看话题发布的数据查看话题的详细信息查看类型的详细信息给话题发布消息&#xff0…

线程状态转换

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;并发编程⛺️稳中求进&#xff0c;晒太阳 程状态转换 假设有线程Thread t 情况1 new-->RUNNABLE 当调用t.start()方法时&#xff0c;由new ->RUNNABLE 情况2 RUNNABLE WAITING t…

无/自监督去噪(1)——一个变迁:N2N→N2V→HQ-SSL

目录 1. 前沿2. N2N3. N2V——盲点网络&#xff08;BSNs&#xff0c;Blind Spot Networks&#xff09;开创者3.1. N2V实际是如何训练的&#xff1f; 4. HQ-SSL——认为N2V效率不够高4.1. HQ-SSL的理论架构4.1.1. 对卷积的改进4.1.2. 对下采样的改进4.1.3. 比N2V好在哪&#xff…

c++基础2

一、c的引用 引用和指针的的区别&#xff1f; 引用是一种更安全的指针&#xff1a; 1. 引用必须初始化&#xff0c;指针可以不用初始化 int a 10; int *p; // 指针可能是野指针 int &b a;//引用赋值"&#xff0c;通常指的是直接修改引用所引用的对象的值&#xff0…