1、在src\caffe\proto\caffe.proto中搜索message LayerParameter,在optional ReLUParameter relu_param = 123之后添加optional ReLU6Parameter relu6_param = 208; (最后的分号别忘了)

2、搜索message ReLUParameter,在这个ReLUParameter实现结构之后添加

// Message that stores parameters used by ReLU6Layer
message ReLU6Parameter {
  enum Engine {
    DEFAULT = 0;
    CAFFE = 1;
    CUDNN = 2;
  }
  optional Engine engine = 2 [default = DEFAULT];
}

支持proto头文件修改完毕,接下来添加所需的头文件和实现文件。

1.在blob/ssd/include/caffe/layers文件夹下新建relu6_layer.hpp,将

#ifndef CAFFE_RELU_LAYER_HPP_
#define CAFFE_RELU_LAYER_HPP_#include <vector>#include "caffe/blob.hpp"
#include "caffe/layer.hpp"
#include "caffe/proto/caffe.pb.h"#include "caffe/layers/neuron_layer.hpp"namespace caffe {/*** @brief Rectified Linear Unit non-linearity @f$ y = \min(6, \max(0, x)) @f$.*        The simple max is fast to compute, and the function does not saturate.*/
template <typename Dtype>
class ReLU6Layer : public NeuronLayer<Dtype> {public:/*** @param param provides ReLUParameter relu_param,*     with ReLULayer options:*   - negative_slope (\b optional, default 0).*     the value @f$ \nu @f$ by which negative values are multiplied.*/explicit ReLU6Layer(const LayerParameter& param): NeuronLayer<Dtype>(param) {}virtual inline const char* type() const { return "ReLU6"; }protected:/*** @param bottom input Blob vector (length 1)*   -# @f$ (N \times C \times H \times W) @f$*      the inputs @f$ x @f$* @param top output Blob vector (length 1)*   -# @f$ (N \times C \times H \times W) @f$*      the computed outputs @f$*        y = \max(0, x)*      @f$ by default.  If a non-zero negative_slope @f$ \nu @f$ is provided,*      the computed outputs are @f$ y = \max(0, x) + \nu \min(0, x) @f$.*/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);/*** @brief Computes the error gradient w.r.t. the ReLU inputs.** @param top output Blob vector (length 1), providing the error gradient with*      respect to the outputs*   -# @f$ (N \times C \times H \times W) @f$*      containing error gradients @f$ \frac{\partial E}{\partial y} @f$*      with respect to computed outputs @f$ y @f$* @param propagate_down see Layer::Backward.* @param bottom input Blob vector (length 1)*   -# @f$ (N \times C \times H \times W) @f$*      the inputs @f$ x @f$; Backward fills their diff with*      gradients @f$*        \frac{\partial E}{\partial x} = \left\{*        \begin{array}{lr}*            0 & \mathrm{if} \; x \le 0 \\*            \frac{\partial E}{\partial y} & \mathrm{if} \; x > 0*        \end{array} \right.*      @f$ if propagate_down[0], by default.*      If a non-zero negative_slope @f$ \nu @f$ is provided,*      the computed gradients are @f$*        \frac{\partial E}{\partial x} = \left\{*        \begin{array}{lr}*            \nu \frac{\partial E}{\partial y} & \mathrm{if} \; x \le 0 \\*            \frac{\partial E}{\partial y} & \mathrm{if} \; x > 0*        \end{array} \right.*      @f$.*/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);
};}  // namespace caffe#endif  // CAFFE_RELU_LAYER_HPP_
 

2.在blob/ssd/src/caffe/layers文件夹下新建relu6_layer.cpp,将

