本例中将一个完全卷积分类器变成密集特征提取,将网络中的inner product classifier layers换成convolutional layers,这样会输出会生成一个分类图(classification map)而不是一个单一的分类结果
一、prototxt文件的差别
1c1
<name: "CaffeNetConv"
---
>name: "CaffeNet"
3c3
<input_dim: 1
---
>input_dim: 10
5,6c5,6
<input_dim: 454
<input_dim: 454
---
>input_dim: 227
>input_dim: 227
151,152c151,152
< name: "fc6-conv"
< type: CONVOLUTION
---
> name: "fc6"
> type: INNER_PRODUCT
154,155c154,155
< top: "fc6-conv"
< convolution_param {
---
> top: "fc6"
> inner_product_param {
157d156
< kernel_size: 6
163,164c162,163
< bottom: "fc6-conv"
< top: "fc6-conv"
---
> bottom: "fc6"
> top: "fc6"
169,170c168,169
< bottom: "fc6-conv"
< top: "fc6-conv"
---
> bottom: "fc6"
> top: "fc6"
176,180c175,179
< name: "fc7-conv"
< type: CONVOLUTION
< bottom: "fc6-conv"
< top: "fc7-conv"
< convolution_param {
---
> name: "fc7"
> type: INNER_PRODUCT
> bottom: "fc6"
> top: "fc7"
> inner_product_param {
182d180
< kernel_size: 1
188,189c186,187
< bottom: "fc7-conv"
< top: "fc7-conv"
---
> bottom: "fc7"
> top: "fc7"
194,195c192,193
< bottom: "fc7-conv"
< top: "fc7-conv"
---
> bottom: "fc7"
> top: "fc7"
201,205c199,203
< name: "fc8-conv"
< type: CONVOLUTION
< bottom: "fc7-conv"
< top: "fc8-conv"
< convolution_param {
---
> name: "fc8"
> type: INNER_PRODUCT
> bottom: "fc7"
> top: "fc8"
> inner_product_param {
207d204
< kernel_size: 1
213c210
< bottom: "fc8-conv"
---
> bottom: "fc8"
二、源程序
输出分别是
fc6 weights are (1, 1, 4096, 9216) dimensional and biases are (1, 1, 1, 4096) dimensional
fc7 weights are (1, 1, 4096, 4096) dimensional and biases are (1, 1, 1, 4096) dimensional
fc8 weights are (1, 1, 1000, 4096) dimensional and biases are (1, 1, 1, 1000) dimensional
fc6-conv weights are (4096, 256, 6, 6)dimensional and biases are (1, 1, 1, 4096) dimensional
fc7-conv weights are (4096, 4096, 1, 1) dimensional andbiases are (1, 1, 1, 4096) dimensional
fc8-conv weights are (1000, 4096, 1, 1) dimensional andbiases are (1, 1, 1, 1000) dimensional
可以看出:
对于ip层,权重第三、四维表示输出和输入的size,二偏置的第四维表示的是输出的size
对卷积层,权重是表示为输出*输入*高*宽
要把ip层换成卷积层,就需要把ip层的矢量转换成通道*高*宽的滤波矩阵
(zip函数接受任意多个(包括0个和1个)序列作为参数,返回一个tuple列表。x=[1, 2,3, 4, 5 ] y=[6, 7, 8, 9, 10] ,zip(x, y)就得到了[(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)])
这一步改变偏置,不需要reshape
Shape和reshape函数都是numpy库中的,shape返回列表的每一维的长度,reshape可以该表列表的维度
这一步则改变权重,将ip层的权重reshape成输出*输入*高*宽,然后赋给卷积层
保存参数的变化。
进行测试(classification),输入的是一张猫的图片
其中:
_Net_forward_all(self,blobs=None, **kwargs):
Run net forward in batches.
_Net_set_mean(self,input_, mean_f, mode='elementwise'):
Set the mean to subtract for datacentering.
_Net_set_input_scale(self,input_, scale):
Set the input feature scaling factors.t. input blob = input * scale.
(以上三个函数的功能暂时不是很理解)
_Net_set_channel_swap(self,input_, order):
转换通道顺序来对应ImageNet模型(2,1,0) 表示RGB to BGR
输出:
array([[278, 151, 259, 281, 282, 259, 282,282],
[283, 259, 283, 282, 283, 281, 259, 277],
[283, 283, 283, 287, 287, 287, 287, 282],
[283, 283, 283, 281, 281, 259, 259, 333],
[283, 283, 283, 283, 283, 283, 283, 283],
[283, 283, 283, 283, 283, 259, 283, 333],
[283, 356, 359, 371, 368, 368, 259, 852],
[356, 335, 358, 151, 283, 263, 277, 744]])
其中每个数字代表一种分类,281-波斯猫,282-斑纹猫(tabby),283-虎,等等
(以上程序来源:caffe官网 :Editing model parameters)