预备知识:前向神经网络和BP训练算法。
cnn目前主要应用在图像领域,它的网络结构相对于普通的神经网络来说,有了卷积层以及参数共享机制使得参数数量大大减少。

1. CNN结构

先来个图吧!
20160620卷积神经网络

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结构。

  1. (LeNet)[http://yann.lecun.com/exdb/publis/pdf/lecun-98.pdf]用来识别手写数字的。
  2. AlexNet 2012年,小卷积层代替大卷积层。层数加多,每层神经元数量降低,计算更快。
  3. (ZF Net)[http://arxiv.org/abs/1311.2901] 2013年
  4. (GoogLeNet)[http://arxiv.org/pdf/1409.4842v1.pdf] 2014年
  5. VGGNet 2014年 object detection比GoogleNet好

3. CNN训练注意事项

  1. 去均值2种方式:RGB各算一个均值,还有一种就是RGB算做一个均值。

  2. 不要做标准化,PCA和白化。

  3. 关于权重初始化要注意:

    1. 我们希望网络是不对称的,从而能够各个神经元学到不同的东西。同时我们希望网络参数初始化正负个数一半一半。
    2. 权重初始化常用: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用这个】
    3. 这里有一些论文推荐:
      Understanding the difficulty of training deep feedforward neural networks
      Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification
  4. 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为什么效果好?

  5. 需要监控每一个epoch的loss,看看loss是否减小。

  6. Dropout
    训练时随机关闭一部分神经元,防止过拟合。
    预测的时候要把所有的X乘以打开的概率P,当然最好在训练的时候直接除以P,这样预测的时候就不用乘了。
    Dropout: A Simple Way to Prevent Neural Networks from Overfitting
    Dropout Training as Adaptive Regularization

  7. 还有一些,具体内容参加:深度学习与计算机视觉系列(8)_神经网络训练与注意点

4. caffe使用

4.1 caffe简介

caffe有4个主要的类:
Blob:学习到的参数,网络传输过程中的产生的数据。
Layer:网络基本单元,派生了许多类。
Net:网络搭建,将layer的派生类组合成网络。
Solver:求解Net。
用proto来定义文件格式。

4.2 使用方法

  1. Resize图片,格式LMDB或者LevelDB
  2. 定义网络结构,以下各层,prototxt,具体见http://caffe.berkeleyvision.org/tutorial/layers.html

    Data Layer
    Convolutional Layer
    Pooling Layer
    Inner product(Fully Connected) Layer
    ReLU Layer
    SoftMax + Loss Layer

  3. 定义solver,prototxt,具体见http://caffe.berkeleyvision.org/tutorial/solver.html

  4. 训练,可以fine-tuning。
    一行命令就搞定。

4.3 fine-tuning和model zoo

常常自己训练一个全新的模型,是非常艰难的,这个时候我们需要拿别人的模型来进行fine-tuning。而且我们常常还会拿着比较大的数据集(比如IMAGENET)上跑出的模型来,针对自己的项目进行fine-tuning,这样会增强网络的泛化能力。
当模型结构修改后,比如中间某一层修改了,只认前面的结构参数,后面结构的参数不会认的。
需要注意的就是fine-tuning前面已经学好的层次,学习率低一点,后面的新层次学习率要设置高一点。
那别人已经训练好的模型在哪里呢,model zoo 上可以下载。