深度学习小结

接触深度学习有一段时间了,写一点自己的感悟,有些是验证过,有些只是想法,有错误请大家指出。

对于图像的分类问题,处理的步奏一般是特征提取+训练算法,和传统的识别方法没有太大区别。不过传统的算法对于特征提取以及图像切割要求比较严格,这里通过卷积网络以及池化的方法可以比较方便的完成特征提取,卷积其实就是对图像做了一定的旋转,缩放等各种变换,池化提取了图像的统计特征,所以对于一些干扰的抗性会比较好。之后再通过神经网络训练,就可以达到比较好的效果。这里提取的特征有点不可控,到底是什么特征,物理意义如何。所以也可以尝试加入自己定义的特征到网络中,有些特征效果会比较好。

不过训练的过程还是有很多技巧,同样的一个网络,不同的人训练出来的结果可能也会差别比较大。对于复杂的网络,在开始阶段最好降低Dropout层的参数,在训练的差不多之后再修改,因为Dropout层虽然能比较有效的防止过拟合,但是也会使训练的速度变慢。网络开始训练阶段最好也不要用算法扩大数据集,不然网络收敛会非常慢,最好先通过几轮训练初始化一下参数之后再做处理。训练过程中最好有日志记录,最后能转化为图形显示,方便观察网络的效果。

接着说一下比较著名的Lenet-5,用数据库里的的资源来做测试会发现识别效果非常好,识别率能轻松达到98%以上。但是如果用到实际场合中呢,比如自己输入一个手写字,然后用之前训练的网络去识别,会发现识别率大幅下降。深度学习是很强,有旋转抗性,对噪声也有抗性,但并不是说怎么旋转都能识别。之前我有做过一个手写输入然后通过卷积神经网络识别的小程序,会发现如果输入不在正中间,或者旋转角度大一些识别效果就会比较差。这里作者给出了他的网络模型,但是并没有具体说明如何训练模型。

如果要增加对旋转的抗性最简单的方法还是通过算法增加数据集,增加有旋转以及噪声的数据集,这样才能有效的增加网络对干扰的抗性。而且这个训练的网络中并没有负样本,如果我随便输入一个英文字符a,网络也会输出一个数字给我。如果用网络来识别一串字符(如下图),感觉算法的思路可能是用一个框按照一定步幅来遍历这幅图,然后把识别出来的位置做一个聚类,最后输出结果。不过要做聚类的话之前的网络应该不行,需要做一定的修改,需要有负样本,有看过TLD算法里提到获取负样本的方法,从正样本的边角裁剪图片获得(不知道用在这里效果如何)。自己还想了一个方法,通过网络层的softmax层输出得到训练值,这里数值的意义是每个分类的概率,通过概率以及测试结果的正确与否来做训练,判断测试结果是否合理。

深度学习小结_第1张图片 

一般情况下较深的网络识别效果不会差,但是计算速度会减慢,而且网络的权值也会比较大,不易于存储或者移植到一些小型系统上。如何构建一个适当深度的网络也是比较有趣,googlenet这篇文章很不错,提到了如何减小网络的权值并且又能得到较好的训练结果。

开始学习的时候装了caffe,发现看不懂。然后就从基础的机器学习方法开始学习,读了《机器学习实战》,码了一下上面的代码,确实比较有帮助,基础还是比较重要。然后发现了theano,基础教程很细致,不过编程比较麻烦。再后来有用keras(theano的基础上封装),编码非常方便,不过也有缺点,官方文档不详细,有些功能要自己去源码里找,而且封装的比较好,所以可改动性比较好。最近想尝试实现Googlenet,就发现keras有点用不来。所以这里再介绍一下lasagne(也是在theano的基础上封装),比keras编码麻烦一点,但是官方文档很详细,而且可改动性很大,可以自己修改很多参数,而且可以比较方便的实现Googlenet这种复杂的网络。

有点乱。。。



你可能感兴趣的:(深度学习小结)