20160620卷积神经网络
预备知识:前向神经网络和BP训练算法。
cnn目前主要应用在图像领域,它的网络结构相对于普通的神经网络来说,有了卷积层以及参数共享机制使得参数数量大大减少。
1. CNN结构
先来个图吧!
1.1 数据输入层DATA
上图没画出来,这个是放在最前做的,毕竟是数据输入层嘛!
一般数据输入层需要可以进行以下操作:
去均值(cnn只做这个,把train data各个维度中心化到0,注意test data的处理方式)
归一化,幅度归一化到一定范围,但是cnn不做这个(因为这里是图像,但如果不是图像的话,可以试试)。
PCA/白化,降维,然后归一化,但是cnn也不做这个。
1.2 卷积层CONV
名词:深度depth,步长stride,填充值zero-padding,窗口大小receptive field
卷积具体计算方式参考url:http://cs231n.github.io/assets/conv-demo/index.html
性质:参数共享机制,假设每个神经元连接数据窗的权重是固定的。
这一点就表明了参数个数大大的降低,想想假设在卷积层有30个filter,一般filter大小远远小于输入层的大小,比如输入层2525=625,filter大小55=25,就算有10个filter也才(25+1)*10个参数,而如果用全连接层,10个神经元就会有,(625+1)*10。
那么这里减少的参数个数我们可以用来干嘛,可以加快运算训练更快呀,而且我们还可以让这层的filter加多呀,而且filter实际上是有意义的。具体有啥意义呢?看看这篇博客总结的:http://blog.csdn.net/zouxy09/article/details/49080029
1.3 激励层RELU
这一层将卷积层输出结果进行非线性映射,将输入放到一个函数f()里面。
常用激励函数有:
Sigmoid(x过大或者过小,他的导数趋于0,梯度过小不容易传播)
Tanh
ReLu(收敛快,较脆弱,但是输出一旦是负数,梯度就是0了,饱和了,不会被激活了)
Leaky ReLU(不会饱和挂掉,还不错)
ELU(有指数,计算量大)
Maxout(计算线性,不会饱和,但是参数有点多)
一般做实验首先用RELU,如果出问题再试试Leaky ReLu或者Maxhout。
1.4 池化层POOL
这一层一般是放在卷积层之间的,用于减少参数的量,还可以减小过拟合。
常用的Pooling方法有:
max pooling(用的较多)
average pooling
1.5 全连接层FC
所有神经元都有权重连接,fc一般接在cnn的末尾。
一般CNN结构为INPUT->[[CONV->RELU]*N->POOL?]*M->[FC->RELU]*K->FC
2 典型CNN结构
caffe的model zoo有许多model,可以看看。
下面介绍几个经典的cnn结构。
- (LeNet)[http://yann.lecun.com/exdb/publis/pdf/lecun-98.pdf]用来识别手写数字的。
- AlexNet 2012年,小卷积层代替大卷积层。层数加多,每层神经元数量降低,计算更快。
- (ZF Net)[http://arxiv.org/abs/1311.2901] 2013年
- (GoogLeNet)[http://arxiv.org/pdf/1409.4842v1.pdf] 2014年
- VGGNet 2014年 object detection比GoogleNet好
3. CNN训练注意事项
去均值2种方式:RGB各算一个均值,还有一种就是RGB算做一个均值。
不要做标准化,PCA和白化。
关于权重初始化要注意:
- 我们希望网络是不对称的,从而能够各个神经元学到不同的东西。同时我们希望网络参数初始化正负个数一半一半。
- 权重初始化常用:W = 0.01*np.random.randn(D,H)【1-2层的隐层还行,深层就不行了】 W = np.random.randn(in,out)/np.sqrt(in)【希望输入方差和输出方差大小保持一致】 W = np.random.randn(in,out)/np.sqrt(in/2)【激励函数ReLU用这个】
- 这里有一些论文推荐: ①Understanding the difficulty of training deep feedforward neural networks ②Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification
Batch Normalization
希望激励过后的结果是高斯分布,就手动修正一下。通常在FC后(FC波动较大,因此往往放在FC后),激励层前做。这里也会引入两个参数gamma和beta,训练的时候得到。
\(\hat{x}^{\left ( k \right)}=\frac{x^{\left ( k \right)} - E\ [ x^{\left ( k \right)}\ ]}{Var\ [x^{\left ( k \right)}\ ]^{0.5}}\)
\(y_i = \gamma \hat{x_i} + \beta\)
优点是梯度传递顺畅,学习率设高也没事儿,较少初始值依赖。
Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift
深度学习中 Batch Normalization为什么效果好?需要监控每一个epoch的loss,看看loss是否减小。
Dropout
训练时随机关闭一部分神经元,防止过拟合。
预测的时候要把所有的X乘以打开的概率P,当然最好在训练的时候直接除以P,这样预测的时候就不用乘了。
Dropout: A Simple Way to Prevent Neural Networks from Overfitting
Dropout Training as Adaptive Regularization还有一些,具体内容参加:深度学习与计算机视觉系列(8)_神经网络训练与注意点
4. caffe使用
4.1 caffe简介
caffe有4个主要的类:
Blob:学习到的参数,网络传输过程中的产生的数据。
Layer:网络基本单元,派生了许多类。
Net:网络搭建,将layer的派生类组合成网络。
Solver:求解Net。
用proto来定义文件格式。
4.2 使用方法
- Resize图片,格式LMDB或者LevelDB
定义网络结构,以下各层,prototxt,具体见http://caffe.berkeleyvision.org/tutorial/layers.html
Data Layer
Convolutional Layer
Pooling Layer
Inner product(Fully Connected) Layer
ReLU Layer
SoftMax + Loss Layer定义solver,prototxt,具体见http://caffe.berkeleyvision.org/tutorial/solver.html
训练,可以fine-tuning。
一行命令就搞定。
4.3 fine-tuning和model zoo
常常自己训练一个全新的模型,是非常艰难的,这个时候我们需要拿别人的模型来进行fine-tuning。而且我们常常还会拿着比较大的数据集(比如IMAGENET)上跑出的模型来,针对自己的项目进行fine-tuning,这样会增强网络的泛化能力。
当模型结构修改后,比如中间某一层修改了,只认前面的结构参数,后面结构的参数不会认的。
需要注意的就是fine-tuning前面已经学好的层次,学习率低一点,后面的新层次学习率要设置高一点。
那别人已经训练好的模型在哪里呢,model zoo 上可以下载。