[译] 调试神经网络的清单

标签: dev | 发表时间:2019-03-27 00:00 | 作者:
出处:http://itindex.net/relian

训练深度学习模型是非常耗时的工作,没有什么比花费了好几天训练而最终结果效果不佳更让人沮丧的了。因此翻译了这篇文章: Checklist for debugging neural networks,希望能给你一点启发,尽早发现模型中的问题。原文地址:https://towardsdatascience.com/checklist-for-debugging-neural-networks-d8b2a9434f21 ,略有删减。点击阅读原文可以跳转到该文章,需要翻墙哦!

众所周知,机器学习代码很难调试。就连简单的前馈神经网络,您也经常需要围绕网络架构、权重值初始化和网络优化做出决策 - 所有这些都可能导致机器学习代码中隐藏BUG。

正如Chase Roberts在一篇精彩的关于“如何单元测试机器学习代码”的文章中写道,他的挫折源于常见的陷阱:

  1. 代码永远不会崩溃、引发异常,甚至变慢。

  2. 网络持续训练,损失仍在不断减少。

  3. 几个小时后会收敛,但结果却很糟糕。

那么该怎么办呢?

本文将提供一个框架来帮助您调试神经网络:

  1. 简单处开始

  2. 确认你的模型损失(loss)

  3. 检查中间输出和连接

  4. 诊断参数

  5. 跟踪你的工作

您可以随意跳到特定部分或顺序阅读下面的内容!请注意:我们不涉及数据预处理或特定模型算法选择。这些主题有很多很好的在线资源(例如,阅读“选择合适的机器学习算法”)。

1.简单处开始

具有正则化和学习速率调度器的复杂架构的神经网络将比简单网络更难调试。这个第一点可能有些投机取巧,因为它与调试您已经建立的网络没有关系,但它仍值得重点推荐!

从简单开始:

  • 首先构建一个更简单的模型

  • 在单个数据点上训练模型

构建一个更简单的模型

作为起点,构建一个具有单个隐藏层的小型网络,并验证一切正常,然后逐渐添加模型复杂性,同时检查模型结构的每个方面(层、参数等)是否有效。

在单个数据点上训练模型

作为一种快速检查,您可以使用一组或两组训练数据点来确认模型是否会产生过拟合。神经网络应立即过拟合,训练精度为100%,验证准确度与您随机猜测的模型相当。如果模型不能在那些数据点上过拟合,那么要么数据集太小,要么有错误。

即使您已经确认模型可以工作,也请尝试在正式训练之前进行一个(或几个)epoch的训练。

2.确认你的模型损失

模型的损失是评估模型性能的主要方式,而模型在评估过程中设置重要的参数,因此您需要确保:

  • 损失适合于当前任务(使用分类交叉熵损失进行多分类问题或使用焦点损失来解决类别不平衡问题)

  • 损失函数都以正确的比例因子进行度量。如果您在网络中使用多种类型的损失,例如MSE、对抗式、L1、特性丢失,那么请确保所有损失都以相同的比例正确缩放。

注意初始损失也很重要。如果您的模型是通过随机猜测开始的,请检查初始损失是否接近您的预期损失。在Stanford CS231n课程中,Andrej Karpathy建议如下:

出于性能考虑寻找正确的损失。使用小参数初始化时,请确保获得预期的损失。最好先只检查数据损失(因此将正则化强度设置为零)。例如,对于具有Softmax分类器的CIFAR-10,我们预期初始损失为2.302,因为我们期望每个类别的扩散概率为0.1(因为有10个类别),而Softmax损失是正确的类别的负的对数概率,所以:-ln(0.1) = 2.302。

对于二分类例子而言,您只需对每个类别执行类似的计算。假设你的数据是20%的0类别和80%的1类别。预期的初始损失将达到 -0.2ln(0.5)-0.8ln(0.5) = 0.693147。如果您的初始损失远大于1,则可能表明神经网络的权重未平衡(即初始化得较差)或您的数据未正则化。

3.检查中间输出和连接

为了调试神经网络,理解神经网络内部的动态以及各个中间层所起的作用以及层的连接方式通常很有用。您可能遇到以下错误:

  • 梯度更新的算式不正确

  • 未应用权重更新

  • 消失或爆炸的梯度

