本文主要讨论的是在caffe中添加python layer的一般流程,自己设计的test_python_layer.py层只是起到演示作用,没有实际的功能。
1) Python layer 在caffe目录结构中放哪?
下图是caffe的目录结构,在本文中我是将python layer防止examples/pycaffe/layers/下
2)Python layer内容
我给这一个python layer取名为test_python_layer.py,其内容为
importcaffeimportnumpy as npclassTestPythonLayer(caffe.Layer):"""Compute the Euclidean Loss in the same manner as the C++ EuclideanLossLayer
to demonstrate the class interface for developing layers in Python."""
defsetup(self, bottom, top):#check input pair
if len(bottom) != 1:raise Exception("Need two inputs to compute distance.")defreshape(self, bottom, top):#loss output is scalar
top[0].reshape(1)defforward(self, bottom, top):
top[0].data[...]= np.sum(bottom[0].data**2) / bottom[0].num / 2.;print('Test passed!')defbackward(self, top, propagate_down, bottom):pass
大家一定要注意,我这样设计这个层(包括代码、代码所放位置)是有一个前提的,那就是我导出了相应的环境变量,如下图所示(红色部分遮住的是具体的路径,大家可以根据自己的实际情况进行调整)。如果没有设置环境变量,可能会出现模块找不到问题。
3)如何测试这个python layer的可行性
设计一个网络结构prototxt文件
name: "CIFAR10_quick"layer {
name:"cifar"type:"Data"top:"data"top:"label"include {
phase: TRAIN
}
transform_param {
mean_file:"examples/cifar10/mean.binaryproto"}
data_param {
source:"examples/cifar10/cifar10_train_lmdb"batch_size:100backend: LMDB
}
}
layer {
name:"cifar"type:"Data"top:"data"top:"label"include {
phase: TEST
}
transform_param {
mean_file:"examples/cifar10/mean.binaryproto"}
data_param {
source:"examples/cifar10/cifar10_test_lmdb"batch_size:100backend: LMDB
}
}
layer {
name:"test"type:"Python"bottom:"data"top:"loss"python_param {
module:"test_python_layer"layer:"TestPythonLayer"}
}
及其对应solver文件
net: "examples/cifar10/test_python_layer.prototxt"base_lr:0.001lr_policy:"fixed"max_iter:10solver_mode: CPU
通过下面命令即可测试其效果
其输出为
我是在cifar10样例的基础上设计上述python layer的,这点请大家注意。可以看出,“test passed!”一共出现了10次,这符合我们的预期。
4)下面是问题的重点,在测试的时候我们可能会遇到如下问题
我自己在这个问题上摸索了一个上午(查了很多资料,始终没有解决这个问题),最后索性按照自己的理解来处理了。我的思路大致如下:在没有添加python layer的时候,我的caffe版本能够正常运行;protobuf版本不匹配问题,应该不是caffe C++部分引起的;这样问题就定位到python protobuf的版本问题,我发现自己python的protobuf版本为3.2.0,这样问题就可以轻而易举的按照如下方式解决了
先卸载已有的protobuf
然后按照2.5.0版本的protobuf(这个版本好应该根据自己的错误提示确定)
至此,问题得到解决!
5)关于python层,我谈谈自己的一些看法
可以用python layer实现on-the-fly的数据增强!
GPU模式下,用python layer的时候应该牢记“数据是不是来回在GPU、CPU直接copy”!这样有助于你定位在什么地方应该用python layer!