神经网络不收敛的原因有以下11种原因:忘记对你的数据进行归一化忘记检查输出结果

GitHub:

前言

如果你的神经网络不收敛怎么办?一般来说,神经网络不收敛的原因有 11 个:

忘记对数据进行归一化 忘记检查输出 没有预处理数据 没有使用任何正则化方法 使用了太大的批量大小 使用了错误的学习率 在网络的最后一层使用了错误的激活函数 包含错误的梯度 网络权重为未正确初始化 使用了太深的神经网络 隐藏层神经元数设置错误

下面对以上11个原因一一说明,并给出相应的解决方案;

1. 忘记标准化你的数据问题描述

如何规范化数据在神经网络训练中非常重要。这是一个不能省略的步骤,不进行归一化几乎不可能训练出好的网络模型。但因为这一步在深度学习社区中是如此重要且广为人知,所以很少被提及,但却是初学者容易犯的错误。

原因

我们之所以需要对数据进行归一化,是因为我们一般假设输入和输出数据呈正态分布,均值为 0,标准差为 1。这个假设在深度学习理论中很常见,从权重初始化,到激活函数,用于训练网络的优化算法。

解决方案

常用的归一化方法主要是零均值归一化,将原始数据映射成均值为0,标准差为1的分布。假设原始特征的均值为,方差为,公式为如下:

另一种常用的归一化方法是线性函数归一化(Min-Max Scaling)。它对原始数据进行线性变换,使结果映射到[0,1]的范围内,实现对原始数据的比例缩放。公式如下:

其中X为原始数据,分别代表数据的最大值和最小值。

未经训练的神经网络通常输出的值大致在 -1 和 1 之间。如果你希望它输出一些其他范围的值(例如 RGB 图像,存储为 0 到 255) 范围内的字节,则会是一些问题。开始训练时,网络会非常不稳定,因为当期望值为 255 时,它会产生 -1 或 1,这个误差被大多数用于训练神经网络的优化算法认为是巨大的。这将产生巨大的梯度和你的训练误差可能会爆炸。如果你的训练没有爆炸,那么前几个阶段的训练仍然是浪费的,因为网络首先要学习的是缩放并将输出值移动到大致所需的范围。如果您对数据进行规范化(在这种情况下,您可以简单地除以 128 减去 1),那么这一切都不是问题。

一般来说,神经网络中特征的规模也决定了它们的重要性。如果输出中有一个规模较大的特征,与其他特征相比,它会产生更大的误差。同样,输入中的大规模特征可以主导网络,从而导致下游更大的变化。出于这个原因,使用许多盲目地减去平均值然后除以每个特征的标准差的神经网络库进行自动归一化并不总是足够的。您可能有一个输入特征通常介于 0.0 和 0.001 之间,而这个特征的范围很小,因为它是一个重要特征(在这种情况下,您可能不想重新缩放它),还是因为与其他属性相比,它有一些更小的单位?

同样,要小心具有如此小范围的特征,以至于它们的标准偏差接近或精确接近于零——如果你对它们进行归一化,这些将产生 nan 不稳定性。仔细考虑这些问题很重要——想想你的每个特征真正代表什么,并将规范化视为制作“单位”的过程。所有输入特征都是相等的。这是我认为真正需要人类参与深度学习的少数几个方面之一。

2. 忘记查看输出问题描述

当您开始训练您的网络几个 epoch 时,错误正在减少。这是否表明网络已成功训练?不幸的是,这不是,这意味着您的代码可能有一些

问题可能出在数据预处理、训练代码或推理部分。仅仅因为错误在减少并不意味着您的网络正在学习有用的信息。

原因

与传统编程不同,机器学习系统几乎在所有情况下都会默默地失败。在传统编程中,我们习惯于计算机在出现问题时抛出错误,并将其用作返回并检查错误的信号。

可惜在机器学习中并非如此,所以我们应该非常小心地通过人眼观察每个阶段的处理过程,这样当出现错误时,我们能够及时、更彻底地检测出来。检查代码。

解决方案

在管道的每个阶段检查数据是否正确非常重要。通常这意味着找到某种方法来可视化结果。如果你有图像数据,这很容易,动画数据也可以很容易地可视化。

如果你有更奇特的东西,你必须找到一种方法来检查它,以确保它在预处理、训练和推理管道的每个阶段看起来都是正确的,并将其与地面实况数据进行比较。

