最近做一个CNN,从0开始调节,终于让准确率提高到了95%。
网络结构为,两层卷积,池化,两层卷积,池化,两层全连接:
目录
打乱
优化器
BATCHSIZE(重要!)
权重初始化
其他方法
打乱
1.千万要对数据进行shuffle,不然准确率低的令人发指。发现某一类别正确率极高,但是数据是平均分布的,怀疑shuffle出错,但是没有。。。
优化器
2.由于准确率一直很低,怀疑陷入局部最优,也可能是鞍点,所以采用各种优化器尝试了下,
adam结果:
理解:adam采用自适应优化,所以它的优势是训练快,但是问题在于更容易陷入局部最优、鞍点等!虽然SDG慢了点,但是真好用(所以那么多研究中都采用SDG)
SDG对应tensorflow:tf.train.GradientDescentOptimizer
ADAM对应tensorflow:tf.train.AdamOptimizer
采用SDG方法损失函数突破1.5,(ADAM为1.9)
BATCHSIZE(重要!)
(我这个网络的问题主要与batchsize有关,由于此参数的不合适,学习到内容过于偏离预期!)
3.batchsize,主要三个作用:
- 内存利用率(只要能跑就行)
- 跑完一次 epoch(全数据集)所需的迭代次数减少,对于相同数据量的处理速度进一步加快。但是盲目加大导致达到相同的精度,其所花费的时间大大增加了,从而对参数的修正也就显得更加缓慢。
- 一般来说 Batch_Size 越大,其确定的下降方向越准,引起训练震荡越小。但是Batch_Size 增大到一定程度,其确定的下降方向已经基本不再变化。也就说容易陷入局部最优(也可以理解为如果batch_size很大会导致学习到的特征偏向于整体特征,学习到的内容不够)
忽略异常的波动:发现合理减少batch-size后准确率提升了,损失函数值下降到新高度(batch-size=700时准确率不足40%,损失最低达到1.5) 橙色为训练集,蓝色为验证集 | ||
batch-size=128 | batch-size=32 | batch-size=8 |
下图为batch-size=32时每个类别的正确率,发现某几个类别从一开始就学习不到(这里只有两个类别没有学习到,batch-size值更大时更多类别学习不到,尤其700时只能学习到2个类别),所以:Batch_Size 增大到一定程度,其确定的下降方向已经基本不再变化,陷入局部最优 |
来一个batch-size=8对比: |
思考那是不是batch-size越小学习的内容越多,最终准确率越高?(虽然越小训练时间越长,不考虑时间的情况下:)
batch-size=1:只学习到了2个类别,未截图
batch-size=2:
原理:batch-size过大,下降方向为整体方向,学习不到足够的东西,batch-size过小,每次下降方向横冲直撞,其实会偏向每个都有的特征方向,最终导致学习不到东西,无法达到预期准确率。只有合理的batch-size才能快准
方法:观测前几代,看是否学习到足够的内容,及时停止,及时止损(batch-size可以理解成下降方向,而算法结果跟初始化权重是有关系的,所以如果在这种batch-size下,在这种下降方向下,总是落到很差的局部最优解,就及早重新来过)
权重初始化
4.权重初始化影响很大,不同初始化导致不同结果,多试几次。而且An Explanation of Xavier Initialization文章介绍xavier不适用于卷积初始化,适用于全连接初始化(尝试了几次,感觉没啥区别啊,想看看原理,文章怎么都找不到。。。)
其他方法
5.batch normlization:加入BN层,可以让权重初始化更加优秀(没有尝试过,当batch-size调整的比较好,多试几次结果就比较好了)
6.网络调整,将网络扩宽或者加深,可以提高准确率(95%足够了,没将此网络继续进行下去)