如果您的梯度值是零,这可能意味着优化器中的学习率太小,或者你遇到了上述的错误#1:不正确的梯度更新算式。

除了查看梯度更新的绝对值之外,还要确保监视每个层的激活幅度、权重和更新。例如,参数更新的幅度(权重和偏差)应为1-e3。

存在一种称为“死亡ReLU”或“消失梯度问题”的现象,其中ReLU神经元在学习其权重的大负偏差项后将输出零。那些神经元永远不会再在任何数据点上激活。

您可以使用梯度检查,通过使用数值方法逼近梯度来检查这些错误。如果它接近计算的梯度,则反向传播实现是正确的。要实现梯度检查,请在此处和此处查看CS231中的这些优秀资源以及Andrew Ng关于该主题的相关课程。

Faizan Shaikh撰写了关于可视化神经网络的三种主要方法:

  • 初步方法 - 向我们展示训练模型的整体结构的简单方法。这些方法包括打印出神经网络的各个层的形状或过滤器以及每层中的参数。

  • 基于激活的方法 - 在这些方法中,我们破译单个神经元或一组神经元的激活,以直观的了解他们正在做什么。

  • 基于梯度的方法 - 这些方法倾向于在训练模型时计算前向和后向梯度。

有许多有用的工具可用于可视化各个层的激活和连接,例如ConX和Tensorboard。

使用ConX进行的动态渲染可视化示例

使用图像数据? Erik Rippel发表了一篇精彩的文章“使用Keras和Cats可视化部分卷积神经网络”。

4.诊断参数

神经网络具有大量彼此相互作用的参数,使得优化变得困难。请注意,这是一个积极研究的领域,所以下面的建议只是起点。

  • 批量大小(技术上称为mini-batch) - 您希望批量大到足以准确估计误差梯度,但小到足以使mini-batch随机梯度下降(SGD)可以正则化网络。小的批量大小将会使得学习过程快速收敛,但可能会以增加噪声为代价,并可能导致优化困难。论文“On Large-Batch Training for Deep Learning: Generalization Gap and Sharp Minima”解释了为什么会这样:

在实践中已经观察到,当使用较大批次时,通过泛化的能力衡量的模型的质量会降低。我们研究了大批量体系中这种泛化下降的原因,并提供了支持大批量方法倾向于收敛到训练和测试函数的局部最小化的观点的数据证据 - 众所周知,局部的最小值导致较差的泛化。相比之下,小批量方法始终如一地收敛到平面最小化,我们的实验支持一种普遍看法,这是由于梯度估计中的固有噪声。

  • 学习率- 学习率太低会导致收敛缓慢或陷入局部最小值的风险,而学习率太大会导致优化发散,因为存在跳过损失函数更深、但更窄部分的风险。可以考虑进行学习速率调度,在训练过程时降低学习速率。CS231n课程有很多关于实现退火学习率的不同技术。

机器学习框架,如Keras、Tensorflow、PyTorch、MXNet现在都有关于使用学习速率调度器/递减的文档或示例:

Keras  -  https://keras.io/callbacks/#learningratescheduler

Tensorflow  -  https://www.tensorflow.org/api_docs/python/tf/train/exponential_decay

PyTorch  -  https://pytorch.org/docs/stable/_modules/torch/optim/lr_scheduler.html

MXNet  -  https://mxnet.incubator.apache.org/versions/master/tutorials/gluon/learning_rate_schedules.html

  • 梯度裁剪- 这将在反向传播期间用最大值或最大范数剪切参数的梯度。这用于解决您在上述错误#3中可能遇到的任何梯度爆炸。

  • 批量标准化- 批量标准化用于标准化每层的输入,以对抗内部协变量移位问题。如果您同时使用Dropout和批量标准化,请务必阅读下面关于Dropout的观点。

