动手学深度学习——3.多层感知机

1.线性模型

线性模型可能出错

例如,线性意味着单调假设: 任何特征的增大都会导致模型输出的增大(如果对应的权重为正), 或者导致模型输出的减小(如果对应的权重为负)。 有时这是有道理的。 例如,如果我们试图预测一个人是否会偿还贷款。 我们可以认为,在其他条件不变的情况下, 收入较高的申请人比收入较低的申请人更有可能偿还贷款。 但是,虽然收入与还款概率存在单调性,但它们不是线性相关的。 收入从0增加到5万,可能比从100万增加到105万带来更大的还款可能性。 处理这一问题的一种方法是对我们的数据进行预处理, 使线性变得更合理,如使用收入的对数作为我们的特征。

然而我们可以很容易找出违反单调性的例子。 例如,我们想要根据体温预测死亡率。 对体温高于37摄氏度的人来说,温度越高风险越大。 然而,对体温低于37摄氏度的人来说,温度越高风险就越低。 在这种情况下,我们也可以通过一些巧妙的预处理来解决问题。 例如,我们可以使用与37摄氏度的距离作为特征。

但是,如何对猫和狗的图像进行分类呢? 增加位置(13,17)处像素的强度是否总是增加(或降低)图像描绘狗的似然? 对线性模型的依赖对应于一个隐含的假设, 即区分猫和狗的唯一要求是评估单个像素的强度。 在一个倒置图像后依然保留类别的世界里,这种方法注定会失败。

与我们前面的例子相比,这里的线性很荒谬, 而且我们难以通过简单的预处理来解决这个问题。 这是因为任何像素的重要性都以复杂的方式取决于该像素的上下文(周围像素的值)。 我们的数据可能会有一种表示,这种表示会考虑到我们在特征之间的相关交互作用。 在此表示的基础上建立一个线性模型可能会是合适的, 但我们不知道如何手动计算这么一种表示。 对于深度神经网络,我们使用观测数据来联合学习隐藏层表示和应用于该表示的线性预测器。

2.加入隐藏层

我们可以通过在网络中加入一个或多个隐藏层来克服线性模型的限制, 使其能处理更普遍的函数关系类型。 要做到这一点,最简单的方法是将许多全连接层堆叠在一起。 每一层都输出到上面的层,直到生成最后的输出。 我们可以把前𝐿−1层看作表示,把最后一层看作线性预测器。 这种架构通常称为多层感知机(multilayer perceptron),通常缩写为MLP。 

3.从线性到非线性

注意在添加隐藏层之后,模型现在需要跟踪和更新额外的参数。 可我们能从中得到什么好处呢?在上面定义的模型里,我们没有好处! 原因很简单:上面的隐藏单元由输入的仿射函数给出, 而输出(softmax操作前)只是隐藏单元的仿射函数。 仿射函数的仿射函数本身就是仿射函数, 但是我们之前的线性模型已经能够表示任何仿射函数。

为了发挥多层架构的潜力, 我们还需要一个额外的关键要素: 在仿射变换之后对每个隐藏单元应用非线性的激活函数(activation function)𝜎。 激活函数的输出(例如,𝜎(⋅))被称为活性值(activations)。 一般来说,有了激活函数,就不可能再将我们的多层感知机退化成线性模型。

4.激活函数

激活函数(activation function)通过计算加权和并加上偏置来确定神经元是否应该被激活, 它们将输入信号转换为输出的可微运算。 大多数激活函数都是非线性的。 由于激活函数是深度学习的基础,下面简要介绍一些常见的激活函数。

5.模型复杂性

当我们有简单的模型和大量的数据时,我们期望泛化误差与训练误差相近。 当我们有更复杂的模型和更少的样本时,我们预计训练误差会下降,但泛化误差会增大。 模型复杂性由什么构成是一个复杂的问题。 一个模型是否能很好地泛化取决于很多因素。 例如,具有更多参数的模型可能被认为更复杂, 参数有更大取值范围的模型可能更为复杂。 通常对于神经网络,我们认为需要更多训练迭代的模型比较复杂, 而需要早停(early stopping)的模型(即较少训练迭代周期)就不那么复杂。

