《深度学习:卷积神经网络从入门到精通》——3.4 LeNet的Caffe代码实现及说明
3.4 LeNet的Caffe代码实现及说明
LeNet是Caffe安装包自带的一个例子模型。在安装好Caffe包后,其Caffe代码可以在子文件夹examples下的mnist案例中找到。
LeNet的Caffe实现代码共有三个文件:网络结构文件lenet_train_test.prototxt、求解器配置文件lenet_solver.prototxt和伪概率计算文件lenet.prototxt。其中,lenet_train_test.prototxt用来定义网络的训练数据目录、测试数据目录和网络结构细节,包括每个卷积层的卷积核个数、大小、步长,每个下采样层的类型、窗口大小、步长,全连接层的节点数目、激活函数的类型、损失函数类型,以及层与层之间的关系等。lenet_solver.prototxt用来给求解器配置训练和测试网络的有关超参数,包括学习率的大小、训练的迭代次数及优化方法、使用的计算模式(CPU或GPU)等。lenet.prototxt用来在模型训练好后对未知样本计算分类伪概率。下面分别对这三个文件的具体内容进行描述。
1.网络结构文件lenet_train_test.prototxt的内容描述
该文件主要用来定义LeNet的网络结构,有关参数及其含义见表3.2。
表3.2 网络结构文件lenet_train_test.prototxt的参数及其含义
下面是具体的代码。
name: "LeNet"
layer {
name: "CaseName" # 表示案例名称
type: "Data" # 表示该层用于数据输入
top: "data"
top: "label"
data_param {
source: "TrainSetDir" # 表示训练集目录
backend: LEVELDB # 一种Caffe数据类型
batch_size: Train_batch_size # 表示训练集迷你块的大小
}
transform_param {
scale: 0.00390625 # 将图像灰度值除以256归一化,把输入数据变换到
[0,1]区间
}
include: { phase: TRAIN }
}
layer {
name: "CaseName"
type: "Data"
top: "data"
top: "label"
data_param {
source: "TestSetDir" # 表示测试集目录
backend: LEVELDB
batch_size: Test_batch_size # 表示测试集迷你块的大小
}
transform_param {
scale: 0.00390625
}
include: { phase: TEST }
}
layer {
name: "conv1"
type: "Convolution" # 表示该层为卷积层
bottom: "data"
top: "conv1"
param {
lr_mult: 1 # 权重学习率倍数,用来放大初始学习率base_lr
}
param {
lr_mult: 2 #偏置学习率倍数,把初始学习率base_lr放大2倍
}
convolution_param {
num_output: conv1_num_output # 表示卷积面的个数
kernel_size: conv1_kernel_size # 表示卷积核的大小
stride: conv1_stride # 表示卷积核的移动步长
weight_filler {
type: "xavier" # 使用xavier方法初始化权值,也可以设置为”gaussian”或其他方法
}
bias_filler {
type: "constant" # 表示把偏置初始化为常数0,若要初始化为0.1,可用语句 value: 0.1
}
}
}
layer {
name: "relu1"
type: "Insanity" # 把该层的激活函数设置为Insanity类型,即一种randomized LReLU
bottom: "conv1"
top: "conv1"
}
layer {
name: "pool1"
type: "Pooling" # 池化层
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX # 把池化类型选为最大池化,还可选择平均池化
kernel_size: pool1_kernel_size # 表示池化窗的大小
stride: pool1_stride # 表示池化窗的移动步长
}
}
layer {
name: "conv2"
type: "Convolution" # 卷积层
bottom: "pool1"
top: "conv2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: conv2_num_output # 表示卷积面的个数
kernel_size: conv2_kernel_size # 表示卷积核的大小
stride: conv2_stride # 表示卷积核的移动步长
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu2"
type: "Insanity"
bottom: "conv2"
top: "conv2"
}
layer {
name: "pool2"
type: "Pooling" # 池化层
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: pool2_kernel_size # 表示池化窗的大小
stride: pool2_stride # 表示池化窗的移动步长
}
}
layer {
name: "ip1"
type: "InnerProduct" # 全连接层,在这里也称为内积
bottom: "pool2"
top: "ip1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: ip1_num_output # 表示全连接层的节点数
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu3"
type: "Insanity"
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: ip2_num_output # 全连接层的节点数
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "accuracy"
type: "Accuracy" # 该层只出现在测试阶段,用于计算准确率
bottom: "ip2" # 计算准确率要用到全连接层ip2
bottom: "label" # 计算准确率还要用到标签层
top: "accuracy"
include {
phase: TEST
}
}
layer {
name: "loss"
type: "SoftmaxWithLoss" # 带损失的软最大输出层,采用退化交叉熵损失函数
bottom: "ip2" # 计算损失要用到全连接层ip2
bottom: "label" # 计算损失还要用到标签层
top: "loss"
}
2.求解器配置文件lenet_solver.prototxt的内容描述
该文件主要用于配置对LeNet模型进行训练和测试的有关参数,其含义在表3.3中给出了详细描述。文件对这些参数的一种具体配置情况如方框3.1所示。
表3.3 求解器配置文件lenet_solver.prototxt的超参数及其含义
方框3.1 求解器的一种具体超参数配置
net: "C:/Caffe/caffe-windows-master/examples/mnist/lenet_train_test.prototxt"
test_iter: 100
test_interval: 500 # 每训练500次,测试1次
base_lr: 0.01
momentum: 0.9
weight_decay: 0.0005
lr_policy: "inv" # 把学习率的下降策略选为inv类型,还可以选为fixed、step和exp等类型
gamma: 0.0001
power: 0.75
display: 100 # 每训练100次显示1次中间结果
max_iter: 10000 # 最多训练10?000次
snapshot: 5000 # 每训练5000次保存1次结果,命名为_iter_5000.caffemodel等
snapshot_prefix: "C:/Caffe/caffe-windows-master/examples/mnist/lenet"
type: “SGD” # 选用随机梯度下降法训练,还可选AdaDelta、AdaGrad、Adam、
# Nesterov、RMSProp
solver_mode: GPU
3.伪概率计算文件lenet.prototxt的内容描述
该文件主要用来在模型训练好后对未知样本计算分类伪概率,有关参数及其含义见表3.4。
表3.4 伪概率计算文件lenet.prototxt的参数及含义
下面是具体的代码。
name: "LeNet"
layer {
name: "data"
type: "Input"
top: "data"
input_param { shape: { dim: dim1 dim: dim2 dim: dim3 dim: dim4 } }
?# 表示输入层大小
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: conv1_num_output # 表示卷积面的个数
kernel_size: conv1_kernel_size # 表示卷积核的大小
stride: conv1_stride # 表示卷积核的移动步长
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: pool1_kernel_size # 表示池化窗的大小
stride: pool1_stride # 表示池化窗的移动步长
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: conv2_num_output
kernel_size: conv2_kernel_size
stride: conv2_stride
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: pool2_kernel_size
stride: pool2_stride
}
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool2"
top: "ip1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: ip1_num_output # 表示全连层的节点数
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu1"
type: "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: ip2_num_output # ip2_num_output表示全连层的节点数
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "prob"
type: "Softmax"
bottom: "ip2"
top: "prob"
}
最后,需要指出,这个伪概率计算文件lenet.prototxt是Caffe安装包自带的,但所定义的网络结构与网络结构文件lenet_train_test.prototxt并不完全一致。因此,如果模型是基于lenet_train_test.prototxt训练的,还必须对lenet.prototxt文件进行适当修改,使得两者的模型结构一致,才能对未知样本正确计算伪概率。
- 点赞
- 收藏
- 关注作者
评论(0)