• 网络系统
  • 2024-09-29 15:31:06
  • 0

神经网络系统都带一个负号,神经网络输出负值

大家好,今天小编关注到一个比较有意思的话题,就是关于神经网络系统都带一个负号的问题,于是小编就整理了1个相关介绍神经网络系统都带一个负号的解答,让我们一起看看吧。

如何更好地调试神经网络?

调试神经网络是一项艰难的工作,专家也不例外。面对数百万的参数,任何一个小变动都可能使你前功尽弃。没有调试和可视化,所有你的行动就像抛硬币,而且更糟糕的是还浪费时间。下面是本文搜集的实践汇总,希望有助于你提早发现问题。

神经网络系统都带一个负号,神经网络输出负值

数据集问题


尝试使用小数据集过拟合你的模型

一般来说神经网络应该在数百次迭代中过拟合你的数据。如果你的损失值不下降,那问题存在于更深层次。

使用迭代逻辑解决问题

尝试构建最简单的网络解决你的主要问题,接着一步一步扩展到全局问题。比如,你正在创建风格迁移网络,首先在一张图像上训练你的脚本迁移风格。如果奏效,再接着创建用于任何图像的风格迁移模型。

使用具有扭曲的平衡数据集

比如训练分类数据的网络,你的训练数据应该对每一分类具有相同数量的输入。其他情况下则存在分类过拟合的可能性。神经网络对于所有的扭曲并非恒定不变,因此需要你对它们进行专门训练。制造输入扭曲将会提升网络准确度。

网络容量 vs 数据集大小

你的数据集应足够大,以便网络用来学习。如果你的数据集小,而网络很大,那么它会停止学习(某些情况下也会为大量的不同输入输出相同结果)。如果你有大数据,而网络很小,那么你将会看到损失值的跳跃,因为网络容量无法存储如此多的信息。

使用均值中心化(mean centering)

这将会从你的网络中移除噪音数据,提升训练性能,同时某些情况下有助于解决 NaN 问题。但是记住,如果你有时序数据,那么你应该使用批而不是全局中心化。

神经网络问题

首先尝试较简单的模型

我在很多案例中看到人们首先尝试一些标准的大型网络,比如 ResNet-50、VGG19 等,但是接着发现他们的问题通过仅有若干层的网络也能解决。因此如果你没有标准问题,首先从小网络开始吧。你添加的数据越多,模型就越难训练,因此从小网络开始会更省时。你也应该记住,大网络需要更大的内存与更多的操作。

可视化是必须的

如果你正使用 TensorFlow,一定要从 TensorBoard 开始。如果没有,尝试为你的框架寻找一些可视化工具,或者自己动手编写。这将对于你发现训练早期阶段的问题非常有帮助。你必须可视化的事情有:损失值、权重直方图、变量和梯度。如果你正在做计算机视觉,那要一直可视化过滤器从而理解网络实际上看到了什么。

权重初始化

如果你错误设置权重,由于零梯度,或者所有神经元的类似更新等,你的网络将变得无法训练。同样你也应该记住权重与学习率是成对的,因此高学习率和大权重可以导致 NaN 问题。

对于一些网络使用 1e-2–1e-3 左右的高斯分布初始化软件已经足够。

对于深度网络这毫无用处,因为你的权重彼此相乘了很多次,将会产生几乎消除反向传播上的梯度的非常小的数值。多亏了 Ioffe 和 Szegedy,现在我们有了批归一化,缓解了令人头疼的大量问题。

使用标准网络解决标准问题

存在大量的预训练模型,你可以正确使用它们。在一些情况中是这样,或者你可以使用调整技术节约训练时间。主要的想法是绝大多数网络容量对于不同问题是相同的。比如,如果我们讨论计算机视觉,它将会包含对于所有图像一样的线、点、角,并且你不需要再训练它们。

把衰减用于学习率

