Captain Jack的答案
Captain Jack的知乎主页
作者:Captain Jack
链接:https://www.zhihu.com/question/25097993/answer/127472322
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
先说下我的观点,调参就是 trial-and-error. 没有其他捷径可以走。唯一的区别是有些人盲目的尝试,有些人思考后再尝试. 快速尝试,快速纠错这是调参的关键.
看了杨军的回答。对于这个回答,下面的评论里面
说的很对。这个回答主要内容更多的是侧重理解网络。而非训练网络.
我要再强调下,杨军的回答更多的涉及是理解网络而非训练网络. 是的,没错。你看完回答中的所有内容,对不起,你还是不知道怎么实际训练一个网络,尤其是复杂任务下的网络 (因为简单任务根本不需要,直接上来效果就会很好,除非你要刷简单任务的排行榜).
- 首先说下可视化:
我个人的理解,对于可视化,更多的还是帮助人类以自己熟悉的方式来观察网络。因为,你是不可能边观察网络,还边调参的。你只是训练完成后 (或者准确率到达一个阶段后), 才能可视化。在这之前,网络没有学习到良好的参数,你可视化了也没意义,网络达到不错的准确率了,你看看其实也就听个响。同样,你的网络训练的一塌糊涂,你可视化也没什么意义,唯一能够看到的就是中间结果乱七八糟,或者全黑全白,这时候你直接看最后准确率就可以知道这网络没救了.
- 关于权重的可视化 [Visualize Layer Weights](现在是否强求 smooth 其实意义不大,这个后面说.):
同样,你看到一个不满足平滑结果的图像,你知道,这网络训练的不好,但是为什么呢?是数据不好?没有预处理?网络结构问题?Learning Rate 太大或者太小?或者就是差了一个 LRN 层 (之前我就遇到,加个 LRN 就能出 smooth 的 weights, 当然这其实和预处理有关)?
Smooth 是需要看一下的,心里有个数。但是具体调参怎么调是没辙的. 第一 , 你不可能告诉网络,这层你得学个边界检测的功能出来. 第二 , 不同任务下会有不同的 weights (虽然底层的特征有很大的通用性), 你觉得你凭什么来指导一个看图片比你快得多的机器?
再说现在是否需要强求 smooth. 现在的趋势是鼓励使用小 filter, 3x3 大小,多加层次 (这样,非线性更好点). 换句话说,3x3 的图片,总共才 9 个像素,你怎么判断 smooth 与否呢?当然如果你使用大的 filter, 一般 5x5 往上,运气不差的话,你是可以看到 smooth 的结果的.
咱们再说另外一个极端,一个网络,运行的完美 (满足应用要求就算完美), 打开一看,这 weights 不 smooth 啊。你告诉我,你打算怎么办?没错,具有不平滑的权重的网络同样可以获得很好的结果 (这种情况我都习以为常了).
- 那么可视化网络就不重要了?
非常重要,但是不在训练这块 , 而是帮助理解网络的原理这块。理解网络原理后,你才能在设计结构的时候心里有感觉 (只是有感觉而已), 网络出了问题,或者在某些情况下不满意,有更好的直觉去调整.(没错,只是直觉,虽然有些情况下的调整从网络原理来看逻辑上应该可以工作,但是人家就是不工作,你能咬机器去么?)
- 那么怎样训练一个不错的网络呢?
这是一个很好的链接,说明了如何从零开始不断的 trial-and-error (其实这里面没遇到什么 error):
Using convolutional neural nets to detect facial keypoints tutorial
========================================================
我自己的经验,有下面这些:
基本原则:
快速试错
一些大的注意事项:
1. 刚开始,先上小规模数据,模型往大了放,只要不爆显存,能用 256 个 filter 你就别用 128 个。直接奔着过拟合去。没错,就是训练过拟合网络,连测试集验证集这些都可以不用.
为什么?
- 你要验证自己的训练脚本的流程对不对。这一步小数据量,生成速度快,但是所有的脚本都是和未来大规模训练一致的 (除了少跑点循环)
- 如果小数据量下,你这么粗暴的大网络奔着过拟合去都没效果。那么,你要开始反思自己了,模型的输入输出是不是有问题?要不要检查自己的代码 (永远不要怀疑工具库,除非你动过代码)? 模型解决的问题定义是不是有问题?你对应用场景的理解是不是有错?不要怀疑 NN 的能力,不要怀疑 NN 的能力,不要怀疑 NN 的能力。就我们调参狗能遇到的问题,NN 没法拟合的,这概率是有多小?
- 你可以不这么做,但是等你数据准备了两天,结果发现有问题要重新生成的时候,你这周时间就酱油了.
2. Loss 设计要合理.
- 一般来说分类就是 Softmax, 回归就是 L2 的 loss. 但是要注意 loss 的错误范围 (主要是回归), 你预测一个 label 是 10000 的值,模型输出 0, 你算算这 loss 多大,这还是单变量的情况下。一般结果都是 nan. 所以不仅仅输入要做 normalization, 输出也要这么弄.
- 多任务情况下,各 loss 想法限制在一个量级上,或者最终限制在一个量级上,初期可以着重一个任务的 loss
3. 观察 loss 胜于观察准确率
准确率虽然是评测指标,但是训练过程中还是要注意 loss 的。你会发现有些情况下,准确率是突变的,原来一直是 0, 可能保持上千迭代,然后突然变 1. 要是因为这个你提前中断训练了,只有老天替你惋惜了。而 loss 是不会有这么诡异的情况发生的,毕竟优化目标是 loss.
给 NN 一点时间,要根据任务留给 NN 的学习一定空间。不能说前面一段时间没起色就不管了。有些情况下就是前面一段时间看不出起色,然后开始稳定学习.
4. 确认分类网络学习充分
分类网络就是学习类别之间的界限。你会发现,网络就是慢慢的从类别模糊到类别清晰的。怎么发现?看 Softmax 输出的概率的分布。如果是二分类,你会发现,刚开始的网络预测都是在 0.5 上下,很模糊。随着学习过程,网络预测会慢慢的移动到 0,1 这种极值附近。所以,如果你的网络预测分布靠中间,再学习学习.
5. Learning Rate 设置合理
- 太大: loss 爆炸,或者 nan
- 太小:半天 loss 没反映 (但是,LR 需要降低的情况也是这样,这里可视化网络中间结果,不是 weights, 有效果,俩者可视化结果是不一样的,太小的话中间结果有点水波纹或者噪点的样子,因为 filter 学习太慢的原因,试过就会知道很明显)
- 需要进一步降低了: loss 在当前 LR 下一路降了下来,但是半天不再降了.
- 如果有个复杂点的任务,刚开始,是需要人肉盯着调 LR 的。后面熟悉这个任务网络学习的特性后,可以扔一边跑去了.
- 如果上面的 Loss 设计那块你没法合理,初始情况下容易爆,先上一个小 LR 保证不爆,等 loss 降下来了,再慢慢升 LR, 之后当然还会慢慢再降 LR, 虽然这很蛋疼.
- LR 在可以工作的最大值下往小收一收,免得 ReLU 把神经元弄死了。当然,我是个心急的人,总爱设个大点的.
6 对比训练集和验证集的 loss
判断过拟合,训练是否足够,是否需要 early stop 的依据,这都是中规中矩的原则,不多说了.
7 清楚 receptive field 的大小
CV 的任务,context window 是很重要的。所以你对自己模型的 receptive field 的大小要心中有数。这个对效果的影响还是很显著的。特别是用 FCN, 大目标需要很大的 receptive field. 不像有 fully connection 的网络,好歹有个 fc 兜底,全局信息都有.
简短的注意事项:
- 预处理: -mean/std zero-center 就够了,PCA, 白化什么的都用不上。我个人观点,反正 CNN 能学习 encoder, PCA 用不用其实关系不大,大不了网络里面自己学习出来一个.
- shuffle, shuffle, shuffle.
- 网络原理的理解最重要,CNN 的 conv 这块,你得明白 sobel 算子的边界检测.
- Dropout, Dropout, Dropout (不仅仅可以防止过拟合,其实这相当于做人力成本最低的 Ensemble, 当然,训练起来会比没有 Dropout 的要慢一点,同时网络参数你最好相应加一点,对,这会再慢一点).
- CNN 更加适合训练回答是否的问题,如果任务比较复杂,考虑先用分类任务训练一个模型再 finetune.
- 无脑用 ReLU (CV 领域).
- 无脑用 3x3.
- 无脑用 xavier.
- LRN 一类的,其实可以不用。不行可以再拿来试试看.
- filter 数量 2^n.
- 多尺度的图片输入 (或者网络内部利用多尺度下的结果) 有很好的提升效果.
- 第一层的 filter, 数量不要太少。否则根本学不出来 (底层特征很重要).
- sgd adam 这些选择上,看你个人选择。一般对网络不是决定性的。反正我无脑用 sgd + momentum.
- batch normalization 我一直没用,虽然我知道这个很好,我不用仅仅是因为我懒。所以要鼓励使用 batch normalization.
- 不要完全相信论文里面的东西。结构什么的觉得可能有效果,可以拿去试试.
- 你有 95% 概率不会使用超过 40 层的模型.
- shortcut 的联接是有作用的.
- 暴力调参最可取,毕竟,自己的生命最重要。你调完这个模型说不定过两天这模型就扔掉了.
- 机器,机器,机器.
- Google 的 inception 论文,结构要好好看看.
- 一些传统的方法,要稍微了解了解。我自己的程序就用过 1x14 的手写 filter, 写过之后你看看 inception 里面的 1x7, 7x1 就会会心一笑...
此外,评论中有启发的内容:
问:请问大神,如果训练的 loss 曲线很漂亮,但验证的 loss 不停震荡,是什么原因呢?调参主要是看训练的 loss,还是验证的 loss?
答:先看训练的准确率,需要超过预期,然后再看验证集的。验证震荡的特别大的话,最好是人工看看数据集,还有中间模型在验证集合上的预测结果,之后可能才会有启发。
问:现在 adam 其实不错,不比 sgd+momentum 差,一般可以先上 adam 试试,但是个人感觉会比 sgd+momentum 训练得慢点;另外我有两个问题,xavier 会比 HeKaiming 提出的那个好吗?第 21 点不太明白,能否再细说一下,谢谢
答: 1x7 这种是为了处理横竖条纹一类的特征。用的 1x14 就是为了提取竖方向上的粗条纹。 xavier 会比 HeKaiming 提出的那个好吗? 才瞟到这个问题。配合 ReLU, 优先用 msra.
问1:请问一下你说的无脑用 ReLU (CV 领域) 无脑用 3x3 无脑用 xavier. 是什么意思啊?那应该用什么?
答1: 无脑用,意思是什么都别想,用这个就可以。
问1:对了 你说 95% 不用 40 层 那现在流行的残差网络最少也有 52 层 不是说这个网络模型很好吗
答1:用不上。那么多层的学术上有点意义。实际应用的根本不用那么多层。好是个多元的标准,要看应用场景的。
问1:哦 我看好多用 VGG 的比较多 实际应用中做图像的二分类一般用什么网络模型会更好点呢?Alexnet?
答1:二分类?那场景应该不复杂吧. LeNet 就可以。不行自己可以加点层次。或者搬点 VGG, Inception 的结构到自己网络里面。你直接用 VGG 这种也可以。可能就是大才小用了.
问1:也得看目标的形态复杂程度,例如要在各种猫里面,只识别波斯猫,但是不能把印度猫,英国猫,法国猫,比利时猫等其他种类的猫也当成波斯猫,要求准确度 99.9%,
形态非常接近的时候难度其实不小,你说是吧
问2:目前我做一个纺织上的项目,只要识别各种布的接缝。但是布有很多条纹,而且有些瑕疵形态上跟接缝形态也相似,很容易识别错,现在的方法就是把识别错的都做到背景里,不知道是不是还有更好的方法,所以我拿猫的识别做例子。因为你要是区分猫跟狗,因为形体差异很大,那很容易,但是要区分不同种类的猫,差别就没这么大了,难度陡增.....不知道作者有没有做过这种课题。
问3:您好,我现在也有这样的疑问,我做的是医学肿瘤图像二分类,肉眼是分别不出来的,我直接迁移 VGG16 的网络进行 fine-tune,正确率最好 70 左右一直提不上去,请问老哥我直接迁移 VGG 是否有问题吗?要是从新设计一个模型的思路应该是怎样的?感觉应该设计好一个模型在进行调参是一个正确的思路,请问老哥您当初设计出来的二分类模型是怎样得出来的?谢谢
问4:老哥您有什么思路吗,对于这种精细的分类应该设计怎样的模型?
答2:如果单做分类 上 resnet googlenet 然后重点是 loss 函数很重要 你现在是做二分类 建议试试类平衡 loss 函数 就是给难易样本上不同的权重 2. 另外也可以试试 focal loss
问4:请问识别错的做到背景里是什么意思?难例?
答2:是的,hard negative mining
问: “不像有 fully connection 的网络,好歹有个 fc 兜底,全局信息都有”。这句话如何理解??CNN 中这种 fc layers 的作用到底体现在哪??
答:fc 作用就是可以把整张图的信息汇总,卷积本身一般没这个能力。
问:看到中间提到了一点关于 FCN 的,有两个问题想请教下:(1) FCN 的网络的 loss,是跟图像大小相关的,图像越大,loss 越大,具体的 loss 怎么算的啊?(2)一般在 FCN 的分割的情况下,不同的类别的样本不均衡影响多大?(3)receptive field 影响一般大感知域和小感知域有什么影响吗?
答: 1. loss 大小看具体选用的 loss function,loss 最终是需要归一的,具体怎样需要根据情况。 2. 有影响,如果很大的话,要考虑加权重来平衡。 3. receptive field 大小和网络能够观测到的上下文信息多少有关。