caffe中可以用NetSpec这个Python接口搭建网络结构,然后运行Python代码生成所需要的prototxt文件。
可参考FCN的github工程https://github.com/shelhamer/fcn.berkeleyvision.org/blob/master/pascalcontext-fcn32s/net.py
其中conv、ReLu、softmaLoss等层在这个例子中已经有体现了。这些层有一个共同的特点,就是top_blob只有一个。所以首先要解决有多个top_blob时层的构建。
这里以Slice层为例,Slice不仅有多个top_blob,参数里还有可能同时出现多个slice_point,比较典型。
import caffe
from caffe import layers as L, params as P
n = caffe.NetSpec()
...
n.s1, n.s2, n.s3 = L.Slice(n.bottom, ntop=3, name='slice', slice_param=dict(slice_dim=1, slice_point=[1, 2]))
...
# 将网络结构写入test.prototxt文件
with open('test.prototxt', 'w') as f:
f.write(str(n.to_proto()))
注意:
1. 返回的top_blob的个数由ntop这个参数决定
1. slice_point这个参数用list赋值就会在prototxt文件中产生同名参数
最终产生的层的形式为:
layer {
name: "slice"
type: "Slice"
bottom: "bottom"
top: "s1"
top: "s2"
top: "s3"
slice_param {
slice_point: 1
slice_point: 2
axis: 1
}
}
在caffe中,有时候需要计算某些层的输出的偏移的shift值。这个值在Crop层中尤其重要,因为很多时候我们希望crop的参考点为中心点,而caffe中的Crop层的默认shift值是0。
import caffe
from caffe import layers as L, params as P
from caffe.coord_map import crop
n = caffe.NetSpec()
...
n.crop = crop(n.bottom, n.refblob)
...
但当网络中有Concat层或者Slice层的时候,会报错
Could not compute map between tops; are they connected by spatial layers?
分析
这是因为在Slice和Concat可以选择沿着某个轴操作,当不是沿着channel轴的时候,没法和其它数据的width和height进行比较。为了严谨,使用coord_map中的crop计算shift的时候就不能在网络中存在这种可以按不同轴操作的层。
解决方法:
1. 当能够确定自己的网络结构中的Slice和Concat层都是沿着channel轴的时候,可以通过改$CAFFR_ROOT/pythpn/caffe/coord_map.py
中的PASS_THROUGH_LAYERS
这个list,添加这两个层名。
PASS_THROUGH_LAYERS = ['AbsVal', 'BatchNorm', 'Bias', 'BNLL', 'Dropout',
'Eltwise', 'ELU', 'Log', 'LRN', 'Exp', 'MVN', 'Power',
'ReLU', 'PReLU', 'Scale', 'Sigmoid', 'Split', 'TanH',
'Threshold', 'Slice', 'Concat']
删除$CAFFR_ROOT/pythpn/caffe/_caffe.so
,重新编译make pycaffe -j16
。
pad
。