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(0len(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(0len(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编辑  收藏  举报

导航