今天来仔细讲一下卷基层和全连接层训练参数个数如何确定的问题。我们以Mnist为例,首先贴出网络配置文件:

  1. name: "LeNet"
  2. layer {
  3. name: "mnist"
  4. type: "Data"
  5. top: "data"
  6. top: "label"
  7. data_param {
  8. source: "examples/mnist/mnist-train-leveldb"
  9. backend: LEVELDB
  10. batch_size: 64
  11. }
  12. transform_param {
  13. scale: 0.00390625
  14. }
  15. include: { phase: TRAIN }
  16. }
  17. layer {
  18. name: "mnist"
  19. type: "Data"
  20. top: "data"
  21. top: "label"
  22. data_param {
  23. source: "examples/mnist/mnist-test-leveldb"
  24. backend: LEVELDB
  25. batch_size: 100
  26. }
  27. transform_param {
  28. scale: 0.00390625
  29. }
  30. include: { phase: TEST }
  31. }
  32. layer {
  33. name: "conv1"
  34. type: "Convolution"
  35. bottom: "data"
  36. top: "conv1"
  37. param {
  38. lr_mult: 1
  39. }
  40. param {
  41. lr_mult: 2
  42. }
  43. convolution_param {
  44. num_output: 20
  45. kernel_size: 5
  46. stride: 1
  47. weight_filler {
  48. type: "xavier"
  49. }
  50. bias_filler {
  51. type: "constant"
  52. }
  53. }
  54. }
  55. layer {
  56. bottom: "conv1"
  57. top: "conv1"
  58. name: "bn_conv1"
  59. type: "BatchNorm"
  60. param {
  61. lr_mult: 0
  62. decay_mult: 0
  63. }
  64. param {
  65. lr_mult: 0
  66. decay_mult: 0
  67. }
  68. param {
  69. lr_mult: 0
  70. decay_mult: 0
  71. }
  72. }
  73. layer {
  74. bottom: "conv1"
  75. top: "conv1"
  76. name: "scale_conv1"
  77. type: "Scale"
  78. scale_param {
  79. bias_term: true
  80. }
  81. }
  82. layer {
  83. name: "pool1"
  84. type: "Pooling"
  85. bottom: "conv1"
  86. top: "pool1"
  87. pooling_param {
  88. pool: MAX
  89. kernel_size: 2
  90. stride: 2
  91. }
  92. }
  93. layer {
  94. name: "relu_pool1"
  95. type: "ReLU"
  96. bottom: "pool1"
  97. top: "pool1"
  98. }
  99. layer {
  100. name: "conv2"
  101. type: "Convolution"
  102. bottom: "pool1"
  103. top: "conv2"
  104. param {
  105. lr_mult: 1
  106. }
  107. param {
  108. lr_mult: 2
  109. }
  110. convolution_param {
  111. num_output: 50
  112. kernel_size: 5
  113. stride: 1
  114. weight_filler {
  115. type: "xavier"
  116. }
  117. bias_filler {
  118. type: "constant"
  119. }
  120. }
  121. }
  122. layer {
  123. bottom: "conv2"
  124. top: "conv2"
  125. name: "bn_conv2"
  126. type: "BatchNorm"
  127. param {
  128. lr_mult: 0
  129. decay_mult: 0
  130. }
  131. param {
  132. lr_mult: 0
  133. decay_mult: 0
  134. }
  135. param {
  136. lr_mult: 0
  137. decay_mult: 0
  138. }
  139. }
  140. layer {
  141. bottom: "conv2"
  142. top: "conv2"
  143. name: "scale_conv2"
  144. type: "Scale"
  145. scale_param {
  146. bias_term: true
  147. }
  148. }
  149. layer {
  150. name: "pool2"
  151. type: "Pooling"
  152. bottom: "conv2"
  153. top: "pool2"
  154. pooling_param {
  155. pool: MAX
  156. kernel_size: 2
  157. stride: 2
  158. }
  159. }
  160. layer {
  161. name: "relu_pool2"
  162. type: "ReLU"
  163. bottom: "pool2"
  164. top: "pool2"
  165. }
  166. layer {
  167. name: "ip1"
  168. type: "InnerProduct"
  169. bottom: "pool2"
  170. top: "ip1"
  171. param {
  172. lr_mult: 1
  173. }
  174. param {
  175. lr_mult: 2
  176. }
  177. inner_product_param {
  178. num_output: 500
  179. weight_filler {
  180. type: "xavier"
  181. }
  182. bias_filler {
  183. type: "constant"
  184. }
  185. }
  186. }
  187. layer {
  188. name: "relu1"
  189. type: "ReLU"
  190. bottom: "ip1"
  191. top: "ip1"
  192. }
  193. layer {
  194. name: "ip2"
  195. type: "InnerProduct"
  196. bottom: "ip1"
  197. top: "ip2"
  198. param {
  199. lr_mult: 1
  200. }
  201. param {
  202. lr_mult: 2
  203. }
  204. inner_product_param {
  205. num_output: 10
  206. weight_filler {
  207. type: "xavier"
  208. }
  209. bias_filler {
  210. type: "constant"
  211. }
  212. }
  213. }
  214. layer {
  215. name: "accuracy"
  216. type: "Accuracy"
  217. bottom: "ip2"
  218. bottom: "label"
  219. top: "accuracy"
  220. include {
  221. phase: TEST
  222. }
  223. }
  224. layer {
  225. name: "loss"
  226. type: "SoftmaxWithLoss"
  227. bottom: "ip2"
  228. bottom: "label"
  229. top: "loss"
  230. }