我们很难比较本质上不同大类的模型之间(例如,决策树与神经网络)的复杂性。 就目前而言,一条简单的经验法则相当有用: 统计学家认为,能够轻松解释任意事实的模型是复杂的, 而表达能力有限但仍能很好地解释数据的模型可能更有现实用途。 在哲学上,这与波普尔的科学理论的可证伪性标准密切相关: 如果一个理论能拟合数据,且有具体的测试可以用来证明它是错误的,那么它就是好的。 这一点很重要,因为所有的统计估计都是事后归纳。 也就是说,我们在观察事实之后进行估计,因此容易受到相关谬误的影响。 目前,我们将把哲学放在一边,坚持更切实的问题。

本节为了给出一些直观的印象,我们将重点介绍几个倾向于影响模型泛化的因素。

  1. 可调整参数的数量。当可调整参数的数量(有时称为自由度)很大时,模型往往更容易过拟合。

  2. 参数采用的值。当权重的取值范围较大时,模型可能更容易过拟合。

  3. 训练样本的数量。即使模型很简单,也很容易过拟合只包含一两个样本的数据集。而过拟合一个有数百万个样本的数据集则需要一个极其灵活的模型。

6.验证集

在机器学习和深度学习中,将数据集分为训练集、验证集和测试集是为了确保模型的性能和泛化能力。这三个数据集的角色和作用分别如下:

  1. 训练集(Training Set)

    • 用于训练模型,即模型在这些数据上进行参数调整和学习模式。
    • 模型在训练集上的表现主要反映其在已知数据上的学习能力。
  2. 验证集(Validation Set)

    • 用于模型的选择和超参数调整。
    • 在训练过程中,验证集帮助监控模型的表现,以防止过拟合(即模型在训练集上表现很好,但在新数据上表现不佳)。
    • 通过验证集,能够在训练过程中评估模型的性能,调整模型的架构或选择最优的超参数组合(如学习率、正则化参数等)。
    • 验证集的结果用于指导模型的优化和调整,而不是最终的模型评估。
  3. 测试集(Test Set)

    • 用于评估模型的最终性能。
    • 测试集在训练和验证过程中不参与任何模型调整。
    • 测试集的结果代表模型在真实世界新数据上的性能,反映模型的泛化能力。

总结来说,验证集的引入是为了在模型训练过程中提供一个独立的数据集来进行模型评估和调整,以防止过拟合,并帮助选择最优的模型参数。测试集则是在模型训练和调优完成后,用于对模型进行最终的性能评估。通过这种分割方法,可以更好地评估模型的性能,并确保模型在未见过的数据上也能表现良好。

7.K折交叉验证

当训练数据稀缺时,我们甚至可能无法提供足够的数据来构成一个合适的验证集。 这个问题的一个流行的解决方案是采用𝐾折交叉验证。 这里,原始训练数据被分成𝐾个不重叠的子集。 然后执行𝐾次模型训练和验证,每次在𝐾−1个子集上进行训练, 并在剩余的一个子集(在该轮中没有用于训练的子集)上进行验证。 最后,通过对𝐾次实验的结果取平均来估计训练和验证误差。

8.权重衰减

在训练参数化机器学习模型时, 权重衰减(weight decay)是最广泛使用的正则化的技术之一, 它通常也被称为𝐿2正则化。 这项技术通过函数与零的距离来衡量函数的复杂度, 因为在所有函数𝑓中,函数𝑓=0(所有输入都得到值0) 在某种意义上是最简单的。 但是我们应该如何精确地测量一个函数和零之间的距离呢? 没有一个正确的答案。 事实上,函数分析和巴拿赫空间理论的研究,都在致力于回答这个问题。

一种简单的方法是通过线性函数 𝑓(𝑥)=𝑤⊤𝑥 中的权重向量的某个范数来度量其复杂性, 例如‖𝑤‖2。 要保证权重向量比较小, 最常用方法是将其范数作为惩罚项加到最小化损失的问题中。 将原来的训练目标最小化训练标签上的预测损失, 调整为最小化预测损失和惩罚项之和。 现在,如果我们的权重向量增长的太大, 我们的学习算法可能会更集中于最小化权重范数‖𝑤‖2。

