[caffe笔记010]:使用NetSpec构建网络结构的一些问题

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时层的构建。

1. 有多个top_blob的Slice层

这里以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
  }
 } 

2. coord_map的使用

在caffe中,有时候需要计算某些层的输出的偏移的shift值。这个值在Crop层中尤其重要,因为很多时候我们希望crop的参考点为中心点,而caffe中的Crop层的默认shift值是0。

2.1 构建crop层自动计算偏移

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)
...

2.2 Could not compute map between tops; are they connected by spatial layers?错误

但当网络中有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

  1. 当修改之后还是报同样的错误,有可能是需要crop的blob的大小比参考blob小。可以考虑在卷积的时候加上比较大的pad

你可能感兴趣的:(caffe点滴)