当前位置: 华文问答 > 数码

深度学习调参有哪些技巧?

2016-10-22数码

破千赞了,来补两个亚马逊工程师的CNN调参经验文章。

大概调了快一年CNN(2019年1月到今天),看到这个话题挺感兴趣的,以下是我的总结

做工程

  • 3\times 3 卷积是CNN的主流组件。平时有设计一些解决分类,回归任务的网络,里面的卷积核基本都设置为3\times 3 ,要说原因的话应该去问问 VGG16 吧。两个3\times 3 的卷积核堆叠能获得5\times 5 卷积核的感受野并且参数比5\times 5 卷积核少,所以是大量推荐使用的。
  • 可以适当使用1\times N 卷积。为什么要提这一点呢,这是因为1\times N 卷积可以减少计算量,并且1\times N 卷积可以在某个方向强调感受野,也就是说假如如果你要对一个长方形形状的目标进行分类,你可以使用1\times N 的卷积核搭配3\times 3 的卷积核对长边方向设定更大的感受野,或许可以获得泛化性能的提升。
  • ACNet结构。这个研究来自于ICCV2019,可以在3\times 3 卷积的基础上加上1\times 3 和3\times 1 的旁路卷积核,最后在推理阶段把三个卷积核都 fusion 到3\times 3 卷积核上,在许多经典CV任务上都可以获得大概1个点的提升。大家可以看看这篇文章解读,来自公众号AI科技评论。 a href="https:// mp.weixin.qq.com/s/uRwh 2-dSVyZeO1sbJzx6qg ">33卷积+13卷积+3*1卷积=白给的精度提升
  • 卷积核权重初始化方式。对于 weight 的初始化我一般都是使用 xavier 初始化。当然也可以可以尝试何凯明大神的He初始化。对于bias的初始化全置于0。
  • Batch Normalization 。这是我一直在使用的技巧,可以很大程度的加快收敛速度。建议搭建自己网络的时候尽量加上 BN ,如果有 BN 了全连接层就没必要加 Dropout 了。
  • 目标检测不能盲目去掉 fpn 结构。在针对自己的数据调检测任务如 yolov3 的时候不能盲目砍掉 fpn 结构,尽管你分析出某个分支的Anchor基本不可能会对你预测的目标起作用,但如果你直接去掉分支很可能会带来漏检。
  • 优化器的选择。我基本都是带动量的 SGD 。如果优化不动可以试试 Adam
  • 激活函数。可以先用 ReLU 做一版,如果想再提升精度可以将 ReLU 改成 PReLU 试试。我更倾向于直接使用 ReLU
  • batch_size :在不同类型的任务中, batch_size 的影响也不同,大家可以看看这篇 batch_size 对模型性能影响的文章,来自公众号AI开发者。Batch_size是怎么影响模型性能的
  • 初始学习率。一般我是从 0.01 开始设置,我个人认为这个学习率和学习率衰减策略是相关的,但不宜设置的过大过小, 0.01 0.1 应该是比较常用的。学习率衰减策略我一般使用 multistep 方式, step_size 的设置要看视你的的 max_iter 而定。
  • 数据与处理之 zero-center 。第一次见到这个词是在看cs231n的视频上。主要有2个步骤,第一个是减均值,第二个是除以方差。这样做下来最后的输入是满足均值为0方差为1的概率分布的,一般减均值是最常用的,后面的除以方差用不用可能需要自己动手试验一下看看效果。
  • 残差结构和密集连接。 resnet 的残差结构和 dense net 密集连接结构,做工程的时候考虑到速度近乎不可能说完全使用完整版本的 resnet densenet 的完整结构,但我们可以自己动手将我们网络的某些模块替换为残差结构和密集连接,替换的时候可以适当降低这俩结构的复杂度,类似于通道数减半,密集连接中只保留一半连接等等。这里需要做一些消融实验来验证改进后的精度。
  • 关于loss。优秀的 loss 一般是对模型的泛化性能有所改善的,但在用 loss 的时候往往并不是直接替换 loss 那么简单,需要仔细思考 loss 背后的数学原理,要用对地方才可有提升。例如,如何将Focal Loss用到YOLOv3中提升 map ,大家可以看看这个帖子。https://www. zhihu.com/question/2933 69755 。
  • 找到模型调参时的可靠评价指标。在调整参数训练模型时一定要找到正确的评价指标,没调整一个参数就要记录一下模型的评价指标如准确率, map 值, miou 值等。并且在调参时建议将调整的参数和在测试集上的精度组合成一个字符串给模型重命令,方便之后快速 review
  • 使用了带 backbone 的网络,如训练 VGG16-SSD 建议选择 finetune 的方式,从头训练不仅费时费力,甚至难以收敛。
  • 在做分割实验的时候我发现用upsamling 加1*1卷积代替反卷积做上采样得到的结果更平滑,并且miou差距不大,所以我认为这两者都是都可以使用的。
  • 一些Anchor-based目标检测算法为了提高精度,都是疯狂给框,ap值确实上去了,但也导致了fp会很多,并且这部分fp没有回归,在nms阶段也滤不掉。相比于ap提升而言,工程上减少fp更加重要。Gaussian yolov3的fp相比于yolov3会减少40%,Anchor-free算法暂时接触得不多,就不太了解了。
  • 做比赛

  • 特征提取。VGG16,VGG19,ResNet50,Xception是非常好用的几个特征提取模型。建议使用训练好的经典模型对数据集提取特征向量存储到本地,更方便使用,同时可以大幅度降低显存消耗。
  • ensemble:
  • 将不同的经典网络提取出的特征向量,假设 VGG16 提取出的特征向量维度是 [N,c1] , ResNet50 提取的特征向量维度是 [N,c2] , Xception 提取的特征向量维度是 [N, c3] ,那么我们可以使用三个系数 a、b、c 将其组合为形状为 [N, a*c1+b*c2+c*c3] ,其中 a、b、c 三个参数的取值代表我们使用哪个模型的特征多一些,如果是分类回归比赛,我们在后面接特征处理网络就可以了。可以取不同的 a、b、c 得到不同的特征,然后对结果做 voting soft-voting 等多种处理,一般结果不会太差啦。
  • 可以使用不同的初始化方式训练出模型,然后做ensemble。
  • 可以使用用不同超参数(如学习率, batch_size ,优化器)训练出不同模型,然后做ensemble。
  • 因为我就做了一点点入门级比赛,上面介绍的方法取得了还不错的结果,所以我就在这里献丑啦,方法确实挺无脑的,大家笑一笑就好啦。 继续想了下,我好像除了这些有接触或者使用到,暂时没有什么其它的了,如果想起其他的了,之后补充下。

    -----------------------------------更新--------------------------------

    欢迎大家关注我的公众号和我交流算法哦。