此外,为什么我们首先使用𝐿2范数,而不是𝐿1范数。 事实上,这个选择在整个统计领域中都是有效的和受欢迎的。 𝐿2正则化线性模型构成经典的岭回归(ridge regression)算法, 𝐿1正则化线性回归是统计学中类似的基本模型, 通常被称为套索回归(lasso regression)。 使用𝐿2范数的一个原因是它对权重向量的大分量施加了巨大的惩罚。 这使得我们的学习算法偏向于在大量特征上均匀分布权重的模型。 在实践中,这可能使它们对单个变量中的观测误差更为稳定。 相比之下,𝐿1惩罚会导致模型将权重集中在一小部分特征上, 而将其他权重清除为零。 这称为特征选择(feature selection),这可能是其他场景下需要的。

权重衰减的数学表达如下:

其中:

  • LtotalL是总损失。
  • Ldata是原始损失(如均方误差或交叉熵损失)。
  • λ是正则化系数,控制权重衰减的强度。
  • wi是模型的权重参数。

具体来说,权重衰减的工作原理如下:

  1. 损失函数修改:在原始损失函数(如交叉熵损失或均方误差损失)中添加一个项,惩罚所有权重的平方和。这意味着权重的值越大,这个惩罚项的值就越大。
  2. 控制复杂性:通过添加这个惩罚项,模型的优化过程会倾向于保持权重较小,这样可以避免模型过于复杂,从而减少过拟合的风险。
  3. 参数更新在每次迭代中,优化算法(如梯度下降)不仅会根据损失函数对权重进行更新,还会根据权重衰减项对权重进行额外的调整,使得权重逐渐减小。

权重衰减在实际应用中具有以下优点:

  • 防止过拟合:通过减少权重值,模型对训练数据的拟合不会过于复杂,从而提高对新数据的泛化能力。
  • 简化模型:权重衰减鼓励模型选择较小的权重,从而学习到更简单的特征。
  • 提高稳定性:通过惩罚大权重,权重衰减可以提高模型训练的稳定性,减少训练过程中的波动。

在实践中,选择合适的正则化系数 λ 是关键。通常需要通过交叉验证来确定最佳的 λ 值,以在防止过拟合和保持模型表现之间取得平衡。

9.Dropout

在探究泛化性之前,我们先来定义一下什么是一个“好”的预测模型? 我们期待“好”的预测模型能在未知的数据上有很好的表现: 经典泛化理论认为,为了缩小训练和测试性能之间的差距,应该以简单的模型为目标。 简单性以较小维度的形式展现, 正如我们讨论权重衰减(𝐿2正则化)时看到的那样, 参数的范数也代表了一种有用的简单性度量。

简单性的另一个角度是平滑性,即函数不应该对其输入的微小变化敏感。 例如,当我们对图像进行分类时,我们预计向像素添加一些随机噪声应该是基本无影响的。 1995年,克里斯托弗·毕晓普证明了 具有输入噪声的训练等价于Tikhonov正则化 。 这项工作用数学证实了“要求函数光滑”和“要求函数对输入的随机噪声具有适应性”之间的联系。

然后在2014年,斯里瓦斯塔瓦等人就如何将毕晓普的想法应用于网络的内部层提出了一个想法: 在训练过程中,他们建议在计算后续层之前向网络的每一层注入噪声。 因为当训练一个有多层的深层网络时,注入噪声只会在输入-输出映射上增强平滑性。

这个想法被称为暂退法(dropout)。 暂退法在前向传播过程中,计算每一内部层的同时注入噪声,这已经成为训练神经网络的常用技术。 这种方法之所以被称为暂退法,因为我们从表面上看是在训练过程中丢弃(drop out)一些神经元。 在整个训练过程的每一次迭代中,标准暂退法包括在计算下一层之前将当前层中的一些节点置零。

需要说明的是,暂退法的原始论文提到了一个关于有性繁殖的类比: 神经网络过拟合与每一层都依赖于前一层激活值相关,称这种情况为“共适应性”。 作者认为,暂退法会破坏共适应性,就像有性生殖会破坏共适应的基因一样。