有很多方法可以检查您的网络是否正常工作。其中一部分是找出报告的训练错误的真正含义。可视化应用于训练集数据的输出,并观察网络输出与真实标签的比较

在训练期间,您可能会看到从 1.0 到 0.01 的错误,但如果 0.01 仍然是不可接受的结果,则输出可能仍然无法使用。如果它在训练集上有用,那么在验证集上检查它是否仍然适用于以前从未见过的数据?

我的建议是从一开始就习惯于将所有内容可视化,不要只是在网络未收敛时开始,并确保在开始尝试不同的神经网络架构之前准备好通过最终用户的完整管道,所有方式做一个完整的检查。这是准确评估许多可能不同的方法的唯一方法。

3. 无数据预处理问题说明

大多数数据都很棘手——通常我们知道相似的数据可能有非常不同的数字表示。举个例子,以角色动画为例,如果我们用角色关节相对于动作捕捉工作室中心的 3D 位置来表示我们的数据,然后在一个位置或朝着一个方向进行运动,它可能具有相同的效果就像在不同的位置上表演一样。运动或在不同方向上执行相同的运动是不同的数字表示。相反,我们需要做的是用不同的方式表示数据——例如,在某些局部参考系中(例如相对于角色的质心),以便我们知道两个动作是相似的,从而获得相似的数字表示。

原因

神经网络只对它们作为输入的数据做了一些基本假设,但其中一个基本假设是数据所在的空间是连续的,对于大多数空间,两个数据点之间的点至少是一些到一些在某种程度上,它是这两个数据点的“混合”,而附近的两个数据点在某种程度上代表了“相似”的东西。数据空间中的大不连续性,或代表同一事物的大量单独数据,将使学习任务更加困难。

解决方案

想想所使用的特征是什么意思,是否可以对它们进行一些简单的转换,以确保表示我们所知道的相似事物的数据点总是得到相似的数字表示?是否有一个局部坐标系来表示数据以使事情更自然,例如更好的色彩空间或其他一些不同的格式?

考虑数据预处理的另一种方法是尝试减少由可能需要的数据更改引起的组合爆炸。例如,如果在角色动画数据上训练的神经网络必须为角色在每个位置和方向上学习相同的一组动作,那么网络的大部分容量将被浪费,许多学习过程将被重复。

4. 没有使用任何正则化方法问题描述

正则化是当今训练神经网络的一种非常重要的方法,通常以 dropout、噪声或其他一些随机过程添加到网络中的形式。

即使数据的维度多于参数,或者在过度拟合不是问题或不太可能出现的情况下,添加 dropout 或某种形式的噪声仍然会有所帮助。

原因

正则化方法不仅用于控制过拟合,它们还通过在训练过程中引入一些随机过程,在一定程度上“平滑”成本环境。这可以加快训练收敛,帮助处理数据中的噪声或异常值,并防止网络的极端权重配置。

解决方案

最常见的正则化方法是在卷积层或全连接层之前使用 dropout。一般采用较高的概率,如0.75或0.9,然后根据网络可能过拟合的概率调整概率值。例如,如果不太可能出现过拟合,那么只需将保持神经元的概率设置得很高,例如 0.99。

数据增强或其他类型的噪声也可以像 dropout 一样进行正则化,有时会使用足够的数据增强来避免 dropout。通常 dropout 被认为是一种组合许多随机子网络的预测的技术,但它也可以被视为一种数据增强形式,在训练期间对输入数据产生许多类似的变化。众所周知,避免过度拟合的最佳方法是拥有足够的数据,以使神经网络永远不会看到相同的数据两次!

最后,与训练神经网络的其他方面一样,您需要小心使用正则化。请记住在预测期间将其关闭,并注意一旦将其关闭,您通常会得到略有不同的结果。在需要极其准确的数值预测的情况下,某种形式的正则化有时会使这变得困难。

5.使用了太大的batch size问题描述

使用太大的批大小会降低梯度下降的随机性,从而降低网络的准确性。

原因

使用更小的批量会导致更不稳定、更随机的权重更新。这有两个好处:

首先,它可以帮助“跳出”过去训练时可能陷入的局部最小值;其次c语言实现神经网络算法,它可以允许训练到最小值,这意味着更好的泛化性能。解决方案

