Caffe源码解读:dropout_layer的正向传播和反向传播
来源:互联网 发布:mysql主键有什么用 编辑:程序博客网 时间:2024/05/18 21:39
原理:
参数:1,神经元被drop out的概率p,被激活的概率为1-p
2,scale_train_标志位(train过程中被激活的神经元是否乘 1/1-p)
train过程:
前向传播过程中每个神经元以1-p的概率被激活
被激活的神经元根据scale_train_标志来确定是否变大1/1-p倍
test过程
若scale_train_为1,不进行任何处理
若scale_train_为0,使用“均值网络“,每个神经元的激活值乘(1-p),即缩小
Caffe源码如下:
template <typename Dtype>void DropoutLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { NeuronLayer<Dtype>::LayerSetUp(bottom, top); //读dropout_ratio参数 //每个神经元被激活的概率为1-threshold_ threshold_ = this->layer_param_.dropout_param().dropout_ratio(); DCHECK(threshold_ > 0.); DCHECK(threshold_ < 1.); scale_ = 1. / (1. - threshold_); uint_thres_ = static_cast<unsigned int>(UINT_MAX * threshold_); scale_train_ = this->layer_param_.dropout_param().scale_train();}template <typename Dtype>void DropoutLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { NeuronLayer<Dtype>::Reshape(bottom, top); // Set up the cache for random number generation // ReshapeLike does not work because rand_vec_ is of Dtype uint // rand_vec_的大小就是bottom[0]的大小 rand_vec_.Reshape(bottom[0]->shape());}
//前向传播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 // 生成bool随机数,激活神经元所在位置的mask值为1,其余为0 caffe_rng_bernoulli(count, 1. - threshold_, mask);//训练过程中的激活值是否乘scale//关系到测试过程中是否使用“均值网络” if (scale_train_) { for (int i = 0; i < count; ++i) { top_data[i] = bottom_data[i] * mask[i] * scale_; } } else { for (int i = 0; i < count; ++i) { top_data[i] = bottom_data[i] * mask[i]; } } } else {//测试阶段 // 如果scale_train_为1,训练过程中激活神经元的输出乘scale // 测试过程中,神经元的输出就不用按比例减小了 caffe_copy(bottom[0]->count(), bottom_data, top_data);// 如果scale_train_为0,即训练过程中神经元的输出没有乘scale// 那么测试过程中,神经元的输出除scale if (!scale_train_) { caffe_scal<Dtype>(count, 1. / scale_, 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(); if (scale_train_) { for (int i = 0; i < count; ++i) { bottom_diff[i] = top_diff[i] * mask[i] * scale_; } } else { for (int i = 0; i < count; ++i) { bottom_diff[i] = top_diff[i] * mask[i]; } } } else {/*反向传播不考虑dropout的情况,直接拷贝数据*/ caffe_copy(top[0]->count(), top_diff, bottom_diff); if (!scale_train_) { caffe_scal<Dtype>(top[0]->count(), 1. / scale_, bottom_diff); } } }}
0 0
- Caffe源码解读:dropout_layer的正向传播和反向传播
- Caffe源码解读:relu_layer前向传播和反向传播
- Caffe源码解读: SoftmaxLayer的前向与反向传播
- Caffe源码解读: Softmax_loss_Layer的前向与反向传播
- Caffe源码解读:conv_layer的前向传播与反向传播
- Caffe源码解读:pooling_layer的前向传播与反向传播
- 对正向传播、反向传播和精度检查的理解
- caffe源码 池化层 反向传播
- batch normalization 正向传播与反向传播
- 神经网络正向传播与反向传播
- caffe学习笔记3.2--前向传播和反向传播
- 深度学习之caffe 前向传播和反向传播
- caffe学习笔记3.2--前向传播和反向传播
- 神经网络正向反向传播算法
- (Caffe,LeNet)反向传播
- caffe 源码学习(4)_反向传播权重更新
- 神经网络的反向传播
- (Caffe,LeNet)反向传播(六)
- php谷歌翻译
- 基于Python的select方式的聊天室应用实例
- Android开发学习笔记:浅谈WebView
- linux下elasticsearch 安装、配置及示例
- bootstrap select2默认选中后台传过来的值
- Caffe源码解读:dropout_layer的正向传播和反向传播
- 使用RTMPdump(libRTMP)直播来自v4l2的摄像头数据
- mysql-sql-select
- equals,==,hashcode
- Java中的泛型类,泛型方法,泛型接口
- MDK debug时error 57:illegal address (0x08000000)解决办法
- (转载)Twain 学习纪录
- 深度学习基础
- [Language]Python跳转控制--条件与循环