最近做一个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=128batch-size=32batch-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%足够了,没将此网络继续进行下去)

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