来自Dishank Bansal的文章“Pitfalls of Batch Norm in TensorFlow and Sanity Checks for Training Networks”是批处理标准化常见错误的重要参考资源。

  • 随机梯度下降(SGD)- 有几种SGD使用动量、自适应学习率和Nesterov更新,但在训练表现和泛化方面都没有明显的优势(参见Sebastian Ruder的优秀文章’梯度下降优化算法概述‘和这个有趣的实验’SGD > Adam?‘)。推荐的开始选择Adam或普通的带Nesterov动量的SGD。

  • 正则化- 正则化对于构建泛化模型至关重要,因为它增加了对模型复杂性或极端参数值的惩罚。它显著降低了模型的方差,但没有明显增加其偏差。如CS231n课程中所讲的:

通常情况是,损失函数是数据损失和正则化损失的总和(例如,权重上的L2惩罚)。需要注意的一个危险是正则化损失可能会压倒数据损失,在这种情况下,梯度将主要来自正则化(通常具有更简单的梯度表达式)。这可以掩盖数据损失梯度的错误实现。

要对此进行审核,您应该关闭正则化并独立检查数据损失梯度。

  • Dropout -  Dropout是另一种正则化网络以防止过度拟合的技术。在训练时,通过仅以某个概率p(超参数)保留神经元的激活来实现Dropout,否则将其设置为零。结果,网络必须在每个训练批次中使用不同的参数子集,这减少了特定参数的变化,防止某些参数占主导地位。

这里重要的注意事项是:如果您同时使用Dropout和批量规范化(batch norm),请谨慎处理这些操作的顺序,甚至谨慎一起使用它们。这仍然是一个活跃的研究领域,但您可以看到最新的讨论:

来自Stackoverflow用户MiloMinderBinder:“Dropout意味着完全阻止来自某些神经元的信息,以确保神经元不会共同适应。因此,批量规范化必须在Dropout之后,否则您将通过规范化统计传递信息。“

来自arXiv:通过方差转换理解Dropout和批量标准化之间的不统一(Xiang Li,Shuo Chen,Xiaolin Hu,Jian Yang) - “从理论上讲,我们发现网络从训练状态转移到测试时,Dropout会改变特定神经元的方差。但是,BN将在测试阶段保持其整个学习过程累积的统计方差。该方差的不一致性(我们将该方案命名为“方差偏移”)导致推理中不稳定的数值行为,当在BN之前应用Dropout时,最终导致更多错误的预测。

5.跟踪你的工作

在您忘记所使用的学习率或类别权重之前,很容易忽略记录实验的重要性。通过更好的跟踪,您可以轻松查看和重现以前的实验,以减少重复工作(也就是遇到相同的错误)。

但是,手动记录信息可能很难做到,也很难扩大到多次实验。 像Comet.ml这样的工具可以帮助自动跟踪数据集、代码更改、实验历史和产品模型(这包括模型的关键信息,如超参数、模型性能指标和环境详细信息)。

您的神经网络对数据、参数甚至包版本的微小变化都非常敏感 - 导致模型性能下降,并可能累积。跟踪您的工作是开始标准化环境和建模工作流程的第一步。

快速回顾

我们希望这篇文章能为调试神经网络提供坚实的起点。总结其关键点,您应该:

  • 从简单开始- 首先构建一个更简单的模型,然后通过对几个数据点的训练进行测试

  • 确认模型损失- 检查您是否使用了正确的损失并检查初始损失

  • 检查中间输出和连接- 使用梯度检查和可视化来检查图层是否正确连接,以及梯度是否按预期更新

  • 诊断参数- 从SGD到学习率,确定正确的组合(或找出错误的组合)

  • 跟踪您的工作- 作为基准,跟踪您的实验过程和关键建模工件

相关 [调试 神经网络 清单] 推荐:

[译] 调试神经网络的清单

- - IT瘾-dev
训练深度学习模型是非常耗时的工作,没有什么比花费了好几天训练而最终结果效果不佳更让人沮丧的了. 因此翻译了这篇文章: Checklist for debugging neural networks,希望能给你一点启发,尽早发现模型中的问题. 原文地址:https://towardsdatascience.com/checklist-for-debugging-neural-networks-d8b2a9434f21 ,略有删减.

轻量的神经网络

- - Just for Life.
很久之前我觉得移动端应用几百兆的模型不切实际,在不考虑蒸馏、量化等压缩方法下,发现了 MobileNet 设计的很神奇,大小只有几 MB,可以说是一股清流了. 就整理发布了一下,然后今天发现找不到了,神奇. (于是顺手和 ShuffleNet 一并整理到轻量化的神经网络中). 基本上可以说这个版本是后面几个版本的出发点.

