Deep Learning的一些tricks

看到一篇关于deep learning一些小trick的博客,感觉对于初学者可能帮助很大,但老司机应该对这些所谓的“黑魔法”烂熟于心。不管怎么说,还是囊括了大部分目前主流的一些tricks,就我本人而言也都在工作中用了这些小技巧,只不过平时都当做common sense了并没有太在意,因此也想着整理记录下来。

  • 在每一个epoch结束后,一定要对数据做shuffle。也就是说要确保每轮迭代时mini-batch中的数据是不一致的

  • 基于DL对大数据量的高可用性,尽可能的扩充数据。最常见的应该是图片分类问题,比如对图片进行旋转、镜像、加噪、白化等等(就像keras的image augmentation)。像在公司里比如提用户训练样本时候就可以通过滑动时间窗口的方法来获取更多数据

  • 在训练大规模数据和模型前,先对数据进行一波小比例采样,如果采样数据能够使模型效果足够好的话,说明你的模型最终是可以收敛的——这个trick感觉真的没有太多人会做,如果做的话一般也都是在程序debug时候为了减少训练时间,大多数情况下都是拿到一批数据直接真刀真枪的干

  • 永远都要使用dropout以防止过拟合,尤其是要在神经元比较多的全连接或卷积层后——现在一般都要随手加个dropout吧,要不总感觉少点什么

  • 避免使用LRN pooling,尽量使用max pooling,因为快!

  • 和sigmoid说bye-bye,和tanh说bye-bye,原因很简单:容易饱和,gradient vanishing,ReLU和PreLU明显是目前最好的选择

  • 在max pooling层之后用ReLU或者PreLU,而不是之前,道理也很简单:max pooling之后维度减小,可以减少不少的计算量

  • 尽量别用ReLU,过时啦!投入PreLU的怀抱!因为ReLU在初始阶段容易把训练卡死,PreLU的alpha选个0.1,完爆ReLU——这个结论感觉下的过于鲁莽,虽然理论上是这样的,但是实验里也没见过PreLU比ReLU好到哪里,但是对于训练初始阶段的情况还真没关注过,以后可以对比实验下

  • 使用Batch Normalization。不多说,和dropout都差不多,加一下已经成习惯了。最近又看了BN的原作者新搞出了一个Batch Renormalization,消除了没个mini-batch中数据的差异性,据说更牛逼

  • 对数据做预处理时映射到-1~1区间,而不是减去他们的均值——估计都是经验之谈,可能每份数据所呈现的结果都不太一样,个人习惯是做z-score,映射到0~1

  • 尽量使用轻量级的模型,因为当你把一个庞大的model放到server上时效率的影响可能对用户体验并不是很好,即使这个工作会使你的模型准确率不够高

  • 如果使用轻量级的模型,尽量做ensemble,如果ensemble了5个network,基本大约可以使准确度提搞3%——这玩意居然给量化出来了,感觉也得看是什么network吧

  • 尽可能用xavier initialization做参数初始化,但是只用在全连接层,别用在CNN层上——应该就是告诉你初始化的时候weights的方差取个啥值

  • 在CNN中可能的地方使用1*1卷积核,会增加spatial locality,可以自己控制升维或者降维,同时也可以把模型做的很deep——谷歌爸爸用了也说好

  • 没有好的GPU,就别搞DL了

  • DL不是神,理解好你要解决的问题,别就会傻套现成的网络结构

以上。

参考:The Black Magic of Deep Learning - Tips and Tricks for the practitioner