实现一个卷积神经网络

来源:互联网 发布:淘宝衣服厂家直销 编辑:程序博客网 时间:2024/06/05 15:06

转自:http://blog.csdn.net/l691899397/article/details/52233454

一、卷积神经网络(CNN)

卷积神经网络(ConvolutionalNeural Network,CNN)是人工神经网络的一种。当前已经成为图像和语音识别领域有十分广泛的应用,特别是在识别位移、缩放及其他形式扭曲不变性的二维图形方面有十分优异的表现,已经成为一个十分重要的研究方向。

关于CNN的详细解释可以看这里:http://blog.csdn.net/zouxy09/article/details/8781543

和这篇论文:http://yann.lecun.com/exdb/publis/pdf/lecun-98.pdf

接下来我将实现一个卷积神经网络,用来识别mnist数据集中的手写数字,我会给出每一层的前向和后向推导,以及caffe中的实现和我自己的实现方法,如有什么错误,欢迎指出。

二、网络结构

我要设计的网络结构如下图所示:包含2个卷积层,2个max池化层,2个全链接层和1个relu层与一个softmax层。


下面我来推导一下每层的神经元数目和参数的个数。

1、输入层:输入层输入一个28*28的图片。

2、卷积层1:该层使用20个5*5的卷积核分别对输入层图片进行卷积,所以包含20*5*5=500个参数权值参数。卷积后图片边长为(28-5+1)/1 = 24,故产生20个24*24个map,包含20*24*24 = 11520个神经元。

3、池化(pooling)层1:对上一层每个2*2区域进行降采样,选取每个区域最大值,这一层没有参数。降采样过后每个map的长和宽变为原来的一半。

4、卷积层2:该层使用20*50个5*5的卷积核分别对上一层的每一个map进行卷积,所以包含20*50*5*5=25000个参数权值参数。卷积后图片边长为(12-5+1)/1 = 8,故产生50个8*8个map,包含50*8*8 = 3200个神经元。

5、池化层2:和上一个池化层功能类似,将8*8的map降采样为4*4的map。该层无参数。

6、全连接层1:将上一层的所有神经元进行连接,该层含有500个神经元,故一共有50*4*4*500 = 400000个权值参数。

7、relu层:激活函数层,实现x=max[0,x],该层神经元数目和上一层相同,无权值参数。

8、全连接层2:功能和上一个全连接层类似,该层共有10个神经元,包含500*10=5000个参数。

9、softmax层:实现分类和归一化,后面会详细介绍。

 

我个人觉得关于这个卷积神经网络比较难以理解的地方:

1、关于第一篇中神经元,如下图,它一层完成了我们上面2层(全连接层+一个激活函数层)的功能,所以,实际中的网络可能和前边理论中不是一一对应的。

2、卷积层的权值共享是指每一个map局部和整体权值共享,具体表现出来就是每一个map与卷积核进行卷积,卷积核在map上移动map的不同局部区域之间使用的同一个卷积核进行计算。而不是多个map使用相同的卷积核。

三、caffe中对该网络的实现

Caffe,全称Convolutional Architecture for Fast Feature Embedding,是一个计算CNN相关算法的框架,使用caffe,我们可以轻松实现自己的卷积神经网络。

在caffe中实现上一节中的网络,其配置文件如下:

[cpp] view plain copy
print?
  1. name: "LeNet"  
  2. layer {  
  3.   name: "data"  
  4.   type: "Input"  
  5.   top: "data"  
  6.   input_param { shape: { dim: 64 dim: 1 dim: 28 dim: 28 } }  
  7. }  
  8. layer {  
  9.   name: "conv1"  
  10.   type: "Convolution"  
  11.   bottom: "data"  
  12.   top: "conv1"  
  13.   param {  
  14.     lr_mult: 1  
  15.   }  
  16.   param {  
  17.     lr_mult: 2  
  18.   }  
  19.   convolution_param {  
  20.     num_output: 20  
  21.     kernel_size: 5  
  22.     stride: 1  
  23.     weight_filler {  
  24.       type: "xavier"  
  25.     }  
  26.     bias_filler {  
  27.       type: "constant"  
  28.     }  
  29.   }  
  30. }  
  31. layer {  
  32.   name: "pool1"  
  33.   type: "Pooling"  
  34.   bottom: "conv1"  
  35.   top: "pool1"  
  36.   pooling_param {  
  37.     pool: MAX  
  38.     kernel_size: 2  
  39.     stride: 2  
  40.   }  
  41. }  
  42. layer {  
  43.   name: "conv2"  
  44.   type: "Convolution"  
  45.   bottom: "pool1"  
  46.   top: "conv2"  
  47.   param {  
  48.     lr_mult: 1  
  49.   }  
  50.   param {  
  51.     lr_mult: 2  
  52.   }  
  53.   convolution_param {  
  54.     num_output: 50  
  55.     kernel_size: 5  
  56.     stride: 1  
  57.     weight_filler {  
  58.       type: "xavier"  
  59.     }  
  60.     bias_filler {  
  61.       type: "constant"  
  62.     }  
  63.   }  
  64. }  
  65. layer {  
  66.   name: "pool2"  
  67.   type: "Pooling"  
  68.   bottom: "conv2"  
  69.   top: "pool2"  
  70.   pooling_param {  
  71.     pool: MAX  
  72.     kernel_size: 2  
  73.     stride: 2  
  74.   }  
  75. }  
  76. layer {  
  77.   name: "ip1"  
  78.   type: "InnerProduct"  
  79.   bottom: "pool2"  
  80.   top: "ip1"  
  81.   param {  
  82.     lr_mult: 1  
  83.   }  
  84.   param {  
  85.     lr_mult: 2  
  86.   }  
  87.   inner_product_param {  
  88.     num_output: 500  
  89.     weight_filler {  
  90.       type: "xavier"  
  91.     }  
  92.     bias_filler {  
  93.       type: "constant"  
  94.     }  
  95.   }  
  96. }  
  97. layer {  
  98.   name: "relu1"  
  99.   type: "ReLU"  
  100.   bottom: "ip1"  
  101.   top: "ip1"  
  102. }  
  103. layer {  
  104.   name: "ip2"  
  105.   type: "InnerProduct"  
  106.   bottom: "ip1"  
  107.   top: "ip2"  
  108.   param {  
  109.     lr_mult: 1  
  110.   }  
  111.   param {  
  112.     lr_mult: 2  
  113.   }  
  114.   inner_product_param {  
  115.     num_output: 10  
  116.     weight_filler {  
  117.       type: "xavier"  
  118.     }  
  119.     bias_filler {  
  120.       type: "constant"  
  121.     }  
  122.   }  
  123. }  
  124. layer {  
  125.   name: "prob"  
  126.   type: "Softmax"  
  127.   bottom: "ip2"  
  128.   top: "prob"  
  129. }  

通过前边的介绍,大致也能看懂其他一些参数的含义,在后面每一层的介绍中我会详细解释配置文件中每一个参数的含义。




原创粉丝点击