caffe python layer
Layer实际上定义了Layer的基本操作,即初始化层、前向传播和反向传播。在前向传播中根据bottom blob得到top blob,反向传播则根据top反传到bottom。而且在前传的时候还可以计算loss,一般来说只有最后一层才会计算loss,虽然每个层都有计算loss的功能。Layer类在没有实现GPU前传和反传的时候会自动使用CPU的实现。下面给出Layer类的具体介绍。
layer {
name: "data"
type: "Python"
top: "data"
top: "label"
python_param {
module: "voc_layers" #模块名,必须在PYTHONPATH中
layer: "SBDDSegDataLayer" #模块中的类名
param_str: "{\'sbdd_dir\': \'../data/sbdd/dataset\', \'seed\': 1337, \'split\': \'train\', \'mean\': (104.00699, 116.66877, 122.67892)}" #这里面的东西都会在setup之前被放在PythonLayer对象的属性中,在setup中解析这些参数,在forward和backward等中使用。
}
}
class
VOCSegDataLayer(caffe.Layer):
def
setup(
self
, bottom, top):
# config
params
=
eval
(
self
.param_str)
self
.voc_dir
=
params[
'voc_dir'
] #是不是觉得挺突兀的?为什么在include里的PythonLayer类中没有定义voc_dir这些属性,VOCSegDataLayer类中也没有定义这些属性,此处却表示VOCSegDataLayer有这些属性呢?因为是自动放进去的,在python_layer.hpp中有相关代码
self
.split
=
params[
'split'
]
self
.mean
=
np.array(params[
'mean'
])
self
.random
=
params.get(
'randomize'
,
True
)
self
.seed
=
params.get(
'seed'
,
None
)
# two tops: data and label
if
len
(top) !
=
2
:
raise
Exception(
"Need to define two tops: data and label."
)
# data layers have no bottoms
if
len
(bottom) !
=
0
:
raise
Exception(
"Do not define a bottom."
)
# load indices for images and labels
split_f
=
'{}/ImageSets/Segmentation/{}.txt'
.
format
(
self
.voc_dir,
self
.split)
self
.indices
=
open
(split_f,
'r'
).read().splitlines()
self
.idx
=
0
# make eval deterministic
if
'train'
not
in
self
.split:
self
.random
=
False
# randomization: seed and pick
if
self
.random:
random.seed(
self
.seed)
self
.idx
=
random.randint(
0
,
len
(
self
.indices)
-
1
)
def
reshape(
self
, bottom, top):
# load image + label image pair
self
.data
=
self
.load_image(
self
.indices[
self
.idx])
self
.label
=
self
.load_label(
self
.indices[
self
.idx])
# reshape tops to fit (leading 1 is for batch dimension)
top[
0
].reshape(
1
,
*
self
.data.shape)
top[
1
].reshape(
1
,
*
self
.label.shape)
def
forward(
self
, bottom, top):
# assign output
top[
0
].data[...]
=
self
.data
top[
1
].data[...]
=
self
.label
# pick next input
if
self
.random:
self
.idx
=
random.randint(
0
,
len
(
self
.indices)
-
1
)
else
:
self
.idx
+
=
1
if
self
.idx
=
=
len
(
self
.indices):
self
.idx
=
0
def
backward(
self
, top, propagate_down, bottom):
pass
def
load_image(
self
, idx):
"""
Load input image and preprocess for Caffe:
- cast to float
- switch channels RGB -> BGR
- subtract mean
- transpose to channel x height x width order
"""
im
=
Image.
open
(
'{}/JPEGImages/{}.jpg'
.
format
(
self
.voc_dir, idx))
in_
=
np.array(im, dtype
=
np.float32)
in_
=
in_[:,:,::
-
1
]
in_
-
=
self
.mean
in_
=
in_.transpose((
2
,
0
,
1
))
return
in_
https://chrischoy.github.io/research/caffe-python-layer/
http://blog.csdn.net/thesby/article/details/51264439
https://www.cnblogs.com/fanhaha/p/7247839.html
这两个博客讲的好
posted on 2017-11-16 11:50 MissSimple 阅读(1616) 评论(0) 编辑 收藏 举报