OK,在开始讲解之前我们先说明几个问题:

1、输入的图片大小是28*28,;

2、我们将分三部分讲解,因为三部分计算方式不同;

3、由于偏置量b的个数与卷积核的个数相同,因此我们讲解的主要是权重,偏置量个数加上就可以了。

1、第一个卷积conv1,之所把第一个卷积单独拿出来,是因为他和后面的卷积计算方式不同,他训练参数个数计算并不关心输入,这里的数据就是指data层中batch_size大小。也可以说第一个卷基层并不关心特征组合,只是提取特征。

在每一个卷积层中都以一个参数num_output,这个参数怎么理解呢?两种理解方式1、卷积的种类个数;2、输出特征图的个数,我么可以认为一种卷积核提取一种特征,然后输出一张特征。

由于第一个卷积层只是简单的提取特征,并没有进行特征组合,因此训练参数个数计算只是num_output*kernel_size^2.这里怎么理解呢?(由于我不会画图,需要大家一点想象力)假设我们的输入有5张图,num_output=3,kernel_size=5。没有进行特征组合,只是简单提取特征,指的是一种卷积核对5张图的同一区域使用相同的权重进行卷积计算,这样每幅图使用相同的卷积核就能提取到相同的特征,然后相同的特征组成一张特征图。

2、第二个卷积至全连接层之间的卷积,这些卷积层的训练参数个数和输入特征图的数量有关,因为这些卷积层需要进行特征组合。举个例子:conv1的num_output=20,说明卷积1层输出了20个特征图,那么卷积2层的输入就是20。conv2的num_output=50,kernel_size=5,那么计算公式是20*50*5*5.

为什么这些卷积层的训练个数和输入的特征图的数量有关呢?重点还是在特征组合。输入的20个特征图,每个特征图代表一种特征,如果我们给每种特征不同的权重那是不是就进行了特征组合呢?conv2的卷积核是5*5,对20个特征图进行卷积,那就会有20组(5*5)个连接(每张特征图是一组),如果这20组卷积核的权重相同,那就回到了第一个卷积层的情况,没有对20个特征进行组合,因为权重相同嘛!只能看成简单的相加,如果20组权重不同,是不是就进行了线性相加了呢?所以对于一个卷积核(5*5)我们要学习的参数不是25个,而是25*20个。说到这里我相信你应该已经明白了吧!