在训练时,找到一个可以容忍的最小批量大小。GPU 可以并行使用的最佳批量大小不一定会带来最佳精度,因为更大的批量可能需要更多的训练时间才能达到相同的精度。所以大胆地从小批量开始训练,比如 16、8 甚至 1。

数据中的某些其他元素有时可以像批量大小一样有效地工作。例如,以两倍分辨率处理图像与使用 4 倍批量大小具有相似的效果。

为了简要说明这个原因,请考虑在 CNN 中,每个过滤器的权重更新将在输入图像中应用的所有像素和批处理中的每个图像上进行平均。平均而言,将图像分辨率提高 2 倍,效果会提高 4 倍以上,就像将批量大小提高 4 倍一样。

总体而言,重要的是要考虑每次迭代中最终梯度更新的平均值,并确保在其不利影响与在 GPU 上使用尽可能多的潜在并行性的需求之间取得平衡。

6. 使用错误的学习率问题描述

学习率对训练网络的难易程度有很大的影响,如果你是新手,由于常见深度学习框架中使用的各种默认选项,你几乎肯定设置错了。

原因

许多深度学习框架默认启用梯度裁剪。此操作通过更改训练中每个步骤的最大权重数来防止梯度爆炸。

这可能很有用 – 特别是当您的数据包含许多异常值时,这可能会产生较大的错误,从而产生较大的梯度和权重更新,但默认设置也使得通过手动难度找到最佳学习率非常困难。我发现大多数刚接触深度学习的人将学习率设置得太高,并通过梯度裁剪来解释这一点,这使得整体训练变慢并且改变学习率的效果不可预测。

解决方案

不使用渐变剪裁。找到在训练过程中不会导致错误爆炸的最大学习率。将学习率设置为比这个低一个数量级,这可能非常接近最优学习率。

如果您正确清理了数据,删除了大部分异常值,并正确设置了学习率,那么您真的不需要梯度裁剪。如果你没有它,你会发现你的训练错误偶尔会变得非常大,然后使用梯度裁剪,但请记住,看到你的训练错误突然爆发几乎总是表明你的某些数据中存在其他错误,梯度裁剪只是临时措施。

7. 最后一层问题描述中使用了错误的激活函数

在最后一层使用激活函数有时会导致网络无法生成所需值的全部范围。例如,最常见的错误是在最后一层使用 ReLU,这会导致网络只输出正数。

原因

想想你的数据值究竟代表什么,归一化后它们的范围是什么。最有可能的是,您的输出值是无限的正数或负数,在这种情况下,您不应该在最后一层使用激活函数。如果输出值可能只在某个范围内有意义,例如它由范围 0-1 中的概率组成,那么很可能应该在最后一层使用特定的激活函数(如 sigmoid 激活函数)。

解决方案

如果你在做回归任务,大多数情况下你不需要在最后一层使用任何激活函数,除非你知道一些关于你想要输出的值的信息。

在最后一层使用激活函数有很多微妙之处。在神经网络产生输出后,系统最终会将输出裁剪到 [-1,1] 范围内。那么将这个裁剪过程添加为最后一层的激活似乎是有意义的,因为这将确保您的网络错误函数不会惩罚大于 1 或小于 -1 的值。

但是,没有错误意味着这些大于或小于 1 的值也没有梯度,这在某些情况下会使网络无法训练。或者,在最后一层使用 Tanh 可能很诱人,因为知道这个激活函数输出的值在 -1 到 1 的范围内,但这也会导致问题,因为函数的梯度在 1 或 -1 附近变得非常小, 这会导致权重大幅增长,试图产生 -1 或 1。

一般来说,你最好的选择是安全地进行,不要在最后一层使用任何激活函数,而不是尝试一些可能适得其反的聪明事情。

8. Network contains bad gradient 问题描述

使用 ReLU 激活函数的神经网络经常会因为梯度差而遇到“死神经元”。它会导致网络性能下降,在某些情况下甚至会导致网络无法继续训练。

原因

对于 ReLU 激活函数,其梯度对于正数和负数分别为 1 和 0。这是因为输入的微小变化不会影响小于零的输入输出。这对于具有正数的大梯度似乎不是问题,但是由于许多网络层堆叠在一起,负权重能够将具有强梯度的大正值变成具有零梯度的负值,通常如果有的话输入是什么,网络中的部分或全部权重是损失函数的梯度。这种情况下,网络死了,权重不能更新,也就是不能继续训练。

