深度学习剖根问底:weight decay等参数的合理解释

1:weight decay

主要为了加入正则项,防止过拟合,过拟合的导致权值会变化;

2:权值的初始化为啥使用较小的数值?

因为权值过大的话,对于sigmoid的来说,容易导致数值在饱和区,反向传播导致梯度基本的不跟新;weight decay是放在正则项(regularization)前面的一个系数正则项一般指示模型的复杂度,所以weight decay的作用是调节模型复杂度对损失函数的影响,若weight decay很大,则复杂的模型损失函数的值也就大。

3:RMSProp方法是在限制了权值的波动范围,momentum是加速了梯度下降的方向,adam方法是以上两种方法的组合;

4:防止过拟合的方法

a: L2正则化,对权值进行约束; b: Dropout,随机的丢失一些神经元; c:数据增强,增加训练样本;d:增加BN;

5:梯度消失和梯度爆炸

a:梯度消失,权值的不断相乘,如果权值初始化大于1,权值的指数次方,导致梯度不断的增大;如果权值梯度小于1,梯度不断的变小,随着层数的加深,梯度逐渐的消失,经过激活函数,会不断变化;

6:L2正则化

weight_decay 是乘在正则项的前面,控制正则化项在损失函数中所占权重的;

7:Dropout的理解

Dropout的概率p,其实就是让它的激活值以概率p变为0, 舍弃;

template <typename Dtype>
void DropoutLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  NeuronLayer<Dtype>::LayerSetUp(bottom, top);
  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_);
}

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_.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
    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);
    }
  }

猜你喜欢

转载自blog.csdn.net/wfei101/article/details/80633934