3、全连接层,全连接层就是普通的神经网络,全连接层的num_output和卷积层中num_output的理解不同,全连接层的num_output应该看成神经元的个数。

3.1、这里要细分一下,先说IP1也就是第一个全连接层。先讲一下ip1的输入,比如最后一个卷积层的num_output=50,那么IP1的输入是50吗?注意这里不是,要理解这个问题,我们只需将全连接层看成是一些列的普通神经网络就可以。比如IP1的num_output=500,也就是有500个神经元,每个神经元都和输入的每一个像素相连,最后一个卷积层输出了50个特征图,每个特征图大小是4*4(输入图像是28*28)那么每个神经元连接的个数就是50*16=800个,也就有800个参数需要学习。总共有500个神经元,因此对于IP1层共需要学习800*500=400,000个参数。

3.2、对于iP2层,iP2的输入就是IP1的输出了,因为IP1输出的不是图像了(或矩阵)而是500个数字。比如ip2的num_output=10,也就是输出数据500维,输出10维的普通神经网络,那么需要学习的参数就是500*10=5000个。

以上,只是我的个人见解,如果有错误,欢迎大家指正!

文章出处: http://blog.csdn.net/sunshine_in_moon/article/details/51434908

卷积中要注意的其他点:

1)尽量使用多层fliter尺寸小的卷积层代替一层filter较大的卷积层。

因为使用多层filter较小的卷积层所能观察到的区域大小和一层filter较大的卷积层是相同的,但是前者可以看到更加抽象的特征,提取的特征表达性能更佳。

此外,前者引入的参数规模相比后者更小。比如,使用3层filter为3X3的卷积层代替1层filter为7X7的卷积层,假设输入的volume为C个通道则前者参数

个数为3×(C×(3×3×C))=27C^2,而后者为C×(7×7×C)=49C^2,明显前者引入的参数更少。

2)为什么使用padding?

使用padding的好处是使得卷积前后的图像尺寸保持相同,可以保持边界的信息。一般padding的大小为P=(F-1)/2,其中F为filter的尺寸。如果不使用

paddding,则要仔细跟踪图像尺寸的变化,确保每一层filter和stride正确的被使用。

3)为什么stride一般设为1?

stride设为1实际表现效果更好,将下采样的工作全部交给池化层。

(4)输入层(input layer)尺寸一般应该能被2整除很多次,比如32(CIFAR-10),64,96(STL-10),224(common ImageNet ConvNets),384和512。

(5)尽量使用filter较小(3x3 or 至多 5x5)的卷积层,如果要使用较大的filter(比如7x7),一般也只在第一个卷积层。

(6)有时候由于参数太多,内存限制,会在第一个卷积层使用较大filter(7x7)和stride(2)(参考 ZF Net),或者filter(11x11),stride(4)

(参考 AlexNet)。

 
 

