layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 32
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.0001
}
bias_filler {
type: "constant"
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
1.1 xavier初始化 (归一化初始化)
当激活函数是sigmoid时,使用标准初始化往往性能比较差,收敛较慢且容易陷入局部最优。
“xavier”初始化是一种有效的神经网络舒适化方法,来自于2010年 Xavier Glorot和Yoshua Bengio两人的一篇论文<< Understanding the difficulty of training deep feedforward neural networks >>,配合tanh等函数能够获得比较好的效果。
主要思想是:尽可能保证前向传播和反向传播时每一层的方差尽量相等
推导前提:激活函数是线性的 ReLU和PReLU不满足这一条件
定义参数所在层的输入维度为n,输出维度为m,则参数讲均匀分布在
W∼U[−6n+m−−−−−−√,6n+m−−−−−−√]
Caffe中的实现:
template <typename Dtype>
class XavierFiller : public Filler<Dtype> {
public:
explicit XavierFiller(const FillerParameter& param)
: Filler<Dtype>(param) {}
virtual void Fill(Blob<Dtype>* blob) {
CHECK(blob->count());
int fan_in = blob->count() / blob->num();
int fan_out = blob->count() / blob->channels();
Dtype n = fan_in;
if (this->filler_param_.variance_norm() ==
FillerParameter_VarianceNorm_AVERAGE) {
n = (fan_in + fan_out) / Dtype(2);
} else if (this->filler_param_.variance_norm() ==
FillerParameter_VarianceNorm_FAN_OUT) {
n = fan_out;
}
Dtype scale = sqrt(Dtype(3) / n);
caffe_rng_uniform<Dtype>(blob->count(), -scale, scale,
blob->mutable_cpu_data());
CHECK_EQ(this->filler_param_.sparse(), -1)
<< "Sparsity not supported by this Filler.";
}
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
caffe中提供了3种方式:
(1)默认情况,只考虑输入
W∼U[−3n−−√,3n−−√]
(2)FillerParameter_VarianceNorm_FAN_OUT
W∼U[−3m−−−√,3m−−−√]
(3)FillerParameter_VarianceNorm_AVERAGE
W∼U[−6n+m−−−−−−√,6n+m−−−−−−√]
1.2 MSRA初始化
来自于MSRA研究员何恺明2015年论文
Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification
传统的固定方差的高斯分布初始化,在网络变深时使得模型很难收敛。
改善的方法有用预训练的模型去初始化网络的部分层;xavier也是不错的初始化方法,但是它需要满足激活函数线性的条件。在MSRA初始化中,考虑了ReLU和PReLU。
MSRA初始化的权重分布是一个均值为0,均值为
2n
的高斯分布,初始化满足下式
W∼G[0,2n−−√]
Caffe中的实现:
template <typename Dtype>
class MSRAFiller : public Filler<Dtype> {
public:
explicit MSRAFiller(const FillerParameter& param)
: Filler<Dtype>(param) {}
virtual void Fill(Blob<Dtype>* blob) {
CHECK(blob->count());
int fan_in = blob->count() / blob->num();
int fan_out = blob->count() / blob->channels();
Dtype n = fan_in;
if (this->filler_param_.variance_norm() ==
FillerParameter_VarianceNorm_AVERAGE) {
n = (fan_in + fan_out) / Dtype(2);
} else if (this->filler_param_.variance_norm() ==
FillerParameter_VarianceNorm_FAN_OUT) {
n = fan_out;
}
Dtype std = sqrt(Dtype(2) / n);
caffe_rng_gaussian<Dtype>(blob->count(), Dtype(0), std,
blob->mutable_cpu_data());
CHECK_EQ(this->filler_param_.sparse(), -1)
<< "Sparsity not supported by this Filler.";
}
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
同样有3种方案:
(1)默认情况下,n是输入层的维度
(2)n取输出层的维度
(3)n取输入和输出层的均值
1.3 其他初始化
(1)“constant”: 常量初始化
(2)“gaussian”: 固定方差高斯分布初始化
(3)“positive_utiball”:每个值为在[0,1]之间,对于每个
i
:
∀i∑jxij=1
(4)“uniform”: 均匀分布初始化
(5)“bilinear”: 双线性初始化,通常用于反卷积核