本文主要討論的是在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,其內容為
import caffe import numpy as np class TestPythonLayer(caffe.Layer): """ Compute the Euclidean Loss in the same manner as the C++ EuclideanLossLayer to demonstrate the class interface for developing layers in Python. """ def setup(self, bottom, top): # check input pair if len(bottom) != 1: raise Exception("Need two inputs to compute distance.") def reshape(self, bottom, top): # loss output is scalar top[0].reshape(1) def forward(self, bottom, top): top[0].data[...] = np.sum(bottom[0].data**2) / bottom[0].num / 2.;print('Test passed!') def backward(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: 100 backend: 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: 100 backend: 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.001 lr_policy: "fixed" max_iter: 10 solver_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!