caffe中全卷积层和全连接层训练参数如何确定的更多相关文章

  1. caffe中LetNet-5卷积神经网络模型文件lenet.prototxt理解

    caffe在 .\examples\mnist文件夹下有一个 lenet.prototxt文件,这个文件定义了一个广义的LetNet-5模型,对这个模型文件逐段分解一下. name: "Le ...

  2. caffe学习--使用caffe中的imagenet对自己的图片进行分类训练(超级详细版) -----linux

    http://blog.csdn.net/u011244794/article/details/51565786 标签: caffeimagenet 2016-06-02 12:57 9385人阅读  ...

  3. caffe中的卷积

    https://www.zhihu.com/question/28385679 如上,将三维的操作转换到二维上面去做,然后调用GEMM库进行矩阵间的运算得到最后结果. 两个矩阵相乘,需要中间的那个维度 ...

  4. caffe 中base_lr、weight_decay、lr_mult、decay_mult代表什么意思?

    在机器学习或者模式识别中,会出现overfitting,而当网络逐渐overfitting时网络权值逐渐变大,因此,为了避免出现overfitting,会给误差函数添加一个惩罚项,常用的惩罚项是所有权 ...

  5. caffe中ConvolutionLayer的前向和反向传播解析及源码阅读

    一.前向传播 在caffe中,卷积层做卷积的过程被转化成了由卷积核的参数组成的权重矩阵weights(简记为W)和feature map中的元素组成的输入矩阵(简记为Cin)的矩阵乘积W * Cin. ...

  6. LeNet - Python中的卷积神经网络

    本教程将  主要面向代码,  旨在帮助您 深入学习和卷积神经网络.由于这个意图,我  不会花很多时间讨论激活功能,池层或密集/完全连接的层 - 将来会有  很多教程在PyImageSearch博客上将 ...

  7. caffe之(四)全连接层

    在caffe中,网络的结构由prototxt文件中给出,由一些列的Layer(层)组成,常用的层如:数据加载层.卷积操作层.pooling层.非线性变换层.内积运算层.归一化层.损失计算层等:本篇主要 ...

  8. resnet18全连接层改成卷积层

    想要尝试一下将resnet18最后一层的全连接层改成卷积层看会不会对网络效果和网络大小有什么影响 1.首先先对train.py中的更改是: train.py代码可见:pytorch实现性别检测 # m ...

  9. Caffe源码阅读(1) 全连接层

    Caffe源码阅读(1) 全连接层 发表于 2014-09-15   |   今天看全连接层的实现.主要看的是https://github.com/BVLC/caffe/blob/master/src ...

随机推荐

  1. English trip V1 - B 24. I'm Interested in... 我对...感兴趣 Teacher:Julia Key: (I/We/They) do/don't (He/She/it)does/doesn't

    In this lesson you will learn to talk about people's interests. 课上内容(Lesson) interest v. 使…感兴趣(inter ...

  2. Linux上配置bond

    http://blog.csdn.net/wuweilong/article/details/39720571 一,配置设定文件[root@woo ~]# vi /etc/sysconfig/netw ...

  3. 时钟中断TIMER_BH(bottom_half)实现分析

    017-12-6 16:27:35时钟中断TIMER_BH(bottom_half)实现分析1.3.1001. 时钟0号中断安装    setup_x86_irq(0, &irq0);@arc ...

  4. android------基础面试题

    1. Android的四大组件是哪些,它们的作用? 答:Activity:Activity是Android程序与用户交互的窗口,是Android构造块中最基本的一种,它需要为保持各界面的状态,做很多持 ...

  5. PHP工厂模式计算面积与周长

    <?phpinterface InterfaceShape{ function getArea(); function getCircumference();} /** * 矩形 */class ...

  6. vue.js面试题整理

    Vue.js面试题整理 一.什么是MVVM? MVVM是Model-View-ViewModel的缩写.MVVM是一种设计思想.Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务 ...

  7. CF1129C Morse Code

    pro: 维护一个01字符串,支持在结尾动态加字符. 每一个长度<=4的01串可以对应一个字母(有几个特例除外) 每次操作后询问,这个字符串的所有子串一共可以对应出多少种本质不同的字符串. so ...

  8. wordpress +window 走起~

    一.安装XAMPP   1 百度搜索xampp后下载安装到D盘(安装时按默认勾选安装即可) 2 安装完后,点击Start来启动Apache和MySQL这两个服务 3 如果Apache服务不能启动,多数 ...

  9. layui 表格图片放大

    1. 表格塞图片 ,{title: '图片', width:120, templet: function(d) { return '<div onclick="show_img(thi ...

  10. node模块之net模块——socket

    当我们去面试的时候,常常会遇到这样一个问题:当用户在浏览器地址栏输入一段url发出资源请求后,到服务端返回数据呈现给用户的这个过程都发生了什么? 我们把进行通信的这两个端(这里指的是,浏览器和资源获取 ...