10.前向传播、反向传播和计算图

前向传播计算图

绘制计算图有助于我们可视化计算中操作符和变量的依赖关系。计算图是简单网络相对应的计算图, 其中正方形表示变量,圆圈表示操作符。 左下角表示输入,右上角表示输出。 注意显示数据流的箭头方向主要是向右和向上的。

s为正则化项,与交叉熵损失函数相加得到最终的损失函数。

反向传播

反向传播(backward propagation或backpropagation)指的是计算神经网络参数梯度的方法。 简言之,该方法根据微积分中的链式规则,按相反的顺序从输出层到输入层遍历网络。 该算法存储了计算某些参数梯度时所需的任何中间变量(偏导数)。 假设我们有函数𝑌=𝑓(𝑋)和𝑍=𝑔(𝑌), 其中输入和输出𝑋,𝑌,𝑍是任意形状的张量。 利用链式法则,我们可以计算𝑍关于𝑋的导数

训练神经网络

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

以上述简单网络为例:一方面,在前向传播期间计算正则项取决于模型参数𝑊(1)和 𝑊(2)的当前值。 它们是由优化算法根据最近迭代的反向传播给出的。 另一方面,反向传播期间参数的梯度计算, 取决于由前向传播给出的隐藏变量ℎ的当前值

因此,在训练神经网络时,在初始化模型参数后, 我们交替使用前向传播和反向传播,利用反向传播给出的梯度来更新模型参数。 注意,反向传播重复利用前向传播中存储的中间值,以避免重复计算。 带来的影响之一是我们需要保留中间值,直到反向传播完成。 这也是训练比单纯的预测需要更多的内存(显存)的原因之一。 此外,这些中间值的大小与网络层的数量和批量的大小大致成正比。 因此,使用更大的批量来训练更深层次的网络更容易导致内存不足(out of memory)错误。

11.梯度消失、梯度爆炸

梯度是𝐿−𝑙个矩阵 𝑀(𝐿)⋅…⋅𝑀(𝑙+1) 与梯度向量 𝑣(𝑙)的乘积。 因此,我们容易受到数值下溢问题的影响. 当将太多的概率乘在一起时,这些问题经常会出现。

不稳定梯度带来的风险不止在于数值表示; 不稳定梯度也威胁到我们优化算法的稳定性。 我们可能面临一些问题。 要么是梯度爆炸(gradient exploding)问题: 参数更新过大,破坏了模型的稳定收敛; 要么是梯度消失(gradient vanishing)问题: 参数更新过小,在每次更新时几乎不会移动,导致模型无法学习。

曾经sigmoid函数很流行, 因为它类似于阈值函数。 由于早期的人工神经网络受到生物神经网络的启发, 神经元要么完全激活要么完全不激活(就像生物神经元)的想法很有吸引力。 然而,它却是导致梯度消失问题的一个常见的原因, 让我们仔细看看sigmoid函数为什么会导致梯度消失。

正如上图,当sigmoid函数的输入很大或是很小时,它的梯度都会消失。 此外,当反向传播通过许多层时,除非我们在刚刚好的地方, 这些地方sigmoid函数的输入接近于零,否则整个乘积的梯度可能会消失。 当我们的网络有很多层时,除非我们很小心,否则在某一层可能会切断梯度。 事实上,这个问题曾经困扰着深度网络的训练。 因此,更稳定的ReLU系列函数已经成为从业者的默认选择(虽然在神经科学的角度看起来不太合理)。

梯度爆炸可能同样令人烦恼。 为了更好地说明这一点,我们生成100个高斯随机矩阵,并将它们与某个初始矩阵相乘。 对于我们选择的尺度(方差𝜎2=1),矩阵乘积发生爆炸。 当这种情况是由于深度网络的初始化所导致时,我们没有机会让梯度下降优化器收敛。

解决方法

参数初始化:解决(或至少减轻)上述问题的一种方法是进行参数初始化, 优化期间的注意和适当的正则化也可以进一步提高稳定性。如果我们不指定初始化方法, 框架将使用默认的随机初始化方法,对于中等难度的问题,这种方法通常很有效。