解决方案

如果你发现你的训练误差不随迭代次数而变化,那么很可能是因为 ReLU 激活函数,神经元正在死亡。尝试使用leaky ReLU 或 ELU 等激活函数,看看是否仍然会发生这种情况。

如果在计算损失函数相对于权重的导数时使用任何梯度为零的操作,如裁剪、舍入或取最大/最小,也会产生不良梯度。如果这些元素出现在您的符号图中,您必须非常小心,因为它们通常会导致无法预料的困难,例如,如果它们在自定义错误度量中用作损失函数的一部分。

9. 网络权重没有正确初始化问题描述

如果你不能正确初始化你的神经网络的权重,那么你的神经网络就不太可能训练。神经网络中的许多其他组件假定某种形式的适当或标准化的权重初始化并将权重设置为零,这通常不适用于它们自己的自定义随机初始化。

原因

您可能听说过可以使用“小随机数”来初始化网络的权重,但这并不是那么简单。常用的权重初始化方法如“he”、“xaiver”和“lecun”使用了非常复杂和详细的数学公式,并证明了为什么它们是最优方法。更重要的是,其他神经网络组件通常围绕这些初始化构建并经过经验测试,因此使用自定义初始化使得重现其他研究人员的结果变得更加困难。

解决方案

在任何情况下都能正常工作的一些更常用的初始化方法包括“he”、“xaiver”和“lecun”。所以随意选择一个或另一个,但首先要尝试找到为您的任务初始化权重的最佳方法。

其他网络层也可能需要仔细初始化。网络偏差被初始化为零,而其他更复杂的层,例如参数激活函数,可能有自己的初始化,这对于获得正确的结果同样重要。

10. 使用了太深的神经网络问题描述

网络越深越好吗?事实上,情况并非总是如此。越深越好,一般你在做基准实验或者你想尝试在某些任务上提高 1% 或更多的准确率,但是如果网络的 3、4 和 5 层无法学习任何东西,那么使用 100 + 网络层也会失败,或者更糟。

原因

看起来,当有人决定堆叠数百层时,神经网络不会突然开始获得突破性的结果。过去十年对神经网络所做的所有改进都是微小的、根本性的变化,适用于深度网络和小型网络。如果您的网络无法正常工作,则更有可能不是深度问题。

解决方案

从 3 到 8 层的神经网络开始。只有当经过训练的网络具有良好的性能并且您开始研究如何提高准确性时,您才会开始尝试更深层次的网络。

从小处着手还意味着更快地训练您的网络、更快地推理以及更快地迭代不同的设计和设置。最初,所有这些东西对网络的准确性的影响比简单地堆叠更多的网络层要大得多。

11.隐藏层神经元个数设置错误问题描述

在某些情况下,使用太多或太少的隐藏神经元会使网络难以训练。神经元太少,它可能无法表达想要的任务,而神经元太多,它可能会变得缓慢和笨拙,难以去除训练中的残留噪声。

原因

在决定使用多少个隐藏神经元时,关键是要粗略地考虑你​​认为表达你想通过网络传递的信息所需的实数值的最小数量。然后你应该把这个数字放大一点。这将允许 dropout,以便网络使用更冗余的表示c语言实现神经网络算法,并且在您的估计中有一点余地。如果你在做分类,你可能会使用 5 到 10 倍的类数作为一个好的初始猜测,如果你在做回归,你可能会使用 2 到 3 倍的输入或输出变量数。当然,所有这些都高度依赖于环境,不存在简单的自动解决方案,良好的直觉仍然是决定隐藏单元数量的最重要因素。

解决方案

从 256 到 1024 的隐藏神经元数量开始。然后,查看其他研究人员在类似应用中使用的数字并将其作为灵感。如果其他研究人员使用的数字与上面给出的数字有很大不同,可能有一些特定的原因说明这对您很重要。

实际上,与其他因素相比,隐藏神经元的数量对神经网络性能的影响往往很小,并且在许多情况下,高估所需的隐藏神经元数量只会减慢训练速度,而不会产生负面影响. 一旦网络正常工作,如果您仍然担心,请尝试一大堆不同的数字并测量它们的准确性,直到找到最有效的数字。

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论