经典模型之Lenet
模型背景
1985年,Rumelhart和Hinton等人提出了后向传播(BackPropagation,BP)算法[1](也有说1986年的,指的是他们另一篇paper:Learningrepresentations by back-propagating errors),使得神经网络的训练变得简单可行,这篇文章在GoogleScholar上的引用次数达到了19000多次,目前还是比Cortes和Vapnic的Support-Vector Networks稍落后一点,不过以Deep Learning最近的发展劲头来看,超越指日可待。
几年后,LeCun利用BP算法来训练多层神经网络用于识别手写邮政编码,这个工作就是CNN的开山之作,如图2所示,多处用到了5*5的卷积核,但在这篇文章中LeCun只是说把5*5的相邻区域作为感受野,并未提及卷积或卷积神经网络。
容易看出,Lenet网络结构由1个数据层、3个卷积层、2个池化层、2个全连接层和、1个SoftmaxLoss层和1个输出层组成。
solver.prototxt
# The train/test net protocol buffer definition
net: "examples/mnist/lenet_train_test.prototxt"
# test_iter specifies how many forward passes the test should carry out.
# In the case of MNIST, we have test batch size 100 and 100 test iterations,
# covering the full 10,000 testing images.
test_iter: 100
# Carry out testing every 500 training iterations.
test_interval: 500
# The base learning rate, momentum and the weight decay of the network.
base_lr: 0.01
momentum: 0.9
weight_decay: 0.0005
# The learning rate policy
lr_policy: "inv"
gamma: 0.0001
power: 0.75
# Display every 100 iterations
display: 100
# The maximum number of iterations
max_iter: 10000
# snapshot intermediate results
snapshot: 5000
snapshot_prefix: "examples/mnist/lenet"
# solver mode: CPU or GPU
solver_mode: CPU
~
参数说明
- net
训练/测试网络结构
- test_iter
表示测试的次数;比如,你的test阶段的batchsize=100,而你的测试数据为10000张图片,则你的测试次数为10000/100=100次;即,你的test_iter=100;
- test_interval
表示你的网络训练多少次才进行一次训练
- base_lr
表示基础学习率,在参数梯度下降优化的过程中,学习率会有所调整,而调整的策略就可通过lr_policy这个参数进行设置;
- momentum
表示上一次梯度更新的权重
- weight_decay
表示权重衰减,用于防止过拟合
- lr_policy
–>fixed:保持base_lr不变;
–>step: 如果设置为step,则还需要设置一个stepsize, 返回 base_lr * gamma ^ (floor(iter / stepsize)),其中iter 表示当前的迭代次数;
–>exp: 返回base_lr * gamma ^ iter, iter为当前迭代次数;
–>inv:如果设置为inv,还需要设置一个power, 返回base_lr * (1 + gamma * iter) ^ (- power)
–>multistep: 如果设置为multistep,则还需要设置一个stepvalue。这个参数和step很相似,step是均匀等间隔变化,而mult-step则是根据stepvalue值变化
–>poly: 学习率进行多项式误差, 返回 base_lr (1 - iter/max_iter) ^ (power)
–>sigmoid:学习率进行sigmod衰减,返回 base_lr ( 1/(1 + exp(-gamma * (iter - stepsize))))
- gamma
和lr_policy有关
- power
和lr_policy有关
- display
每隔多少次训练显示结果
- max_iter
最大迭代次数
- snapshot
保存模型间隔
- snapshot_prefix
保存模型的前缀
- solver_mode
是否使用GPU
train.prototxt
name: "LeNet"
layer {
name: "mnist"
type: "Data" // 数据层
top: "data"
top: "label"
include {
phase: TRAIN
}
transform_param {
scale: 0.00390625 // 归一化,1/256
}
data_param {
source: "examples/mnist/mnist_train_lmdb"
batch_size: 64 // 一次处理图片数目
backend: LMDB // LMDB格式,也可以为图片格式
}
}
layer {
name: "mnist"
type: "Data"
top: "data"
top: "label"
include {
phase: TEST
}
transform_param {
scale: 0.00390625
}
data_param {
source: "examples/mnist/mnist_test_lmdb"
batch_size: 100
backend: LMDB
}
}
layer {
name: "conv1"
type: "Convolution" // 卷积层
bottom: "data"
top: "conv1"
param {
lr_mult: 1 // weight学习率,和solver中的base_lr关联
}
param {
lr_mult: 2 // bias学习率,一般为weight学习率系数的两倍
}
convolution_param {
num_output: 20 // 通道数,新的通道数,优化时经常会减小通道数
kernel_size: 5 // 卷积核大小
stride: 1 // 步长
weight_filler { // 权值初始化,xavier/guassion/constant
type: "xavier" // 可以理解为一种均匀分布,跟输入的维度有关
}
bias_filler { // 偏置初始化
type: "constant" // 全为0
}
}
}
layer {
name: "pool1"
type: "Pooling" // 池化层
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX // 最大化方法,也可以取均值/最小化
kernel_size: 2 // 卷积核大小,起缩放效果
stride: 2 // 步长
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 50
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "ip1"
type: "InnerProduct" // 全连接层,类似卷积层
bottom: "pool2"
top: "ip1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 500
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu1"
type: "ReLU" // Relu层,激活函数
bottom: "ip1"
top: "ip1"
}
layer {
name: "ip2"
type: "InnerProduct" // 全连接层
bottom: "ip1"
top: "ip2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 10 // 分类数
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "accuracy"
type: "Accuracy" // Accuracy层,测试阶段查看训练精度
bottom: "ip2"
bottom: "label"
top: "accuracy"
include {
phase: TEST
}
}
layer {
name: "loss"
type: "SoftmaxWithLoss" // Softmax层,分类作用
bottom: "ip2"
bottom: "label"
top: "loss"
}
参数说明
卷积层Convolution
- lr_mult
学习率的系数,最终的学习率是这个数乘以solver.prototxt配置文件中的base_lr。如果有两个lr_mult, 则第一个表示权值的学习率,第二个表示偏置项的学习率。一般偏置项的学习率是权值学习率的两倍。
- num_output
卷积核(filter)的个数
- kernel_size
卷积核的大小。如果卷积核的长和宽不等,需要用kernel_h和kernel_w分别设定
- stride
卷积核的步长,默认为1。也可以用stride_h和stride_w来设置。
- weight_filler
权值初始化。 默认为“constant”,值全为0,很多时候我们用”xavier”算法来进行初始化,也可以设置为”gaussian”
- bias_filler
偏置项的初始化。一般设置为”constant”,值全为0。
池化层Pooling
- kernel_size
必须设置的参数。池化的核大小。也可以用kernel_h和kernel_w分别设定。
- pool
池化方法,默认为MAX。目前可用的方法有MAX, AVE, 或STOCHASTIC
- stride
池化的步长,默认为1。一般我们设置为2,即不重叠。也可以用stride_h和stride_w来设置。
全连接层InnerProduct
参数同卷积层
Relu层
Accuracy层
SoftmaxWithLoss层