修改caffe源代码从添加loss(层)函数开始

来源:互联网 发布:菜鸟网络 工作强度 编辑:程序博客网 时间:2024/05/16 19:52

DeepLearning(基于caffe)实战项目(8)--修改caffe源代码从添加loss(层)函数开始

标签: Caffe实战项目LossLayer修改源代码
479人阅读 评论(0)收藏举报
分类:
作者同类文章X

    目录(?)[+]

    1. 第一步在caffeproto增加对应的LayerParameter message
    2. 第二步在includecaffelayers下增加相应的layer的声明
    3. 第三步在srccaffeutilmath_functionscpp下增加绝对值求和模板函数
    4. 第四步在srccaffelayers下增加相应layer的CPUGPU实现文件
    5. 第五步用vs打开caffe进行编译编译成功后恭喜你功力又上升一个段位哈哈

    在caffe中摸爬滚打了一个多月了,修改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

    [plain] view plain copy
    print?
    1. optional AbsoluteLossParameter Absolute_loss_param = 151;  

    [plain] view plain copy
    print?
    1. message AbsoluteLossParameter   
    2. {  
    3.   optional float dis = 1 [default = 1];  
    4. }  

    第二步:在./include/caffe/layers/下增加相应的layer的声明

    [plain] view plain copy
    print?
    1. #ifndef CAFFE_ABSOLUTE_LOSS_LAYER_HPP_  
    2. #define CAFFE_ABSOLUTE_LOSS_LAYER_HPP_  
    3.   
    4.   
    5. #include <vector>  
    6.   
    7.   
    8. #include "caffe/blob.hpp"  
    9. #include "caffe/layer.hpp"  
    10. #include "caffe/proto/caffe.pb.h"  
    11.   
    12.   
    13. #include "caffe/layers/loss_layer.hpp"  
    14.   
    15.   
    16. namespace caffe {  
    17.   
    18.   
    19. template <typename Dtype>  
    20. class AbsoluteLossLayer : public LossLayer<Dtype> {  
    21.  public:  
    22.   explicit AbsoluteLossLayer(const LayerParameter& param)  
    23.       : LossLayer<Dtype>(param), dis_() {}  
    24.   virtual void Reshape(const vector<Blob<Dtype>*>& bottom,  
    25.       const vector<Blob<Dtype>*>& top);  
    26.   
    27.   
    28.   virtual inline const char* type() const { return "AbsoluteLoss"; }  
    29.   
    30.   
    31.   virtual inline bool AllowForceBackward(const int bottom_index) const {  
    32.     return true;  
    33.   }  
    34.   
    35.   
    36.  protected:  
    37.   /// @copydoc AbsoluteLossLayer  
    38.   virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,  
    39.       const vector<Blob<Dtype>*>& top);  
    40.   virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,  
    41.       const vector<Blob<Dtype>*>& top);  
    42.   
    43.   
    44.   virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,  
    45.       const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom);  
    46.   virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,  
    47.       const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom);  
    48.   
    49.   
    50.   Blob<Dtype> dis_;  
    51. };  
    52.   
    53.   
    54. }  // namespace caffe  
    55.   
    56.   
    57. #endif  // CAFFE_EUCLIDEAN_LOSS_LAYER_HPP_  
    58.   
    59. #endif  // CAFFE_EUCLIDEAN_LOSS_LAYER_HPP_  

    第三步:在./src/caffe/util/math_functions.cpp/下增加“绝对值求和”模板函数

    说明:因为AbsoluteLoss需要绝对值求和,所以在math_fuction.cpp中需要增加一个“绝对值”模板函数(与此同时,我惊喜的发现了BLAS、CBLAS

    /********************************************************************************************************************

    TIPS:科普一下什么是BLAS/CBLAS

    Basic Linear Algebra Subprograms,即基础线性代数子程序库,里边拥有大量的已经编好的关于线性代数运算的程序,主要用于向量和矩阵的计算的高性能数学库,本身是由Fortran编写的,为了方便C/C++程序使用,就有了BLAS的C接口库CBLAS,详细列表:http://www.netlib.org/blas/

    /********************************************************************************************************************

    [plain] view plain copy
    print?
    1. //--------------------------add------------------------------------------  
    2. template <>  
    3. float caffe_cpu_asum<float>(const int n, const float* x) {  
    4.   return cblas_sasum(n, x, 1);      //sum of absolute values  
    5. }  
    6.   
    7. template <>  
    8. double caffe_cpu_asum<double>(const int n, const double* x) {  
    9.   return cblas_dasum(n, x, 1);      //sum of absolute values  
    10. }  
    11.   
    12. template <typename Dtype>  
    13. Dtype caffe_cpu_abs_sum(const int n, const Dtype* x) {  
    14.   return caffe_cpu_asum(n, x);  
    15. }  
    16.   
    17. template  
    18. float caffe_cpu_asum<float>(const int n, const float* x);  
    19.   
    20. template  
    21. double caffe_cpu_asum<double>(const int n, const double* x);  
    22. //-------------------------add-------------------------------------------  

    第四步:在./src/caffe/layers/下增加相应layer的CPU/GPU实现文件

       CPU版本(absolute_loss_layer.cpp)

    [plain] view plain copy
    print?
    1. #include <vector>  
    2.   
    3. #include "caffe/layers/absolute_loss_layer.hpp"  
    4. #include "caffe/util/math_functions.hpp"  
    5.   
    6. namespace caffe {  
    7.   
    8. template <typename Dtype>  
    9. void AbsoluteLossLayer<Dtype>::Reshape(  
    10.   const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {  
    11.   LossLayer<Dtype>::Reshape(bottom, top);   //在LossLayer 中定义  
    12.   CHECK_EQ(bottom[0]->count(1), bottom[1]->count(1))  //保证输入维度相同  
    13.       << "Inputs must have the same dimension.";  
    14.   dis_.ReshapeLike(*bottom[0]);           //Blob 类型的diff_用来存放两个bottom的差,和bottom具有相同的  
    15. }  
    16.   
    17. template <typename Dtype>  
    18. void AbsoluteLossLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,  
    19.     const vector<Blob<Dtype>*>& top) {  
    20.   int count = bottom[0]->count();   //总共有count个featuremap   
    21.   caffe_sub(  
    22.       count,  
    23.       bottom[0]->cpu_data(),  
    24.       bottom[1]->cpu_data(),  
    25.       dis_.mutable_cpu_data());    //diff_ = bottom[0] - bottom[1]   
    26.   Dtype loss_param = this->layer_param_.absolute_loss_param().dis();  
    27.   Dtype abs_sum = caffe_cpu_abs_sum(count,dis_.cpu_data());  
    28.   //Dtype dot = caffe_cpu_abs_sum()(count, diff_.cpu_data(), dis_.cpu_data());  
    29.   Dtype loss = loss_param * abs_sum / bottom[0]->num();  
    30.   top[0]->mutable_cpu_data()[0] = loss;  
    31. }  
    32.   
    33. template <typename Dtype>  
    34. void AbsoluteLossLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,  
    35.     const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {  
    36.   for (int i = 0; i < 2; ++i) {  
    37.     if (propagate_down[i]) {  
    38.        //对于输入的label bottom propagate_dowm为0  
    39.       const Dtype sign = (i == 0) ? 1 : -1;  
    40.       const Dtype alpha = sign * top[0]->cpu_diff()[0] / bottom[i]->num();  
    41.       caffe_cpu_axpby(  
    42.           bottom[i]->count(),                       // count  
    43.           alpha,                             // alpha  
    44.           dis_.cpu_data(),                        // a  
    45.           Dtype(0),                           // beta  
    46.           bottom[i]->mutable_cpu_diff());                 // b  
    47.     }     //bottom[i]->mutable_cpu_diff()) = alpha*dis_.cpu_data()  
    48.   }  
    49. }  
    50.   
    51. #ifdef CPU_ONLY  
    52. STUB_GPU(AbsoluteLossLayer);  
    53. #endif  
    54.   
    55. INSTANTIATE_CLASS(AbsoluteLossLayer);  
    56. REGISTER_LAYER_CLASS(AbsoluteLoss);  
    57.   
    58. }  // namespace caffe  
    GPU版本(absolute_loss_layer.cu)
    [plain] view plain copy
    print?
    1. #include <vector>  
    2.   
    3.   
    4. #include "caffe/layers/absolute_loss_layer.hpp"  
    5. #include "caffe/util/math_functions.hpp"  
    6.   
    7. namespace caffe {  
    8.   
    9. template <typename Dtype>  
    10. void AbsoluteLossLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,  
    11.     const vector<Blob<Dtype>*>& top) {  
    12.   int count = bottom[0]->count();   //总共有count个featuremap   
    13.   caffe_gpu_sub(  
    14.       count,  
    15.       bottom[0]->gpu_data(),  
    16.       bottom[1]->gpu_data(),  
    17.       dis_.mutable_gpu_data());  
    18.   Dtype loss_param = this->layer_param_.  
    19.   Dtype abs_sum;  
    20.   caffe_gpu_asum(count, dis_.gpu_data(), &abs_sum);  
    21.   Dtype loss = loss_param * abs_sum/ bottom[0]->num();  
    22.   top[0]->mutable_cpu_data()[0] = loss;  
    23. }  
    [plain] view plain copy
    print?
    1. template <typename Dtype>  
    2. void AbsoluteLossLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,  
    3.     const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {  
    4.   for (int i = 0; i < 2; ++i) {  
    5.     if (propagate_down[i]) {  
    6.       const Dtype sign = (i == 0) ? 1 : -1;  
    7.       const Dtype alpha = sign * top[0]->cpu_diff()[0] / bottom[i]->num();  
    8.       caffe_gpu_axpby(  
    9.           bottom[i]->count(),                       // count  
    10.           alpha,                             // alpha  
    11.           dis_.gpu_data(),                        // a  
    12.           Dtype(0),                           // beta  
    13.           bottom[i]->mutable_gpu_diff());                 // b  
    14.     }  
    15.   }  
    16. }  
    17.   
    18. INSTANTIATE_LAYER_GPU_FUNCS(AbsoluteLossLayer);  
    19.   
    20. }  // namespace caffe  

    第五步:用vs打开caffe,进行编译,编译成功后,恭喜你,功力又上升一个段位,哈哈

    1.修改../windows/libcaffe下的两个文件:libcaffe.vcxproj和libcaffe.vcxproj.filters

    libcaffe.vcxproj增加:

    [plain] view plain copy
    print?
    1. <ClCompile Include="..\..\src\caffe\layers\absolute_loss_layer.cpp" />  
    2. <ClInclude Include="..\..\include\caffe\layers\absolute_loss_layer.hpp" />  
    3. <CudaCompile Include="..\..\src\caffe\layers\absolute_loss_layer.cu" />  
    libcaffe.vcxproj.filter增加:
    [plain] view plain copy
    print?
    1. <ClInclude Include="..\..\include\caffe\layers\absolute_loss_layer.hpp">  
    2. <Filter>include\layers</Filter>  
    3. </ClInclude>  
    4. <CudaCompile Include="..\..\src\caffe\layers\absolute_loss_layer.cu">  
    5. <Filter>cu\layers</Filter>  
    6. </CudaCompile>  
    7. <ClCompile Include="..\..\src\caffe\layers\absolute_loss_layer.cpp">  
    8. <Filter>src\layers</Filter>  
    9. </ClCompile>  
    2.打开caffe.sln,再进行重新生成新的解决方案,编译通过后,恭喜你功力又升一级!
    0
    0
     
     

      相关文章推荐
    • caffe添加新层教程
    • 【免费】深入理解Docker内部原理及网络配置--王渊命
    • pthread_create 传递参数时指针跑飞问题
    • SDCC 2017之区块链技术实战线上峰会--蔡栋
    • 【C++11新特性】 C++11智能指针之shared_ptr
    • php零基础到项目实战
    • 从零开始山寨Caffe·壹:仰望星空与脚踏实地
    • C语言及程序设计入门指导
    • LTE系统信息(1)-MIB
    • Android入门实战
    • typedef和define具体的详细区别
    • 5天搞定深度学习框架Caffe
    • C语言的一个关键字——static
    • 最快速度找到内存泄漏
    • DeepLearning(基于caffe)实战项目(8)--修改caffe源代码从添加loss(层)函数开始
    • DeepLearning(基于caffe)实战项目(1)--mnist_convert函数分析