Caffe源码解析6:Neuron_Layer
转载请注明出处,楼燚(yì)航的blog,http://home.cnblogs.com/louyihang-loves-baiyan/
NeuronLayer,顾名思义这里就是神经元,激活函数的相应层。我们知道在blob进入激活函数之前和之后他的size是不会变的,而且激活值也就是输出 \(y\) 只依赖于相应的输入 \(x\)。在Caffe里面所有的layer的实现都放在src文件夹下的layer文件夹中,基本上很多文章里应用到的layer类型它都有cpu和cuda的实现。
在caffe里面NeuronLayer比较多,在此罗列了一下
- AbsValLayer
- BNLLLayer
- DropoutLayer
- ExpLayer
- LogLayer
- PowerLayer
- ReLULayer
- CuDNNReLULayer
- SigmoidLayer
- CuDNNSigmoidLayer
- TanHLayer
- CuDNNTanHLayer
- ThresholdLayer
- PReLULayer
Caffe里面的Neuron种类比较多方便人们使用,这里我们着重关注几个主要的Neuro_layer
ReLULayer
目前在激活层的函数中使用ReLU是非常普遍的,一般我们在看资料或者讲义中总是提到的是Sigmoid函数,它比Sigmoid有更快的收敛性,因为sigmoid在收敛的时候越靠近目标点收敛的速度会越慢,也是其函数的曲线形状决定的。而ReLULayer则相对收敛更快,具体可以看Krizhevsky 12年的那篇ImageNet CNN文章有更详细的介绍。
其计算的公式是:
\]
如果有负斜率式子变为:
\]
反向传播的公式
\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.
\]
其在cafffe中的forward和backward函数为
template <typename Dtype>
void ReLULayer<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();
Dtype negative_slope = this->layer_param_.relu_param().negative_slope();
for (int i = 0; i < count; ++i) {
top_data[i] = std::max(bottom_data[i], Dtype(0))
+ negative_slope * std::min(bottom_data[i], Dtype(0));
}
}
template <typename Dtype>
void ReLULayer<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();
Dtype negative_slope = this->layer_param_.relu_param().negative_slope();
for (int i = 0; i < count; ++i) {
bottom_diff[i] = top_diff[i] * ((bottom_data[i] > 0)
+ negative_slope * (bottom_data[i] <= 0));
}
}
}
SigmoidLayer
Sigmoid函数,也称为阶跃函数,函数曲线是一个优美的S形。目前使用Sigmoid函数已经不多了,大多使用ReLU来代替,其对应的激活函数为:
\]
其反向传播时
= \frac{\partial E}{\partial y} y (1 - y)\]
其相应的forward和backward的函数为
template <typename Dtype>
void SigmoidLayer<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] = sigmoid(bottom_data[i]);
}
}
template <typename Dtype>
void SigmoidLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down,
const vector<Blob<Dtype>*>& bottom) {
if (propagate_down[0]) {
const Dtype* top_data = top[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) {
const Dtype sigmoid_x = top_data[i];
bottom_diff[i] = top_diff[i] * sigmoid_x * (1. - sigmoid_x);
}
}
}
DropoutLayer
DropoutLayer现在是非常常用的一种网络层,只用在训练阶段,一般用在网络的全连接层中,可以减少网络的过拟合问题。其思想是在训练过程中随机的将一部分输入x之置为0。
\begin{array}{ll}
\frac{x}{1 - p} & \mbox{if } u > p \\
0 & \mbox{otherwise}
\end{array} \right.
\]
其forward_cpu和backward_cpu为:
template <typename Dtype>
void DropoutLayer<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();
unsigned int* mask = rand_vec_.mutable_cpu_data();
const int count = bottom[0]->count();
if (this->phase_ == TRAIN) {
// Create random numbers构造随机数,这里是通过向量掩码来和bottom的数据相乘,scale_是控制undropped的比例
caffe_rng_bernoulli(count, 1. - threshold_, mask);
for (int i = 0; i < count; ++i) {
top_data[i] = bottom_data[i] * mask[i] * scale_;
}
} else {
caffe_copy(bottom[0]->count(), bottom_data, top_data);
}
}
template <typename Dtype>
void DropoutLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down,
const vector<Blob<Dtype>*>& bottom) {
if (propagate_down[0]) {
const Dtype* top_diff = top[0]->cpu_diff();
Dtype* bottom_diff = bottom[0]->mutable_cpu_diff();
if (this->phase_ == TRAIN) {
const unsigned int* mask = rand_vec_.cpu_data();
const int count = bottom[0]->count();
for (int i = 0; i < count; ++i) {
bottom_diff[i] = top_diff[i] * mask[i] * scale_;
}
} else {
caffe_copy(top[0]->count(), top_diff, bottom_diff);
}
}
}
Caffe源码解析6:Neuron_Layer的更多相关文章
- Caffe源码解析7:Pooling_Layer
转载请注明出处,楼燚(yì)航的blog,http://home.cnblogs.com/louyihang-loves-baiyan/ Pooling 层一般在网络中是跟在Conv卷积层之后,做采样 ...
- Caffe源码解析5:Conv_Layer
转载请注明出处,楼燚(yì)航的blog,http://home.cnblogs.com/louyihang-loves-baiyan/ Vision_layer里面主要是包括了一些关于一些视觉上的操 ...
- Caffe源码解析4: Data_layer
转载请注明出处,楼燚(yì)航的blog,http://home.cnblogs.com/louyihang-loves-baiyan/ data_layer应该是网络的最底层,主要是将数据送给blo ...
- Caffe源码解析3:Layer
转载请注明出处,楼燚(yì)航的blog,http://home.cnblogs.com/louyihang-loves-baiyan/ layer这个类可以说是里面最终的一个基本类了,深度网络呢就是 ...
- Caffe源码解析2:SycedMem
转载请注明出处,楼燚(yì)航的blog,http://www.cnblogs.com/louyihang loves baiyan/ 看到SyncedMem就知道,这是在做内存同步的操作.这类个类的 ...
- Caffe源码解析1:Blob
转载请注明出处,楼燚(yì)航的blog,http://www.cnblogs.com/louyihang-loves-baiyan/ 首先看到的是Blob这个类,Blob是作为Caffe中数据流通的 ...
- caffe源码解析
http://blog.csdn.net/lanxuecc/article/details/53186613
- caffe源码阅读
参考网址:https://www.cnblogs.com/louyihang-loves-baiyan/p/5149628.html 1.caffe代码层次熟悉blob,layer,net,solve ...
- 【Caffe】源码解析----caffe.proto (转载)
分析caffe源码,看首先看caffe.proto,是明智的选择.好吧,我不是创造者,只是搬运工. 原文地址:http://blog.csdn.net/qq_16055159/article/deta ...
随机推荐
- SQL语句分组排序,多表关联排序
SQL语句分组排序,多表关联排序总结几种常见的方法: 案例一: 在查询结果中按人数降序排列,若人数相同,则按课程号升序排列? 分析:单个表内的多个字段排序,一般可以直接用逗号分割实现. select ...
- Asp.net 面向接口可扩展框架之数据处理模块及EntityFramework扩展和Dapper扩展(含干货)
接口数据处理模块是什么意思呢?实际上很简单,就是使用面向接口的思想和方式来做数据处理. 还提到EntityFramework和Dapper,EntityFramework和Dapper是.net环境下 ...
- aspx后台传递Json到前台的两种接收方法
第一种:前台接收 dataType: "json", success: function (data) { va ...
- HTML5学习笔记
参考资料:http://www.runoob.com/html/html-tutorial.html 1.html5声明.将此html文档标记为html5文档 <!DOCTYPE html> ...
- 从零开始学Python08作业思路:开发简单的FTP
一,作业要求 开发简单的FTP 1,用户登录 2,上传/下载文件 3,不同用户家目录不同 4,查看当前目录下文件 5,充分使用面向对象 二,程序文件清单 Folder目录:用户上传文件家目录 db目录 ...
- 2分钟在eclipse下使用SpringBoot搭建Spring MVC的WEB项目
1. 首先用eclipse创建一个maven工程, 普通maven工程即可 2. 修改pom如下: <?xml version="1.0" encoding="UT ...
- Class.forName("com.mysql.jdbc.Driver") ;
try { Class.forName("com.mysql.jdbc.Driver") ; } catch(ClassNotFoundException e) { System. ...
- XML序列化和反序列化
上篇总结了下JSON的序列化和反序列化,博园中大牛给了很多牛叉的评论,学习了不少. 不过在上篇中忘了把json序列化和反序列化的另外一种方式写上去了,这里做个简单的补充: Json篇:http://w ...
- angular源码分析:angular中脏活累活的承担者之$interpolate
一.首先抛出两个问题 问题一:在angular中我们绑定数据最基本的方式是用两个大括号将$scope的变量包裹起来,那么如果想将大括号换成其他什么符号,比如换成[{与}],可不可以呢,如果可以在哪里配 ...
- 关于arcgis engine的工作空间(IWorkspace)和选择集(FeatureSelection)
1.通过某个WorkspaceFactoryClass(例如AccessWorkspaceFactoryClass)拿到工作空间工厂接口,这时的OpenFromFile方法可以直接打开mdb类型文件, ...