BP神经网络的Java实现

- - ITeye博客
课程作业要求实现一个BPNN. 此前只用Matlab实现过,这次尝试使用Java实现了一个. 关于BPNN的原理,就不赘述了.  为了验证正确性,我写了一个测试用例,目的是对于任意的整数(int型),BPNN在经过训练之后,能够准确地判断出它是奇数还是偶数,正数还是负数. System.out.println("训练完毕,下面请输入一个任意数字,神经网络将自动判断它是正数还是复数,奇数还是偶数.

神经网络与用户行为

- - 博客园_新闻
英文原文: Neurology & User Behavior: What We Know. 流量和转化率是我们衡量一个网站是否成功的两个重要指标. 网站转化率就是指用户进行了相应目标行动的访问次数(成交人数)与总访问次数的比率. 这里所指的相应的行动可以是用户登录、用户注册、用户订阅、用户下载、用户购买等一些列用户行为,因此网站转化率是一个广义的概念.

研究人员首次用DNA构造人工神经网络

- Robi - Solidot
加州理工研究人员首次用DNA构造出人工神经网络,类似一个简化的大脑. 此前他们曾研制过一个能计算平方根的DNA逻辑门. 研究人员112种不同的DNA链组成四个相互联系的人工神经元,它会玩一个猜心术的游戏. 研究人员和这个试管中的神经网络玩了27次游戏,每次提供的线索都不相同,而它每次都猜对了. 研究人员表示,具有人工智能的生化系统,可以在医药,化学以及生物领域带来不可估量的应用.

自组织增量学习神经网络-SOINN

- 金文 - 丕子
自组织增量学习神经网络(Self-organizing incremental neural network, SOINN)实现包括学习、记忆、联想、推理、常识等方面的研究,最终目的是实现能够模拟人类大脑的供智能机械使用的通用型智能信息处理系统——人工脑. a. 基于SOINN的监督学习、非监督学习、半监督学习算法研究.

动态神经网络工具包DyNet:比Theano和TensorFlow更快

- - IT瘾-tuicool
近日,来自卡内基梅隆大学、日本奈良先端科学技术大学、Google DeepMind、以色列巴伊兰大学、艾伦人工智能研究所、IBM T.J. Watson 研究中心、澳大利亚墨尔本大学、约翰·霍普金斯大学、谷歌、华盛顿大学、微软和英国爱丁堡大学的研究者共同发表了一篇重磅论文《DyNet: The Dynamic Neural Network Toolkit》,正式介绍了动态神经网络工具包 DyNet;该工具包也已在 GitHub 上开源:http://github.com/clab/dynet.

用神经网络训练一个文本分类器

- - 文章 – 伯乐在线
理解聊天机器人的工作原理是非常重要的. 聊天机器人内部一个非常重要的组件就是文本分类器. 我们看一下文本分类器的神经网络(ANN)的内部工作原理. 我们将会使用2层网络(1个隐层)和一个“词包”的方法来组织我们的训练数据. 文本分类有3个特点:模式匹配、算法、神经网络. 虽然使用多项朴素贝叶斯算法的方法非常有效,但是它有3个致命的缺陷:.

用paddle实现一个CNN神经网络

- - 非技术 - ITeye博客
问题:实现在MNIST数据集上,对数字的识别. (1)输入:MNIST手写的数字图片,它是一个28*28的二维图片,为了计算,我们将其转为784维的一个向量. (2)输出:分类器的输出是0-9的数字的概率. (3)分类器的设计:5层的卷积神经网络. 即:conv->pool->conv->pool->FC->softmax.

神经网络的菜鸟入门秘籍

- - 机器之心
在过去几年中,如果你打开过浏览器,那么你肯定看到过几百回“神经网络”这个词. 在这篇短文中,我将为你初步介绍这一领域和神经网络本身的背景信息. 接下来的5分钟可能不会让你迅速成为这个领域的世界级专家,但让你经历一个意义非凡的入门阶段却是很简单的. 另外,你还将学习到一些流行术语(尤其是按文后的清单做进一步阅读),这可以成为你茶余饭后的谈资.