SSD: ReLU6
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相关推荐
- 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. ...
- 神经网络实现---SSD
最详细的目标检测SSD算法讲解 深度学习之目标检测 SSD的理解和细节分析 SSD算法--模型结构的详解及Python源码分析 SSD框架详细解读(一) 关于SSD的实现,参考了https://git ...
- caffe不支持relu6_SSD: ReLU6
1.在src\caffe\proto\caffe.proto中搜索message LayerParameter,在optional ReLUParameter relu_param = 123之后添加 ...
- 高性能、高适配,SSD 孪生兄弟出场即 C 位
内容导读 PyTorch 1.9 同步更新了一些库,包括 TorchVision 中新增的 SSD 和 SSDlite 模型,与 SSD 相比,SSDlite 更适用于移动端 APP 开发. SSD ...
- 基于深度学习的目标检测DET - SSD
SSD: Single Shot MultiBox Detector, 是一个end to end 的目标检测识别模型.先小八卦下,它属于google派系,它的作者也是googlenet的作者.该模型 ...
- 华为开源自研AI框架昇思MindSpore应用案例:SSD目标检测
目录 一.环境准备 1.进入ModelArts官网 2.使用CodeLab体验Notebook实例 二.环境准备 三.数据准备与处理 数据采样 数据集创建 四.模型构建 五.损失函数 六.Metric ...
- 如何为嵌入式应用选择适当的SSD
如何为嵌入式应用选择适当的SSD Selecting the right SSD for evolving embedded applications 变革涉及技术的每一个要素,闪存也不例外.价格下跌 ...
- Single Shot Multibox Detection (SSD)实战(下)
Single Shot Multibox Detection (SSD)实战(下) Training 将逐步解释如何训练SSD模型进行目标检测. 2.1. Data Reading and Initi ...
- Single Shot Multibox Detection (SSD)实战(上)
Single Shot Multibox Detection (SSD)实战(上) 介绍了边界框.锚框.多尺度对象检测和数据集.现在,我们将利用这些背景知识构建一个目标检测模型:单次多盒检测(SSD) ...
最新文章
- VMware workstation 7.1 安装错误提示1021解决方法
- python生成报告_python生成测试报告
- Cisco无线AP上联口为trunk时无法注册故障处理
- HDU多校5 - 6822 Paperfolding(组合数学)
- Qt中消息的机制原理
- 初识Matlab遗传算法工具箱 ga
- 如何查看 Linux是32位还是64位?
- 【Java】indexOf 方法区分大小写
- Yarn分布式集群操作系统
- LeetCode 刷题隔天忘怎么办?
- 题目:求100以内的全部素数,每行输出10个。1不是素数
- 查找python矩阵中最大元素_一种快速查找numpy数组中最大N个元素的方法
- 点石成金 访客至上的网页设计秘笈 (全一点)
- shell脚本IFS的概念
- android电视hdmi声音录音,RK3288 android 5.1 HDMI 喇叭同时输出声音
- win10系统如何格式化
- Windons10安装RDKit
- 天使跟我走,世界我都有
- FireFox下载时文件名乱码问题解决
- 在字符串两侧填充指定字符ljust()与rjust()方法