修改caffe源代码--添加loss(层)函数--GPU

版权声明:本文为博主原创文章,转载请加入原文链接,谢谢。。 https://blog.csdn.net/shawncheer/article/details/77752653

本文主体参考: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


第一步:在caffe.proto增加对应的LayerParameter 和 message:

在caffe.proto中的message LayerParameter 中添加下面这行:

[cpp]  view plain  copy
  1. optional AbsoluteLossParameter absolute_loss_param = 151;  

在caffe.proto中的某个与message LayerParameter 平级的位置添加下面这段代码:

[cpp]  view plain  copy
  1. message AbsoluteLossParameter {    
  2.   optional float dis = 1 [default = 1.0];    
  3. }    

第二步:打开./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,进行编译,编译成功即可、


猜你喜欢

转载自blog.csdn.net/shawncheer/article/details/77752653
今日推荐