修改caffe源代码--添加loss(层)函数--GPU
2017-08-31 20:50
302 查看
本文主体参考:http://blog.csdn.net/sihailongwang/article/details/72783944
因其在windows上面操作,本文提供在Linux上操作的尝试。另外部分命名不规则,所以修正了一下。
修改caffe源代码,loss层是一个比较独立的一个层,而且可以仿照caffe给的样例进行添加,难度会稍微小点。
caffe自带了十种loss层(contrastive、euclidean、hinge、multinomial_logistic、
sigmoid_cross_entropy、smooth_L1、smooth_L1_ohem、
softmax、softmax_ohem、infogain)
详见:http://blog.csdn.NET/sihailongwang/article/details/72657637
公式含义推荐:http://blog.csdn.net/u012177034/article/details/52144325
接下来,就是自己添加一个新的loss(层)函数了,我打算添加:Absolute loss
plain copy
optional AbsoluteLossParameter absolute_loss_param = 151;
在caffe.proto中的某个与message LayerParameter 平级的位置添加下面这段代码:
[cpp] view
plain copy
message AbsoluteLossParameter {
optional float dis = 1 [default = 1.0];
}
第二步:打开./include/caffe/下的文件loss_layers.hpp,在caffe命名空间最下面添加:
第三步:在./src/caffe/util/math_functions.cpp中增加“绝对值求和”模板函数,在caffe命名空间最下面添加:
template <typename Dtype>
Dtype caffe_cpu_abs_sum(const int n, const Dtype* x) {
return caffe_cpu_asum(n, x);
}
template
float caffe_cpu_abs_sum<float>(const int n, const float* x);
template
double caffe_cpu_abs_sum<double>(const int n, const double* x);
第四步:在./src/caffe/layers/下增加相应layer的CPU/GPU实现文件:
CPU版本(absolute_loss_layer.cpp):
#include <vector>
#include "caffe/loss_layers.hpp"
#include "caffe/util/math_functions.hpp"
namespace caffe {
template <typename Dtype>
void AbsoluteLossLayer<Dtype>::Reshape(
const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
LossLayer<Dtype>::Reshape(bottom, top); //在LossLayer 中定义
CHECK_EQ(bottom[0]->count(1), bottom[1]->count(1)) //保证输入维度相同
<< "Inputs must have the same dimension.";
dis_.ReshapeLike(*bottom[0]); //Blob 类型的diff_用来存放两个bottom的差,和bottom具有相同的
}
template <typename Dtype>
void AbsoluteLossLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
int count = bottom[0]->count(); //总共有count个featuremap
caffe_sub(
count,
bottom[0]->cpu_data(),
bottom[1]->cpu_data(),
dis_.mutable_cpu_data()); //diff_ = bottom[0] - bottom[1]
Dtype loss_param = this->layer_param_.absolute_loss_param().dis();
Dtype abs_sum = caffe_cpu_abs_sum(count,dis_.cpu_data());
//Dtype dot = caffe_cpu_abs_sum()(count, diff_.cpu_data(), dis_.cpu_data());
Dtype loss = loss_param * abs_sum / bottom[0]->num();
top[0]->mutable_cpu_data()[0] = loss;
}
template <typename Dtype>
void AbsoluteLossLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {
for (int i = 0; i < 2; ++i) {
if (propagate_down[i]) {
//对于输入的label bottom propagate_dowm为0
const Dtype sign = (i == 0) ? 1 : -1;
const Dtype alpha = sign * top[0]->cpu_diff()[0] / bottom[i]->num();
caffe_cpu_axpby(
bottom[i]->count(), // count
alpha, // alpha
dis_.cpu_data(), // a
Dtype(0), // beta
bottom[i]->mutable_cpu_diff()); // b
} //bottom[i]->mutable_cpu_diff()) = alpha*dis_.cpu_data()
}
}
#ifdef CPU_ONLY
STUB_GPU(AbsoluteLossLayer);
#endif
INSTANTIATE_CLASS(AbsoluteLossLayer);
REGISTER_LAYER_CLASS(AbsoluteLoss);
} // namespace caffe
GPU版本(absolute_loss_layer.cu):
#include <vector>
#include "caffe/layers/absolute_loss_layer.hpp"
#include "caffe/util/math_functions.hpp"
namespace caffe {
template <typename Dtype>
void AbsoluteLossLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
int count = bottom[0]->count(); //总共有count个featuremap
caffe_gpu_sub(
count,
bottom[0]->gpu_data(),
bottom[1]->gpu_data(),
dis_.mutable_gpu_data());
Dtype loss_param = this->layer_param_.absolute_loss_param().dis();
Dtype abs_sum;
caffe_gpu_asum(count, dis_.gpu_data(), &abs_sum);
Dtype loss = loss_param * abs_sum/ bottom[0]->num();
top[0]->mutable_cpu_data()[0] = loss;
}
template <typename Dtype>
void AbsoluteLossLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {
for (int i = 0; i < 2; ++i) {
if (propagate_down[i]) {
const Dtype sign = (i == 0) ? 1 : -1;
const Dtype alpha = sign * top[0]->cpu_diff()[0] / bottom[i]->num();
caffe_gpu_axpby(
bottom[i]->count(), // count
alpha, // alpha
dis_.gpu_data(), // a
Dtype(0), // beta
bottom[i]->mutable_gpu_diff()); // b
}
}
}
INSTANTIATE_LAYER_GPU_FUNCS(AbsoluteLossLayer);
} // namespace caffe
第五步:打开caffe,进行编译,编译成功即可、
因其在windows上面操作,本文提供在Linux上操作的尝试。另外部分命名不规则,所以修正了一下。
修改caffe源代码,loss层是一个比较独立的一个层,而且可以仿照caffe给的样例进行添加,难度会稍微小点。
caffe自带了十种loss层(contrastive、euclidean、hinge、multinomial_logistic、
sigmoid_cross_entropy、smooth_L1、smooth_L1_ohem、
softmax、softmax_ohem、infogain)
详见:http://blog.csdn.NET/sihailongwang/article/details/72657637
公式含义推荐:http://blog.csdn.net/u012177034/article/details/52144325
接下来,就是自己添加一个新的loss(层)函数了,我打算添加:Absolute loss
第一步:在caffe.proto增加对应的LayerParameter 和 message:
在caffe.proto中的message LayerParameter 中添加下面这行:
[cpp] viewplain copy
optional AbsoluteLossParameter absolute_loss_param = 151;
在caffe.proto中的某个与message LayerParameter 平级的位置添加下面这段代码:
[cpp] view
plain copy
message AbsoluteLossParameter {
optional float dis = 1 [default = 1.0];
}
第二步:打开./include/caffe/下的文件loss_layers.hpp,在caffe命名空间最下面添加:
template <typename Dtype> class AbsoluteLossLayer : public LossLayer<Dtype> { public: explicit AbsoluteLossLayer(const LayerParameter& param) : LossLayer<Dtype>(param), dis_() {} virtual void Reshape(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top); virtual inline const char* type() const { return "AbsoluteLoss"; } virtual inline bool AllowForceBackward(const int bottom_index) const { return true; } protected: /// @copydoc AbsoluteLossLayer virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top); virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top); virtual void Backward_cpu(const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom); virtual void Backward_gpu(const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom); Blob<Dtype> dis_; };
第三步:在./src/caffe/util/math_functions.cpp中增加“绝对值求和”模板函数,在caffe命名空间最下面添加:
template <typename Dtype>
Dtype caffe_cpu_abs_sum(const int n, const Dtype* x) {
return caffe_cpu_asum(n, x);
}
template
float caffe_cpu_abs_sum<float>(const int n, const float* x);
template
double caffe_cpu_abs_sum<double>(const int n, const double* x);
第四步:在./src/caffe/layers/下增加相应layer的CPU/GPU实现文件:
CPU版本(absolute_loss_layer.cpp):
#include <vector>
#include "caffe/loss_layers.hpp"
#include "caffe/util/math_functions.hpp"
namespace caffe {
template <typename Dtype>
void AbsoluteLossLayer<Dtype>::Reshape(
const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
LossLayer<Dtype>::Reshape(bottom, top); //在LossLayer 中定义
CHECK_EQ(bottom[0]->count(1), bottom[1]->count(1)) //保证输入维度相同
<< "Inputs must have the same dimension.";
dis_.ReshapeLike(*bottom[0]); //Blob 类型的diff_用来存放两个bottom的差,和bottom具有相同的
}
template <typename Dtype>
void AbsoluteLossLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
int count = bottom[0]->count(); //总共有count个featuremap
caffe_sub(
count,
bottom[0]->cpu_data(),
bottom[1]->cpu_data(),
dis_.mutable_cpu_data()); //diff_ = bottom[0] - bottom[1]
Dtype loss_param = this->layer_param_.absolute_loss_param().dis();
Dtype abs_sum = caffe_cpu_abs_sum(count,dis_.cpu_data());
//Dtype dot = caffe_cpu_abs_sum()(count, diff_.cpu_data(), dis_.cpu_data());
Dtype loss = loss_param * abs_sum / bottom[0]->num();
top[0]->mutable_cpu_data()[0] = loss;
}
template <typename Dtype>
void AbsoluteLossLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {
for (int i = 0; i < 2; ++i) {
if (propagate_down[i]) {
//对于输入的label bottom propagate_dowm为0
const Dtype sign = (i == 0) ? 1 : -1;
const Dtype alpha = sign * top[0]->cpu_diff()[0] / bottom[i]->num();
caffe_cpu_axpby(
bottom[i]->count(), // count
alpha, // alpha
dis_.cpu_data(), // a
Dtype(0), // beta
bottom[i]->mutable_cpu_diff()); // b
} //bottom[i]->mutable_cpu_diff()) = alpha*dis_.cpu_data()
}
}
#ifdef CPU_ONLY
STUB_GPU(AbsoluteLossLayer);
#endif
INSTANTIATE_CLASS(AbsoluteLossLayer);
REGISTER_LAYER_CLASS(AbsoluteLoss);
} // namespace caffe
GPU版本(absolute_loss_layer.cu):
#include <vector>
#include "caffe/layers/absolute_loss_layer.hpp"
#include "caffe/util/math_functions.hpp"
namespace caffe {
template <typename Dtype>
void AbsoluteLossLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
int count = bottom[0]->count(); //总共有count个featuremap
caffe_gpu_sub(
count,
bottom[0]->gpu_data(),
bottom[1]->gpu_data(),
dis_.mutable_gpu_data());
Dtype loss_param = this->layer_param_.absolute_loss_param().dis();
Dtype abs_sum;
caffe_gpu_asum(count, dis_.gpu_data(), &abs_sum);
Dtype loss = loss_param * abs_sum/ bottom[0]->num();
top[0]->mutable_cpu_data()[0] = loss;
}
template <typename Dtype>
void AbsoluteLossLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {
for (int i = 0; i < 2; ++i) {
if (propagate_down[i]) {
const Dtype sign = (i == 0) ? 1 : -1;
const Dtype alpha = sign * top[0]->cpu_diff()[0] / bottom[i]->num();
caffe_gpu_axpby(
bottom[i]->count(), // count
alpha, // alpha
dis_.gpu_data(), // a
Dtype(0), // beta
bottom[i]->mutable_gpu_diff()); // b
}
}
}
INSTANTIATE_LAYER_GPU_FUNCS(AbsoluteLossLayer);
} // namespace caffe
第五步:打开caffe,进行编译,编译成功即可、
相关文章推荐
- DeepLearning(基于caffe)实战项目(8)--修改caffe源代码从添加loss(层)函数开始
- 修改caffe源代码--添加loss(层)函数--CPU
- 修改caffe源代码从添加loss(层)函数开始
- caffe infogain_loss 信息熵代价函数
- 在caffe中添加triplet loss layer
- 将focal loss添加到你的网络框架当中(caffe 版本)
- JS自定义功能函数实现动态添加网址参数修改网址参数值
- 适合所有表的添加、删除、修改的函数
- caffe中loss函数代码分析--caffe学习(16)
- 如何为WPF添加Main()函数 程序入口点的修改
- 怎样给没有源代码的.net程序添加修改功能
- caffe中的loss函数简单介绍
- 在 caffe 中添加 FaceNet 中 Triplet Loss Layer
- Caffe添加自定义层-自定义loss
- 如果需要改动源代码生成器中的代码,如何做到,下次重新生成的代码也具有额为添加的特殊函数
- JS自定义功能函数实现动态添加网址参数修改网址参数值
- 适合所有表的添加、删除、修改的函数
- 适合所有表的添加、删除、修改的函数
- caffe搭建--caffe- win10 vs2015 编译(支持GPU)--注意在cmake的时候需要根据情况仔细修改配置
- caffe 加权交叉熵损失函数层(weighted sigmoid_cross_entropy_loss_layer)添加方法