layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1 #lr_mult: 學習率的係數,最終的學習率是這個數乘以solver.prototxt配置文件中的base_lr。如果有兩個lr_mult, 則第一個表示權值的學習率,第二個表示偏置項的學習率。一般偏置項的學習率是權值學習率的兩倍。
}
param {
lr_mult: 2 #偏置項的學習率
}
convolution_param {
num_output: 20 #卷積核(filter)的個數
kernel_size: 5 #卷積核的大小
stride: 1 #卷積核的步長,默認為1
pad: 0 #擴充邊緣,默認為0,不擴充
group: 2 #默認為0(通達卷積的實現方式)
weight_filler {
type: "xavier" #權值初始化。 默認為「constant",值全為0,很多時候我們用"xavier"算法來進行初始化,也可以設置為」gaussian"
}
bias_filler {
type: "constant" #偏置項的初始化。一般設置為"constant",值全為0
}
}
}
卷積配置參數意義卷積計算公式
卷積計算過程圖示
上圖取自CS231n,展示了三維卷積的計算過程,輸入數據的三個維度,對應第二個卷積核生成了第二個Feature Map
Feature Map大小計算
如上圖所示,輸出Feature Map大小計算公式如下:
權值與偏置的初始化方法caffe源文件filler.hpp中提供了7種權值初始化的方法。在計算機視覺的領域中權重參數的初始化常用xavier,偏置的初始化常用constant,並且初始化為0。
Filler<Dtype>* GetFiller(const FillerParameter& param) {
const std::string& type = param.type();
if (type == "constant") {
return new ConstantFiller<Dtype>(param);
} else if (type == "gaussian") {
return new GaussianFiller<Dtype>(param);
} else if (type == "positive_unitball") {
return new PositiveUnitballFiller<Dtype>(param);
} else if (type == "uniform") {
return new UniformFiller<Dtype>(param);
} else if (type == "xavier") {
return new XavierFiller<Dtype>(param);
} else if (type == "msra") {
return new MSRAFiller<Dtype>(param);
} else if (type == "bilinear") {
return new BilinearFiller<Dtype>(param);
} else {
CHECK(false) << "Unknown filler name: " << param.type();
}
return (Filler<Dtype>*)(NULL);
}
結合 .prototxt 文件中的 FillerParameter來看看怎麼用
message FillerParameter {
// The filler type.
optional string type = 1 [default = 'constant'];
optional float value = 2 [default = 0]; // the value in constant filler
optional float min = 3 [default = 0]; // the min value in uniform filler
optional float max = 4 [default = 1]; // the max value in uniform filler
optional float mean = 5 [default = 0]; // the mean value in Gaussian filler
optional float std = 6 [default = 1]; // the std value in Gaussian filler
// The expected number of non-zero output weights for a given input in
// Gaussian filler -- the default -1 means don't perform sparsification.
optional int32 sparse = 7 [default = -1];
// Normalize the filler variance by fan_in, fan_out, or their average.
// Applies to 'xavier' and 'msra' fillers.
enum VarianceNorm {
FAN_IN = 0;
FAN_OUT = 1;
AVERAGE = 2;
}
optional VarianceNorm variance_norm = 8 [default = FAN_IN];
}
optional string type = 1 [default = 'constant'];
optional float value = 2 [default = 0]; // the value in constant filler
caffe中默認的初始化方式,它就是把權值或著偏置初始化為一個常數,具體是什麼常數,自己可以定義。它的值等於上面的.prototxt文件中的 value的值,默認為0。
// Normalize the filler variance by fan_in, fan_out, or their average.
// Applies to 'xavier' and 'msra' fillers.
enum VarianceNorm {
FAN_IN = 0;
FAN_OUT = 1;
AVERAGE = 2;
}
optional VarianceNorm variance_norm = 8 [default = FAN_IN];
xavier是和relu完美配合的初始化。xavier誕生時並沒有用relu做例子,但是實際效果中xavier還是和relu很搭配的。
xavier初始化定義為:定義參數所在層的輸入維度為n,輸出維度為m,那麼參數將以均勻分布的方式在的範圍內進行初始化。具體的原理可以參靠CNN數值——xavier
它的思想就是讓一個神經元的輸入權重的(當反向傳播時,就變為輸出了)的方差等於:1 / 輸入的個數;這樣做的目的就是可以讓信息可以在網絡中均勻的分布一下。
對於權值的分布:是一個讓均值為0,方差為1 / 輸入的個數 的均勻分布。
如果我們更注重前向傳播的話,我們可以選擇 fan_in,即正向傳播的輸入個數;如果更注重後向傳播的話,我們選擇 fan_out, 因為,等著反向傳播的時候,fan_out就是神經元的輸入個數;如果兩者都考慮的話,那就選 average = (fan_in + fan_out) /2