使用适当的激活函数:

  • ReLU(Rectified Linear Unit):ReLU激活函数有助于缓解梯度消失问题,因为它在正区域不会饱和。
  • Leaky ReLU 和 ELU(Exponential Linear Unit):这些是ReLU的变体,可以在负区域有非零梯度,进一步减少梯度消失问题。

归一化层:

  • 批归一化(Batch Normalization):通过在每个小批量数据上归一化输入,可以稳定训练过程并加快收敛。
  • 层归一化(Layer Normalization):对每个训练样本的激活进行归一化,适合于RNN等不适合批归一化的场景。

梯度裁剪:设定梯度的阈值,避免梯度爆炸问题。常用的方法是将梯度的范数裁剪到一个预定的最大值。

调整学习率:

  • 使用学习率调度器:如学习率逐步衰减(Learning Rate Decay),或者在某些训练时期动态调整学习率。
  • 自适应优化方法:如Adam、RMSprop,它们会根据梯度的历史信息自适应调整学习率。

更深层网络的架构设计:

  • 残差网络(ResNet):引入残差连接,有效地缓解了梯度消失和梯度爆炸问题。
  • 长短期记忆网络(LSTM)和门控循环单元(GRU):在RNN中,通过引入门控机制,缓解梯度消失和梯度爆炸问题。

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

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

相关文章

【Java--数据结构】队列与栈的相互成就

欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 用队列实现栈 用栈实现队列 用队列实现栈 oj链接 一个队列是无法实现栈的 入栈push:把数据放到不为空的队列当中。 注意:第一次入栈时&…

手写new

