caffe下添加python层

Caffe通过Boost中的Boost.Python模块来支持使用Python定义Layer:

  • 使用C++增加新的Layer繁琐、耗时而且很容易出错
  • 开发速度与执行速度之间的trade-off

编译同时支持Python Layer的Caffe,方便更改使用。如果想要使用应进行以下配置:
如果是首次编译,修改Caffe根目录下的Makefile.cinfig,uncomment

WITH_PYTHON_LAYER:=1

python层的主要标志是:
在这里插入图片描述
python层具体格式以及参数可以参照

添加python层

1.应该修改prototxt文件:

layer{
	type:"Python"
	name:"mylayer"
	bottom:"norm1"
	top:"mylayer"
	python_param{
		#python文件名
		module:"mylayer"
		#函数名
		layer:"mylayer"
	}
}

2.这里创建一个什么都不做的python层,仅仅把前一层的数据传给下一层。
在自己项目的目录下编写自己的python函数:
在这里插入图片描述

#!/usr/bin/env python
import sys
import caffe
class mylayer(caffe.Layer):
    #什么都不做
    def setup(self,bottom,top):
        pass
    #对输出数据进行形状变换,使输出数据和输入形状相同
    def reshape(self,bottom,top):
        top[0].reshape(*bottom[0].data.shape)

    def forward(self,bottom,top):
        #top[0].data[...]=bottom[0].data
        #把输入数据赋值给输出
        top[0].data[...]=bottom[0].data[:]

    def backward(self,top,propagate_down,bottom):
        for i in range(len(propagate_down)):
            if not propagate_down[i]:
                continue
            #bottom[i].diff[...]=top[i].diff
            #把高层的梯度赋值给底层,注意此处为反向传播
            bottom[i].diff[...]=top[i].diff[:]
             

添加python的Loss层

1.修改.prototxt文件:
在文件的最后添加此层,注意删除原有的loss层,注意此层的输入。

layer{
    type:"Python"
    name:"loss"
    top:"loss"
    bottom:"fc9"
    bottom:"label"
    python_param{
        module:"myloss"
        layer:"myloss"
    }
    #set loss weight,so caffe know this is loss layer
    loss_weight:1
}

2.添加python文件,位置同上:

import caffe
import numpy as np
 
 
class EuclideanLossLayer(caffe.Layer):
    def setup(self, bottom, top):
        # top是最后的loss值, bottom 中有两个值,一个网络的输出, 一个是label。
        # check input pair
        if len(bottom) != 2:
            raise Exception("Need two inputs to compute distance.")
 
    def reshape(self, bottom, top):
        '''
        在reshape中确定输出的形状,即top的形状。
        所以,最后一定是top[i].reshape(形状),i是对应的输出编号,这里只有一个输出。
        '''
        # check input dimensions match
        if bottom[0].count != bottom[1].count:
            raise Exception("Inputs must have the same dimension.")
        # difference is shape of inputs
        self.diff = np.zeros_like(bottom[0].data, dtype=np.float32)
        # loss output is scalar
        top[0].reshape(1)
 
    def forward(self, bottom, top):
        '''
        forward函数中最后的结果要放入top[i].data[...]中,
        其中i就是第几个top,因为有些层会有多个输出的。
        '''
        self.diff[...] = bottom[0].data - bottom[1].data
        #这里定义了平方损失函数
        top[0].data[...] = np.sum(self.diff**2) / bottom[0].num / 2.
 
    def backward(self, top, propagate_down, bottom):
        '''
        backward函数中,是对输入这一层的数据求梯度,
        而不是输出这一层的数据。即是对bottom求梯度,
        不是对top求梯度,所以这样写:
        bottom[i].diff[...]=得到的梯度
        '''
        for i in range(2):
            if not propagate_down[i]:
                continue
            if i == 0:
                sign = 1
            else:
                sign = -1
            #注意此处为反向传播的梯度计算,计算了loss函数的导数
            bottom[i].diff[...] = sign * self.diff / bottom[i].num

最后,我们可以通过代码验证网络是否符合要求:

#!/usr/bin/env python
import sys
#这里在其他人的工程下建立自己的工程,所以指定了caffe位置
#如果直接在caffe下建立的工程,配好环境,应该不需要
caffe_root = 'path/to/caffe/' 
sys.path.insert(0, caffe_root + 'python')
import caffe
#使用导入的caffe包
#设置使用GPU
caffe.set_device(0)
caffe.set_mode_gpu()
print("==============================")
#指定网络文件
net=caffe.Net("add_python_layer.prototxt",caffe.TEST)
#对文件进行前向传播
net.forward()
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值