#include <algorithm>
#include <vector>#include "caffe/layers/relu6_layer.hpp"namespace caffe {template <typename Dtype>
void ReLU6Layer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top) {const Dtype* bottom_data = bottom[0]->cpu_data();Dtype* top_data = top[0]->mutable_cpu_data();const int count = bottom[0]->count();for (int i = 0; i < count; ++i) {top_data[i] = std::min(std::max(bottom_data[i], Dtype(0)), Dtype(6));}
}template <typename Dtype>
void ReLU6Layer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,const vector<bool>& propagate_down,const vector<Blob<Dtype>*>& bottom) {if (propagate_down[0]) {const Dtype* bottom_data = bottom[0]->cpu_data();const Dtype* top_diff = top[0]->cpu_diff();Dtype* bottom_diff = bottom[0]->mutable_cpu_diff();const int count = bottom[0]->count();for (int i = 0; i < count; ++i) {bottom_diff[i] = top_diff[i] * ((bottom_data[i] > 0 && bottom_data[i] < 6));}}
}#ifdef CPU_ONLY
STUB_GPU(ReLU6Layer);
#endifINSTANTIATE_CLASS(ReLU6Layer);
REGISTER_LAYER_CLASS(ReLU6);}  // namespace caffe

3.在blob/ssd/src/caffe/layers文件夹下新建relu6_layer.cu,将

#include <algorithm>
#include <vector>#include "caffe/layers/relu6_layer.hpp"namespace caffe {template <typename Dtype>
__global__ void ReLU6Forward(const int n, const Dtype* in, Dtype* out) {CUDA_KERNEL_LOOP(index, n) {out[index] = in[index] < 0 ? 0: (in[index] > 6 ? 6 : in[index]);}
}template <typename Dtype>
void ReLU6Layer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top) {const Dtype* bottom_data = bottom[0]->gpu_data();Dtype* top_data = top[0]->mutable_gpu_data();const int count = bottom[0]->count();// NOLINT_NEXT_LINE(whitespace/operators)ReLU6Forward<Dtype><<<CAFFE_GET_BLOCKS(count), CAFFE_CUDA_NUM_THREADS>>>(count, bottom_data, top_data);CUDA_POST_KERNEL_CHECK;// << " count: " << count << " bottom_data: "//     << (unsigned long)bottom_data//     << " top_data: " << (unsigned long)top_data//     << " blocks: " << CAFFE_GET_BLOCKS(count)//     << " threads: " << CAFFE_CUDA_NUM_THREADS;
}template <typename Dtype>
__global__ void ReLU6Backward(const int n, const Dtype* in_diff,const Dtype* in_data, Dtype* out_diff) {CUDA_KERNEL_LOOP(index, n) {out_diff[index] = in_diff[index] * ((in_data[index] > 0)&& (in_data[index] < 6));}
}template <typename Dtype>
void ReLU6Layer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,const vector<bool>& propagate_down,const vector<Blob<Dtype>*>& bottom) {if (propagate_down[0]) {const Dtype* bottom_data = bottom[0]->gpu_data();const Dtype* top_diff = top[0]->gpu_diff();Dtype* bottom_diff = bottom[0]->mutable_gpu_diff();const int count = bottom[0]->count();// NOLINT_NEXT_LINE(whitespace/operators)ReLU6Backward<Dtype><<<CAFFE_GET_BLOCKS(count), CAFFE_CUDA_NUM_THREADS>>>(count, top_diff, bottom_data, bottom_diff);CUDA_POST_KERNEL_CHECK;}
}INSTANTIATE_LAYER_GPU_FUNCS(ReLU6Layer);}  // namespace caffe

重新编译ssd。

转载于:https://www.cnblogs.com/crazybird123/p/9602781.html

