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