唐宇迪深度学习框架Caffe系列-7

caffe中如果我想定义自己的层,私人定制一波,

在文章:

唐宇迪深度学习框架Caffe系列-1中参考博客:

深度学习文章1:Caffe安装教程:Ubuntu16.04(CPU)

https://blog.csdn.net/u010193446/article/details/53259294

caffe安装过程中,有这么一段:

唐宇迪深度学习框架Caffe系列-7

这里我们打开自己的Makefile.config

gedit Makefile.config 

找到这一行# WITH_PYTHON_LAYER := 1

唐宇迪深度学习框架Caffe系列-7

删除 # 号,使这一行在程序中可用 

然后重新编译整个caffe(安装的时候怎么编译,现在就怎么再编译一遍,记得make clean 删除干净再编译)

sudo make clean
make all -j2
make pycaffe

做完这些工作,我们来尝试建立属于自己的层:

首先给出 .prototxt 文件,在流程文件中,我们新建了一个名字为MyPythonLayer,层类型为Python

name: "convolution"
input: "data"
input_dim: 1
input_dim: 3
input_dim: 100
input_dim: 100
layer {
  name: "conv"
  type: "Convolution"
  bottom: "data"
  top: "conv"
  convolution_param {
    num_output: 3
    kernel_size: 5
    stride: 1
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: 'MyPythonLayer'
  type: 'Python'
  top: 'output'
  bottom: 'conv'
  python_param {
    module: 'mypythonlayer'
    layer: 'MyLayer'
    param_str: "'num': 21"
  }
}

其中

input_dim: 1
input_dim: 3
input_dim: 100
input_dim: 100

代表 batch * C * H * W

新建层的功能 将上一层的结果,每一个特征图每个位置 +21 

注意 :  layer: 'MyLayer' 

唐宇迪深度学习框架Caffe系列-7

bottom 指的是输入这一层的是什么

top 指的是 经过这一层后 输出的是什么 

输入输出可以有很多个 比如数据层的输出就是两个 

  top: "data"
  top: "label"

在python代码里面就和下面的代码一样是  top[0]  top[1]

 

所以在 mypythonlayer.py 中(文件名字和  module: 'mypythonlayer'  一样)

import sys
caffe_root='/home/tyd/caffe/'
sys.path.insert(0, caffe_root+'python')
import caffe
import numpy as np                                                                                                                                                       
import yaml
import cv2   
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

class MyLayer(caffe.Layer):

    def setup(self, bottom, top):
        self.num = yaml.load(self.param_str)["num"]
        print "Parameter num : ", self.num

    def reshape(self, bottom, top):
        pass

    def forward(self, bottom, top):
        top[0].reshape(*bottom[0].shape) # 将输出top 变成 输入bottom 一样的维度
        print bottom[0].data.shape
        print bottom[0].data
        top[0].data[...] = bottom[0].data + self.num
        print top[0].data[...]

    def backward(self, top, propagate_down, bottom):
        pass



net = caffe.Net('conv.prototxt',caffe.TEST)
#im = np.array(Image.open('timg.jpeg'))
im = np.array(cv2.imread('timg.jpeg'))
print im.shape
#im_input = im[np.newaxis, np.newaxis, :, :]
im_input = im[np.newaxis, :, :]
print im_input.shape
#print im_input.transpose((1,0,2,3)).shape
im_input2 = im_input.transpose((0,3,1,2))
print im_input2.shape
#print im_input.shape
net.blobs['data'].reshape(*im_input2.shape)
net.blobs['data'].data[...] = im_input2
net.forward() # 把网络运行一遍

im = np.array(cv2.imread('timg.jpeg'))
print im.shape (496,700,3)
im_input = im[np.newaxis, :, :]
print im_input.shape (1,496,700,3)
im_input2 = im_input.transpose((0,3,1,2))
print im_input2 .shape (1,3,496,700)

这里是希望把维度变成和caffe中的 batch * C * H * W 一样

input_dim: 1
input_dim: 3
input_dim: 100
input_dim: 100

net.blobs['data'].reshape(*im_input2.shape)
net.blobs['data'].data[...] = im_input2

这里是因为网络中是1*3*100*100,读入的图像是(1,3,496,700)

这里做的工作是把网络的格式变成(1,3,496,700),然后把读入的图像放进去