利用Caffe进行深度神经网络训练第一步需要搞懂几个重要文件:
solver.prototxt
train_val.prototxt
train.sh
solver.prototxt
solver这个文件主要存放模型训练所用到的一些超参数:
net := 指定待训练模型结构文件,即train_val.prototxt
test_interval := 测试间隔,即每隔多少次迭代进行一次测试
test_initialization := 指定是否进行初始测试,即模型未进行训练时的测试
test_iteration := 指定测试时进行的迭代次数
base_lr := 指定基本学习率
lr_policy := 学习率变更策略,这里有介绍,可供参考
gamma := 学习率变更策略需要用到的参数
power := 同上
stepsize := 学习率变更策略Step的变更步长(固定步长)
stepvalue := 学习率变更策略Multistep的变更步长(可变步长)
max_iter := 模型训练的最大迭代次数
momentum := 动量,这是优化策略(Adam, SGD, … )用到的参数
momentum2 := 优化策略Adam用到的参数
weight_decay := 权重衰减率
clip_gradients := 固定梯度范围
display := 每隔几次迭代显示一次结果
snapshot := 快照,每隔几次保存一次模型参数
snapshot_prefix := 保存模型文件的前缀,可以是路径
type := solver优化策略,即SGD、Adam、AdaGRAD、RMSProp、NESTROVE、ADADELTA等
solver_mode := 指定训练模式,即GPU/CPU
debug_info := 指定是否打印调试信息,这里有对启用该功能的输出作介绍
device_id := 指定设备号(使用GPU模式),默认为0
用户根据自己的情况进行相应设置,黑体参数为必须指定的,其余参数为可选(根据情况选择)!
train_val.prototxt
train_val文件是用来存放模型结构的地方,模型的结构主要以layer为单位来构建。下面我们以LeNet为例介绍网络层的基本组成:
name: "LeNet"
layer {
name: "mnist" #网络层名称
type: "Data" #网络层类型,数据层
top: "data" #这一层的输出,数据
top: "label" #这一层的输出,标签
include { phase: TRAIN } #TRAIN:=用于训练,TEST:=用于测试
transform_param { scale: 0.00390625 } #对数据进行scale
data_param { #数据层配置
source: "examples/mnist/mnist_train_lmdb" #数据存放路径
batch_size: 64 #指定batch大小
backend: LMDB #指定数据库格式,LMDB/LevelDB
}
}
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{name:"conv1_w" lr_mult:1 decay_mult:1} #卷积层参数w的名称,学习率和衰减率(相对于base_lr和weight_decay的倍数)
param{name:"conv1_b" lr_mult:2 decay_mult:0} #卷积层参数b的名称,学习率和衰减率
convolution_param{
num_output:20 #卷积层输出的feature map数量
kernel_size:5 #卷积层的大小
pad:0 #卷积层的填充大小
stride:1 #进行卷积的步长
weight_filler{type:"xavier" } #参数w的初始话策略
weight_filler{type:"constant" value:0.1} #参数b的初始化策略
}
}
layer { #BatchNorm层,对feature map进行批规范化处理
name:"bn1"
type:"BatchNorm"
bottom:"conv1"
top:"conv1"
batch_norm_param{ use_global_stats:false} #训练时为false,测试时为true
}
layer { #池化层,即下采样层
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX #最大值池化,还有AVE均值池化
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:"bn2"
type:"BatchNorm"
bottom:"conv2"
top:"conv2"
batch_norm_param{ use_global_stats:false}
}
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"
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: "prob"
type: "SoftmaxWithLoss"
bottom: "ip2"
bottom: "label"
top: "prob"
}
参数初始化策略可参考这里, 激活函数可参考这里。
网络结构和超参数都设计完了,接下来就可以进行模型训练了。这里我介绍最常用的模型训练脚本,也是Caffe官方文档给的例子。
参考:https://blog.csdn.net/cham_3/article/details/72141753