caffe详解之卷积层
从零开始,一步一步学习caffe的使用,期间贯穿深度学习和调参的相关知识!
卷积层参数说明
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];
}
constant初始化
optional string type = 1 [default = 'constant'];
optional float value = 2 [default = 0]; // the value in constant filler
caffe中默认的初始化方式,它就是把权值或着偏置初始化为一个常数,具体是什么常数,自己可以定义。它的值等于上面的.prototxt文件中的 value
的值,默认为0
。
xavier初始化
// 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 (https://zhuanlan.zhihu.com/p/22028079)
它的思想就是让一个神经元的输入权重的(当反向传播时,就变为输出了)的方差等于:1 / 输入的个数;这样做的目的就是可以让信息可以在网络中均匀的分布一下。
对于权值的分布:是一个让均值为0,方差为 1 / 输入的个数
的均匀分布。
如果我们更注重前向传播的话,我们可以选择 fan_in
,即正向传播的输入个数;如果更注重后向传播的话,我们选择 fan_out
, 因为,等着反向传播的时候,fan_out
就是神经元的输入个数;如果两者都考虑的话,那就选 average = (fan_in + fan_out) /2
参考
caffe中权值初始化方法 CNN数值——xavier
- OpenCV3.1.0级联分类器训练与使用
- 图像处理之理解Homography matrix(单应性矩阵)
- OpenCV中图像直方图与应用
- OpenCV中图像修复技术介绍与演示
- 44个Java代码性能优化总结
- LDA(Linear Discriminant Analysis)算法介绍
- Express.js 4,Node.js,MongoDB REST API 简易教程
- 基于梯度下降算法求解线性回归
- 彩色图像高斯反向投影
- OpenCV中直方图反向投影算法详解与实现
- 基于一维级联快速膨胀与腐蚀算法
- mac下利用Breakpad的dump文件进行调试
- OpenCV3.2集成Android Studio2.2开发配置
- laravel中使用gulp打包发布前端部分
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法