Caffe 使用总结 2:单一操作

1. Forward

forward propagation(fp):

  • matlab:

形式1:

res = net.forward({data});

data是原始数据;返回值res是fp到最后一层的输出,在matlab中它是一个cell变量,通过下面命令可以获取其中值

prob = res{1};

prob即为输出,其大小为 d*n, d为最后一层定义的dimension, n为batch size

形式2:

1
2
3
net.blobs('data').set_data(data);
net.forward_prefilled(); %notice the function used here
prob = net.blobs('prob').get_data();

这种形式是通过之前介绍的对blob的操作,直接把data放入,然后调用forward_prefiled()函数进行fp操作。对最后一层get_data()即为最后的输出

值得注意的是,无论形式1或者是形式2,其实整个net已经完成了fp,想取得某一层的featue map都可以通过之前介绍的blob操作完成。例如:

pool5_feat = net.blobs(‘pool5’).get_data();
可以得到pool5层的feature map

  • python:

net.forward()返回值是一个字典,key为每一层的名字,值为每一层的feature map。此外,还可以选择forward到某一层:

net.forward(end=’fc8’)[‘fc8’]

这句讲返回fp到fc8层的feature map

2. Backward

backward propagation (bp):

Caffe默认是禁止这样操作bp的,想通过这种方法,需要在deploy.prototxt 中加入’force_backward: true’。加过之后,以下方法生效:

实际上,与fp基本一样,只需要把需要拿到的值从data变成了diff而已

  • matlab:

形式1

1
2
res = net.backward({prob_diff});
data_diff = res{1};

prob_diff为最后一层的初始gradient(实际中,是通过与ground truth label的计算得出的)
data_diff为bp到第一层产生的gradient

形式2

1
2
3
net.blobs('prob').set_diff(prob_diff);
net.backward_prefilled();
data_diff = net.blobs('data').get_diff();
  • python

net.backward(start=’fc8’)[‘data’]

这句将返回从fc8开始bp,到原始数据的gradient

3. Reshape

deploy.prototxt中已经定义好了网络的结构,包括data层中对原始数据的要求。比如对于caffenet,其定义是:

input_param { shape: { dim: 10 dim: 3 dim: 227 dim: 227 } }

值得注意的是,在matlab中,这个顺序是反的,即为:[width, height, channels, num]
因此,如果我们想通过matlab 接口直接修改batch size,而不动deploy.prototxt文件,可以通过对data层进行reshape:

1
2
net.blobs('data').reshape([227 227 3 1]); % reshape blob 'data'
net.reshape();

这样,整个网络的大小也会发生改变,比如 net.blobs(‘prob’).shape的结果就会从[1000,10]变为[1000,1]了