[Caffe]: 关于dropout的实现细节

Dropout

关于Dropout的博文网上很多,今晚同学问了我关于Dropout具体是怎么实现的,一时答不出来。
然后就查看了下Caffe的源码,代码思路很清晰,很简洁。

思路

前向: 训练时,利用伯努利分布,随机出一个只包含0,1的mask矩阵,然后利用这个mask去对应乘上每个输入,得到的就是Dropout后的结果;测试时,Dropout并不起作用。
后向:训练时,根据mask来求对应梯度;测试时,与无Dropout一致。

参数

message DropoutParameter {
  // dropouot_ratio 即伯努利分布中p的值,源码中根据1-p的概率选取0,使特征失效
  optional float dropout_ratio = 1 [default = 0.5]; // dropout ratio
}

代码

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
    caffe_rng_bernoulli(count, 1. - threshold_, mask); // Important,
    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);
    }
  }
}

反思

Dropout用了这么久,却没有注意到具体是怎么实现的,这是学习上的疏忽。
以后对自己用到的每一种网络层都需要了解原理,明白实现细节。


2017.09.03 记

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值