这几乎每次都会给你一个提升。TensorFlow 中有大量的不同衰减调度器(https://www.tensorflow.org/versions/r0.12/api_docs/python/train/decaying_the_learning_rate)。

使用网格搜索、随机搜索或配置文件调整超参数

不要试图手动调整所有参数,这很耗时,效率低下。我经常使用全局配置调整所有参数,并在运行完检查结果后看看在哪个方向上应该进一步调查。如果这个方法没有帮助,你可以试一下随机搜索或网格搜索。

激活函数

1.梯度消失问题

一些激活函数,比如 Sigmoid 和 Tanh 正在遭受饱和问题。在其极值时,它们的导数接近于零,这将会消除梯度和学习过程。因此检查不同的函数比较好。现在标准的激活函数是 ReLU。同样这一问题也出现在一个非常深度或者循环的网络中,比如你有 150 层,所有的激活值是 0.9,那么 0.9¹⁵⁰ = 0,000000137。但是正如上文所说,批归一化将有助于解决这一问题,残差层也是。

2.不是零中心的激活值

比如 Sigmoid、ReLU 函数就不是零中心的。这意味着训练期间所有你的梯度将全部是正或负,并会引发学习问题。这就是为什么我们使用零中心的输入数据。

3.Dead ReLUs

标准的 ReLU 函数也不完美。对于负数 ReLU 给出零的问题意味着它们将不会被激活,因此你的神经元的某些部分将会死掉并永不再用。这之所以能发生是因为高学习率和错误的权重初始化。如果参数调整没有帮助,那么你可以试一下 Leaky ReLU、PReLU、ELU 或 Maxout,它们没有这一问题。

4.梯度爆炸

这一问题与梯度消失相同,除却每一步梯度变的越来越大。一个主要的解决办法是使用梯度剪裁,为梯度设置基本的硬限制。

深度网络的精确度降级

从一些点上真正深化网络的问题开始表现为一个坏手机,因此增加更多层降低了网络精确度。解决办法是使用残差层把输入的一些部分传递到所有层。

声明:本文适用于神经网络初学者。

神经网络的调试要比绝大多数程序更困难,因为大多数bug不会导致运行错误,只会导致不良的收敛。也许还会有许多看似模棱两可的错误信息:

性能错误:你的神经网络没有训练好(Performance Error: your neural net did not train well.)。

如果你经验丰富,就应该知道这表示代码还需要大改动。

一、处理NaN?

多数情况下,NaN错误在前100次迭代中出现,原因很简单:你的学习率过高了。当学习率非常高的时候,就会在前100次迭代的时候出现NaN错误。用因子为3来降低学习率,直到前100次迭代不再出现NaN错误。这么做一旦有效,你就有了一个非常好的学习率作为开端。根据我的经验,最好的学习率是你得到NaN错误的范围的一到十分之一。

如果你在100次迭代之后碰到了NaN错误,又有两种常见原因。

如果你使用的是RNN,确保你使用了梯度下降,并对梯度使用L2正则化。RNN似乎在训练早期会产生梯度,10%或更少的批次有学习峰值,此时的梯度幅值是相当高的。没有对梯度削减,这些峰值会产生NaN。

如果写的是自定义的网络层,那么很有可能因为除以0而引发NaN。另一个众所周知会产生Nan错误的层是Softmax层。Softmax计算包括分子分母的exp(x)操作,它可以用无穷大除以无穷大,会产生NaN。确保你使用了稳定的Softmax实现。

二、神经网络无法学习?

一旦你没有了NaN错误,那么你的神经网络就可以在上千次迭代中平稳运行,而且不会在前几百次迭代后减少训练损失。当你第一次构建代码库的时候,最好别使用2000次迭代。这并不是因为所有的网络可以从低于2000次迭代开始学习。相反,从开头开始编码网络很可能出现bug,在达到高迭代次数之前,你会想要过早进行调试。现在的目的是一次又一次地缩小问题范围,直到你得到了一个在2000次迭代以下训练出来的网络。幸运地是,有两种方式来降低复杂性。

将训练集大小减小到10个实例。在几百次的迭代中,在这10个实例上,神经网络通常会出现过度拟合的情况。许多编码错误不会导致过拟合的出现。如果你的网络在10个实例的训练集上没有出现过度拟合,那么确保你使用的数据挂上了正确的标签。将批次大小减小到1来检查批次计算错误。在代码中添加打印语句确保输出与你期望的一致。通常情况下,你可以通过上面介绍的纯粹蛮力来找出错误。一旦网络可以在10个实例上训练,你可以试着让它在100个实例上训练。如果这种方式运行正常,但效果不是很好,你可以试试下面的方法。

解决你感兴趣的最简单的问题。如果你想翻译句子,首先可以建立一个针对特定语言的语言模型。如果你完成了,那么试着在给出3个词语的情况下预测翻译出来的第一个词。如果你想检测图像中的物体,那么在训练回归网络之前,你可以对图像中物体数目进行分类。在网络能够解决的棘手问题和使用最少的时间让代码得到合适的数据之间需要权衡。这个时候就要发挥你的创造能力了。

将神经网络运用于其他新场景的技巧是合理使用上面介绍的两个步骤。这是一种协调机制,并且效果不错。首先,你表明这个神经网络至少可以记住几个例子。然后这个神经网络可以泛化到更简单问题的验证集中。你慢慢在取得稳步进展时提升难度。这并没有高手第一次使用的Karpathy风格那么有趣,但至少它起作用。有时候你会碰到棘手的问题,你会发现它在2000次迭代中不会继续学习了。那很棒!但它的迭代次数很少会是这个问题之前复杂度下迭代次数的10倍。如果你发现是这种情况,尝试搜索中等水平的复杂度。

三、调整超参数

现在你的网络可以学习东西了,你可能会得意忘形。你还可能发现你训练的网络并不能够解决大多数复杂的问题。超参数调整就是解决问题的关键。有些人直接下载一个CNN的包然后在他们的数据集上运行,然后告诉你说使用超参数调整并没有带来什么不同。这是因为它们使用已经存在的架构来解决已经存在的问题。如果你要解决的问题需要新的架构呢,通过超参数调整来得到良好的设置就是必须的了。你最好确保针对你要解决的问题阅读了超参数教程,不过我还是会在下面列出一些基本思想。

可视化:不要怕在训练过程中花时间编写自定义可视化工具。如果你的可视化方法效果不行,那么考虑换另一种方法。

权重初始化:一般情况下,较大的初始化权重是个不错的选择,但是太大又会导致NaN。

确保权重看起来“健康”。要了解这是什么意思,我建议在IPython的notebook中查看现有网络的权重值。花些时间来观察在诸如ImageNet或Penn Tree Bank这些标准的数据集上训练的成熟的网络中成分的权重的直方图应该是什么样的。

神经网络的w.r.t.输入不是不变的,特别是在使用SGD而不是其他方法训练的时候,因为SGD不是尺度不变的方法。花时间用与扩展其他方面的方式来扩展输入数据和输出标签。

在训练过程中降低学习速率几乎总会给你带来提升。最好的衰减策略通常是:在k次迭代后,每n次迭代就用学习率除以1.5,k>n。

使用超参数配置文件,虽然把超参数放到代码中也行,但是如果你想试试不同的值那么会比较麻烦。我把参数放在一个JSON文件中,使用一条命令导入,确切的格式不重要。不要轻易重构代码,因为重新加载超参数比较麻烦!重构会引入bug,它们将会延长训练周期,并且可以在你得到一个你喜欢的网络前避免。

更多优质内容,请持续关注镁客网~~

到此,以上就是小编对于神经网络系统都带一个负号的问题就介绍到这了,希望介绍关于神经网络系统都带一个负号的1点解答对大家有用。

相关推荐