zoukankan      html  css  js  c++  java
  • caffe增加新的layer

    ---恢复内容开始---

    在caffe中如果想要增加新的功能层,必须要自己在caffe的安装目录下(source code)中增加相应的文件

    大体步骤如下:

    1. 在caffe/src/caffe/proto/caffe.proto中增加对应layer的parameter message,  有两部分,现在LayerParameter中注册新层名字,注意选取不重复的ID, 然后写上新层的message传递的参数
    2. 在caffe/include/caffe/layers/中添加相应的新层的hpp文件,看其他层的实现,仿照着写
    3. 在caffe/src/caffe/layers/增加相应的.cpp和.cu的文件,进行类的实现, 在文件的末尾仿照着写个注册的语句REGISTE....
    4. 在caffe/src/caffe/gtest中增加新层的测试代码,这样可以保证所添加的层是正确的,不会在之后的运行中报错

    参考教程: https://blog.csdn.net/tangwei2014/article/details/46815231

    https://www.cnblogs.com/denny402/p/5071126.html

    tensorflow ckpt转 caffemodel遇到的坑

    龙明盛老师的论文基本都是caffe   可以看他是怎么实现的一些层

    一个别人实现的新层例子: 

    https://github.com/luoyetx/OrdinalRegression

    具体实现:

    1. 在newlayer.hpp中常定义一些常量或者变量,用来在前传中存储中间计算结果,因为如果定义在forward计算过程中,那么反传时还要重复计算,所以定义在hpp文件中比较合适
    2. 在newlayer.cpp中,主要有三个功能需要实现: 
      1. LayerSetUp: 主要是做一些CHECK工作,然后根据bottom和top对类中的数据成员初始化    注意一般都是继承基类,如果基类实现了就不要再实现了
      2. Forward_cpu: 前传
      3. backward_cpu: 反传,计算梯度  
    3. 在newlayer.cu中,实现GPU下的前传和反传
    4. 测试代码
    5. 重新编译, make all      make test    make runtest

     一些基础知识:

    1. Blob 是一个模板类,相当于是个结构体,主要的成员变量有 data_, diff_, shape_, count_, capacity_,   成员函数主要有Reshape, ReshapeLike, SharedData, Updata
      1. 参考: https://blog.csdn.net/seven_first/article/details/47398613
      2. https://www.jianshu.com/p/59e77efcce83
    2. Layer:  卷积层
      1. 参考: https://blog.csdn.net/xizero00/article/details/51049858
      2. 官网api查找:  https://caffe.berkeleyvision.org/doxygen/namespacecaffe.html

    Kevin 老师帮忙整理的资料

    1.  bottom是个blob指针的数组,bottom[0]第一个输入的指针, bottom[1]第二个输入指针, top[0]第一个输出指针

    LayerSetUp函数中:

    int bottom_batch_size_ = bottom[0]->num();
    int bottom_channels_ = bottom[0]->channels();
    int bottom_height_ = bottom[0]->height();
    int bottom_width_ = bottom[0]->width();

    注意,对于指针取数据用->  对于单纯blob取数据 用 .

    blob<Dtype>*  表示指向blob的指针,其中blob的数据类型是Dtype

    但是如果要取blob对应的数据地址要用 ->cpu_data()  这个类似于取数据的地址操作

    Forward_cpu函数中:

    Dtype* top_data = top[0]->mutable_cpu_data();  //mutable_cpu_data()表示top[0]数据可修改   

    const Dtype* bottom_data = bottom[0]->cpu_data();   //-> cpu_data()表示只可读

    caffe自带的数学函数 https://blog.csdn.net/seven_first/article/details/47378697

    2.  shape操作

    vector<int> top_shape = bottom[0]->shape();
    top[0]->Reshape(top_shape);

    如果top[0]的channel是bottom[0]的channel+bottom[1]的channel,其他的都一样,可以这样定义:
    vector<int> top_shape = bottom[0]->shape();
    top_shape[1] = bottom[0]->shape(1)+bottom[0]->shape(1);
    top[0]->Reshape(top_shape);

    如果这个变量是一个中间变量的话,可以这样定义:
    Blob<Dtype> conf_permute_; //一般写在.hpp里
    然后在.cpp中的LayerSetUp或者Reshape中定义 conf_permute_.ReshapeLike(*(bottom[1]));

    注意成员函数的参数都是类型的,比如是blob指针,就可以直接输bottom[0], 如果要求参数是blob, 

    如果有取地址符,那么只需要传入实体,这样也能修改内容

    如果是指针的话是 *的形式

    3. 关于count

    const int count = bottom[0]->count();表示 count = bottom[0]的num * channel * height * width
    const int count = bottom[0]->count(0, 1); 表示 count = bottom[0]的num * channel
    const int count = bottom[0]->count(0, 2); 表示 count = bottom[0]的num * channel* height
    const int count = bottom[0]->count(1); 表示 count = bottom[0]的 channel * height * width
    const int count = bottom[0]->count(2); 表示 count = bottom[0]的 height * width

    const int num = bottom[0]->shape(0); //bottom[0]的batch_size
    const int channel = bottom[0]->shape(1); //bottom[0]的channel
    const int height = bottom[0]->shape(2); //bottom[0]的height
    const int width = bottom[0]->shape(3); //bottom[0]的width


    3.printf:
    const int count = bottom[0]->count();
    printf("count %d ", count);


    4.gdb Debug调试:
    https://zhuanlan.zhihu.com/p/28146796

  • 相关阅读:
    Java中的接口回调
    java中使用String的replace方法替换html模板保存文件
    overflow:解决 div的高度塌陷问题
    鼠标单击到 img行的时候图片隐藏方案
    HTML中的行级标签和块级标签 《转换》
    Java中的异常注意点
    oracle数据库忘记用户名和密码莫着急
    Log4j记录日志使用方法
    Java中的overload(方法的覆写)
    jdk和tomcat环境配置
  • 原文地址:https://www.cnblogs.com/lainey/p/9026381.html
Copyright © 2011-2022 走看看