[DeepLearning]深度学习之五常见tricks

本文主要给出了在实现网络或者调节代码过程使用的以及平时看一些文章记录下来的一些小技巧,主要针对卷积网络和图像处理。就个人感受,有些技巧还是非常有效的,而且通常可以通过看开源库的一些文档或者源代码来发掘这些内容,最后能够称为自己所用。

构造validation set

一般数据集可能不会给出验证集,所以自己会从给的训练集中按照一定比例(9:1)分离出验证集。

增加训练数据

为了更好的训练网络,有时候需要增加原始数据集,一般有以下方法[1]:

  • 沿着x轴将图片左右翻转
  • 随机的剪切、缩放、旋转
  • 用pca来改变RGB的强度值,产生分别对应的特征值和特征向量,然后用均值为0方差为0.1的随机数与特征值和特征向量相乘得到新的数据[2]

预处理

常见的是减均值、除方差,还有变化到-1~1,主要针对不同尺度的特征,例如房价预测的例子中,每个房子的房屋大小和卧室数量就不在一个数量级上,这种情况就需要对每一维特征进行尺度变换normalize,还有的方法是使用pca白化。但是就图像处理领域,通常就减去一个均值就可以直接拿来计算。

权重初始化

不要全部初始化为0,这样会导致大部分的deltaw都一样,一般用高斯分布或者uniform分布。但是这样的分布会导致输出的方差随着输入单元个数而变大,因此需要除以fan in(输入个数的平方根)。

卷积tricks

  • 图片输入是2的幂次方,例如32、64、96、224等。
  • 卷积核大小是3*3或者5*5。
  • 输入图片上下左右需要用0补充,即padding,且假如卷积核大小是5那么padding就是2(图片左右上下都补充2),卷积核大小是3padding大小就是1。

pooling层tricks

poolin层也能防止过拟合,使用overlapped pooling,即用来池化的数据有重叠,但是pooling的大小不要超过3。

max pooling比avg pooling效果会好一些。

避免overfitting

  • drop out能够避免过拟[1],一般在加在全连接层后面[3],但是会导致收敛速度变慢。
  • 正则化也能避免过拟合,L2正则l2正则惩罚了峰值权重,l1正则会导致稀疏权重,趋近于0,l1会趋向选择有用的输入。又或者可以给给权重矢量的模加上上边界(3 or 4),更新时对delta w进行归一化。

调参

使用pretrain好的网络参数作为初始值。然后fine-tuning,此处可以保持前面层数的参数不变,只调节后面的参数。但是finetuning要考虑的是图片大小和跟原数据集的相关程度,如果相关性很高,那么只用取最后一层的输出,不相关数据多就要finetuning比较多的层。

初始值设置为0.1,然后训练到一定的阶段除以2,除以5,依次减小。

加入momentum项[2],可以让网络更快的收敛。

  • 节点数增加,learning rate要降低
  • 层数增加,后面的层数learning rate要降低

激励函数

Sigmoid作为激励函数有饱和和梯度消失的现象,在接近输出值0和1的地方梯度接近于0(可通过sigmoid的分布曲线观察出)。因而可采用Rectified Linear Units(ReLUs)作为激励函数,这样会训练的快一些,但是relu比较脆弱,如果某次某个点梯度下降的非常多,权重被改变的特别多,那么这个点的激励可能永远都是0了,还有带参的prelu、产生随机值的rrelu等改进版本。但是leaky版本(0换成0.01)的效果并不是很稳定。

通过做图来观察网络训练的情况

可以画出随着不同参数训练集测试集的改变情况,观察它们的走势图来分析到底什么时候的参数比较合适。

  • 不同学习率与loss的曲线图,横坐标是epoch,纵坐标是loss或者正确率
  • 不同的batchsize与loss的曲线图,坐标同上

数据集不均衡

这种情况如果数据集跟imagenet的比较相近,可以直接用finetuning的方法,假如不相近,首先考虑重新构造数据集的每一类个数,再次可以减少数据量比较大的类(减采样),并且复制数据量比较小的类(增采样)。

以上是在实现卷积神经网络中使用过的和平时看文章中提及到的一些技巧,大多数现在的开源软件都是已经实现好了,直接调用使用即可。

参考:[1] http://cs231n.stanford.edu/

[2]http://lamda.nju.edu.cn/weixs/project/CNNTricks/CNNTricks.html

[3] http://www.cs.toronto.edu/~fritz/absps/imagenet.pdf