手写new new是什么执行new会发生什么实现new new是什么 new 操作符是可以创建一个用户定义的对象的实例或具有构造函数的内置对象的实例 function Car (make, model, year) {this.make makethis.model modelthis.year year } Car.prototype.running function () {return …

R语言极值分析:GEV与GPD模型与MCMC的海洋观测数据极值模拟可视化研究

全文链接:https://tecdat.cn/?p37007 原文出处:拓端数据部落公众号 在海洋科学领域,极端天气和海洋事件如极端海浪、风暴潮和海啸等,对沿海社区、基础设施及生态环境构成了重大威胁。准确预测和评估这些极端事件的强度和频率&a…

Golang中读写锁的底层实现

目录 Sync.RWMutex 背景与机制 接口简单介绍 sync.RWMutex 数据结构 读锁流程 RLock RUnlock RWMutex.rUnlockSlow 写锁流程 Lock Unlock Sync.RWMutex 背景与机制 从逻辑上,可以把 RWMutex 理解为一把读锁加一把写锁; 写锁具有严格的排他性&…

Qt程序图标更改以及程序打包

Qt程序图标更改以及程序打包 1 windows1.1 cmake1.1.1 修改.exe程序图标1.1.2 修改显示页面左上角图标 1.2 qmake1.2.1 修改.exe程序图标1.2.2 修改显示页面左上角图标 2 程序打包2.1 MinGW2.2 Visual Studio 3 参考链接 1 windows 1.1 cmake 1.1.1 修改.exe程序图标 获得一个…

【Linux】进程控制的详细介绍

前言 在此之前,我们学过进程的概念,进程的状态,进程地址空间等一系列进程相关的问题。本章我们继续学习进程,我们要来学习一下进程的控制,关于进程等待,等问题。 目录 1.再次认识Fork函数1.1 fork()之后操…

搜集日志。

logstash 负责: 接收数据 input — 解析过滤并转换数据 filter(此插件可选) — 输出数据 output input — decode — filter — encode — output elasticsearch 查询和保存数据 Elasticsearch 去中心化集群 Data node 消耗大量 CPU、内存和 I/O 资源 分担一部分…

数据结构进阶:使用链表实现栈和队列详解与示例(C, C#, C++)

文章目录 1、 栈与队列简介栈(Stack)队列(Queue) 2、使用链表实现栈C语言实现C#语言实现C语言实现 3、使用链表实现队列C语言实现C#语言实现C语言实现 4、链表实现栈和队列的性能分析时间复杂度空间复杂度性能特点与其他实现的比较…

启动yarn后,其他节点没有NodeManager

写在前面: 这个问题虽然折磨了我两天,但是原因特别蠢,可能与各位不一定一样,我是因为ResourceManager的节点的"/etc/hadoop/workers"文件没有配置好(没有配hadoop102和hadoop104),但排…

MySQL日期和时间相关函数

目录 1. 获取当前时间和日期 2. 获取当前日期 3. 获取当前时间 4. 获取单独的年/月/日/时/分/秒 5. 添加时间间隔 date_add ( ) 6. 格式化日期 date_format ( ) 7. 字符串转日期 str_to_date () 8. 第几天 dayofxx 9. 当月最后一天 last_day ( ) 10. 日期差 datedif…

Java中的线程同步

为什么要实现线程同步 线程的同步是为了保证多个线程按照特定的顺序、协调地访问共享资源,避免数据不一致和竞争条件等问题。 线程同步的方式 1.synchronized关键字 (1)同步方法 public synchronized void save(){} 注: syn…

网络编程+文件上传操作的理解

前言: 概述:在网络通信协议下,不同计算机上运行的程序,进行数据传输 比如:通信,视频通话,网游,邮件等 只要是计算机之间通过网络进行数据传输,就有网络编程的存在 (下面单纯是在Java基础中了解了一下网络编程,感觉理…

如何保证数据库和redis的数据一致性

1、简介 在客户端请求数据时,如果能在缓存中命中数据,那就查询缓存,不用在去查询数据库,从而减轻数据库的压力,提高服务器的性能。 2、问题如何保证两者的一致性 先更新数据库在删除缓存 难点:如何保证…

Classifier-Free Guidance (CFG) Scale in Stable Diffusion

1.Classifier-Free Guidance Scale in Stable Diffusion 笔记来源: 1.How does Stable Diffusion work? 2.Classifier-Free Diffusion Guidance 3.Guide to Stable Diffusion CFG scale (guidance scale) parameter 1.1 Classifier Guidance Scale 分类器引导是…

vite配置环境变量和使用,配置正确后import.meta.env.VITE_APP_BASE_URL编译报错的解决方法

一、配置: 1.新增四个环境文件 .env.development .env.test .env.production .env.pre 内容为不同环境的不同参数变量必须以VITE_APP开头,如: #接口地址 VITE_APP_BASE_URL"¥¥¥¥&#xff…

嵌入式人工智能(6-树莓派4B按键输入控制LED)

1、按键 按键的原理都是一样,通过按键开关的按下导通,抬起断开的情况,GPIO引脚来检测其是否有电流流入。GPIO有input()方法,对于GPIO引脚检测电流,不能让其引脚悬空,否则引脚会受周边环境电磁干扰产生微弱…

获取欧洲时报中国板块前新闻数据(多线程版)

这里写目录标题 一.数据获取流程二.获取主页面数据并提取出文章url三.获取文章详情页的数据并提取整体代码展示 一.数据获取流程 我们首先通过抓包就能够找到我们所需数据的api 这里一共有五个参数其中只有第一个和第五个参数是变化的第一个参数就是第几页第五个是一个由时…

HCNA ICMP:因特网控制消息协议

ICMP:因特网控制消息协议 前言 Internet控制报文协议ICMP是网络层的一个重要协议。ICMP协议用来在网络设备间传递各种差错和控制信息,他对于手机各种网络信息、诊断和排除各种网络故障有至关重要的作用。使用基于ICMP的应用时,需要对ICMP的工…

中介者模式(行为型)

目录 一、前言 二、中介者模式 三、总结 一、前言 中介者模式(Mediator Pattern)是一种行为型设计模式,又成为调停者模式,用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地互相引用,从而使其耦合…

防火墙双机热备(接上一个NAT实验)

一、实验拓扑 二、实验需求 1、对现有网络进行改造升级,将当个防火墙组网改成双机热备的组网形式,做负载分担模式,游客区和DMZ区走FW3,生产区和办公区的流量走FW1 2、办公区上网用户限制流量不超过100M,其中销售部人员…