整理一下如何调参,开始是准备翻译,后来加入了一些自己的理解,有少部分不是很确定的没有写出来,如果有问题可以看原文,在末尾有写出。水平有限,如果有错误请指出。
获取数据:确保有足够多的高质量输入-输出的数据集,而且要有代表性。
有时并没有这么大的数据集,比如字符识别中对mnist数据库的训练,很容易就可以达到98%的识别率,但是真正用在实际中会发现效果并没有那么好,把数据库的图片存到硬盘看一下,会发现几乎所有字体都在图片正中,大小几乎一样,而且没有大幅度的旋转,所以这里图片的代表性就不够强,有必要通过一些方法扩大数据集。当然有些情况下有些数据可能会对网络的训练有不好的影响,如果有方法可以去掉这些数据应该也会比较有用。
预处理:将数据中心化,使其均值为0,各维度的方差为1是非常有效的。有些情况下输入数据的数量级差别非常大,我们最好对数据取log(1+x)。
theano上mnist数据集的例子是把输入x平均到0-1的浮点数,所以这里还有有点异议的,不过这步操作确实非常有必要。记得人脸识别中,为了防止光照的影响有使用log(1+x)处理,应该是为了减小高亮度部分的影响,不过在训练卷积神经网络的时候,这一步不一定有很好的效果,因为网络在我们不知道的情况下可能已经做了相同功能的处理,不过尝试加入自己定义的某些特征有时还是会有比较好的效果。
Minibatches的选择:(虽然实际中,将minibatches选为1会达到较好的效果,而且能达到较低的过拟合,不过为了达到更快的计算效果 ,我们必须要做出一个权衡,所以minibatches一般会选较大的数值。比如mnist数据库中的例程minibatches选的是128,对于较大的数据集可以增加minibatches的大小,或者根据显存的情况增大minibatches。)
梯度归一化:在训练的过程中不一定要修改学习率,可以通过修改minibatches的大小来修改梯度变化。(这里标题翻译的和正文不统一的感觉)
修改学习率:开始使用一个标准化的学习率,然后慢慢减小。
0.1是一个典型的学习率取值,对大多说的情况都可以使用,不过有时也会根据情况减小数值。
使用validation set做交叉验证,可以从训练集中取出一部分不做训练,用于验证训练的效果,根据效果来修改学习率或者终止训练过程。如果训练结果在验证集上不再有更好的效果,可以尝试把学习率缩小到1/2或者1/5。还有一个方法是根据更新值变化和权值的比率,如果在10^-3左右是比较好的,如果太小的话学习速度会比较慢,太大的话会不稳定。
初始化权值:在最开始随机初始化权值
这里提到的初始化方法将的不是特别明白,还是不写的。不过有说到,对于浅层的网络较简单的初始化方法,网络也可以正常工作,但是对于深层网络,如果没有较好的初始化,网络很可能会无法工作,所以如果你的网络模型不能工作要尝试初始化权值而不要急着修改网络。在theano的例程中用到的权值初始化是±sqrt(6/(fan_in+fan_out)), fan_in是上一层的单元数fan_out是下一层的单元数。
梯度值检验:如果你用的不是theano或者torch,在求梯度的时候要进行检验,记得Andrew
Ng的机器学习的课程中也有提到过,这里我用的是theano,在编程中没有注意过这个问题。
扩大数据集:对于图像可以加入旋转和翻转,对于语音处理,可以加入随机噪声等方法,效果非常明显。
使用Dropout:Dropout层对于防止过拟合的效果非常好,不过有一个明显的缺陷就是会减慢网络的训练速度。and
to not forget to turn off Dropout and to multiply the weights by (namely by 1-dropout probability) at test time。在测试的时候记得去掉Dropout层,不过我有试过,感觉去掉并没有较好的效果,可能是没有操作正确。
集成:训练多个分类器,然后对他们的结果去平均。这里有点不确定,没用过,等之后理解了再补全。
突然想到,这里没有提到正则化,今天先写到这里吧,之后再补充。
参考文献:http://yyue.blogspot.com/2015/01/a-brief-overview-of-deep-learning.html 正常应该打不开,没有完全翻译,写了一些自己的理解。
版权声明:本文为博主原创文章,未经博主允许不得转载。