SSD: ReLU6相关推荐

  1. 22个激活函数,ReLU、RReLU、LeakyReLU、PReLU、Sofplus、ELU、CELU、SELU、GELU、ReLU6、Sigmoid、Tanh、Softsign、Hardtanh等

    转自:https://www.pianshen.com/article/33331174884/ 1.22.Linear常用激活函数 1.22.1.ReLU torch.nn.ReLU() 1.22. ...

  2. 神经网络实现---SSD

    最详细的目标检测SSD算法讲解 深度学习之目标检测 SSD的理解和细节分析 SSD算法--模型结构的详解及Python源码分析 SSD框架详细解读(一) 关于SSD的实现,参考了https://git ...

  3. caffe不支持relu6_SSD: ReLU6

    1.在src\caffe\proto\caffe.proto中搜索message LayerParameter,在optional ReLUParameter relu_param = 123之后添加 ...

  4. 高性能、高适配,SSD 孪生兄弟出场即 C 位

    内容导读 PyTorch 1.9 同步更新了一些库,包括 TorchVision 中新增的 SSD 和 SSDlite 模型,与 SSD 相比,SSDlite 更适用于移动端 APP 开发. SSD ...

  5. 基于深度学习的目标检测DET - SSD

    SSD: Single Shot MultiBox Detector, 是一个end to end 的目标检测识别模型.先小八卦下,它属于google派系,它的作者也是googlenet的作者.该模型 ...

  6. 华为开源自研AI框架昇思MindSpore应用案例:SSD目标检测

    目录 一.环境准备 1.进入ModelArts官网 2.使用CodeLab体验Notebook实例 二.环境准备 三.数据准备与处理 数据采样 数据集创建 四.模型构建 五.损失函数 六.Metric ...

  7. 如何为嵌入式应用选择适当的SSD

    如何为嵌入式应用选择适当的SSD Selecting the right SSD for evolving embedded applications 变革涉及技术的每一个要素,闪存也不例外.价格下跌 ...

  8. Single Shot Multibox Detection (SSD)实战(下)

    Single Shot Multibox Detection (SSD)实战(下) Training 将逐步解释如何训练SSD模型进行目标检测. 2.1. Data Reading and Initi ...

  9. Single Shot Multibox Detection (SSD)实战(上)

    Single Shot Multibox Detection (SSD)实战(上) 介绍了边界框.锚框.多尺度对象检测和数据集.现在,我们将利用这些背景知识构建一个目标检测模型:单次多盒检测(SSD) ...

最新文章

  1. VMware workstation 7.1 安装错误提示1021解决方法
  2. python生成报告_python生成测试报告
  3. Cisco无线AP上联口为trunk时无法注册故障处理
  4. HDU多校5 - 6822 Paperfolding(组合数学)
  5. Qt中消息的机制原理
  6. 初识Matlab遗传算法工具箱 ga
  7. 如何查看 Linux是32位还是64位?
  8. 【Java】indexOf 方法区分大小写
  9. Yarn分布式集群操作系统
  10. LeetCode 刷题隔天忘怎么办?
  11. 题目:求100以内的全部素数,每行输出10个。1不是素数
  12. 查找python矩阵中最大元素_一种快速查找numpy数组中最大N个元素的方法
  13. 点石成金 访客至上的网页设计秘笈 (全一点)
  14. shell脚本IFS的概念
  15. android电视hdmi声音录音,RK3288 android 5.1 HDMI 喇叭同时输出声音
  16. win10系统如何格式化
  17. Windons10安装RDKit
  18. 天使跟我走,世界我都有
  19. FireFox下载时文件名乱码问题解决
  20. 在字符串两侧填充指定字符ljust()与rjust()方法

热门文章

  1. Linux静态库和动态库的设计
  2. python输出进度条 tqdm_python-tqdm进度条
  3. matalotlib(2)
  4. 中webgl解析json_WebGL蒙皮(下)
  5. hdfs复制文件夹_HDFS常用命令
  6. Spark 机器学习中的线性代数库
  7. LeetCode 808. 分汤(动态规划)
  8. LeetCode 734. 句子相似性(哈希)
  9. LeetCode 934. 最短的桥(2次BFS)
  10. LeetCode 914. 卡牌分组(最大公约数)