caffe prototxt
浅谈caffe中train_val.prototxt和deploy.prototxt文件的区别
在刚开始学习的时候,觉得train_val.prototxt
文件和deploy.prototxt
文件很相似,然后当时想尝试利用deploy.prototxt还原出train_val.prototxt文件,所以就进行了一下对比,水平有限,可能很多地方说的不到位,希望大神们指点批评~~
本文以CaffeNet为例:
1. train_val.prototxt
首先,train_val.prototxt文件是网络配置文件。该文件是在训练的时候用的。
2.deploy.prototxt
该文件是在测试时使用的文件。
区别:
首先deploy.prototxt文件都是在train_val.prototxt文件的基础上删除了一些东西,所形成的。
由于两个文件的性质,train_val.prototxt文件里面训练的部分都会在deploy.prototxt文件中删除。
在train_val.prototxt
文件中,开头要加入一下训练设置文件和准备文件。例如,
transform_param中的
mirror: true(开启镜像);
crop_size: ***(图像尺寸);
mean_file: ""(求解均值的文件),
还有data_param中的
source:""(处理过得数据训练集文件);
batch_size: ***(训练图片每批次输入图片的数量);
backend: LMDB(数据格式设置)。
然后接下来,训练的时候还有一个测试的设置,测试和训练模式的设置通过一个include{phase: TEST/TRAIN}来设置。接下来就是要设置TEST模块内容。然后其他设置跟上面一样,里面有个batch_size可以调小一点,因为测试的话不需要特别多的图片数量。
而以上这一块的内容在deploy里表现出来的只有一个数据层的设置。只需设置name,type,top,input_param这些即可。
接下来,第一个卷积层的设置,train_val.prototxt文件中多了param(反向传播学习率的设置),这里需要设置两个param一个时weight的学习率,一个时bias的学习率,其中一般bias的学习率是weight学习率的两倍。然后就是设置convolution_param,但是在train_val里面需要有对weight_filler的初始化和对bias_filler的初始化。
然后就是设置激活激活函数。这一块由于没有初始化,所以两个文件都是一样的。
再接下来就是池化层,由于池化就是降低分辨率,所以这两边是一样的,只需要设置kernel_size,stride,pool即可。无需参数的初始化。
再下来时LRN层,该层的全称是Local Response Normalization(局部响应值归一化),该层的作用就是对局部输入进行一个归一化操作,不过现在有论文表明,这一层加不加对结果影响不是很大。但这一层的定义都是相同的。
再接下来就是"conv2"、"relu2"、"pool2"、"LRN2"这样的循环,具体跟之前说的一样,train_val主要多的就是参数的初始化和学习率的设置。
在第五个卷积层之后,进入了"fc6"层,该层是全连接层,这里train_val里面还是多两个param学习率的设置,和weight_filler、bias_filler的初始化设置,而两者共同的是有一个输出向量元素个数的设置:inner_product_param。
再接下来就是激活函数RELU。
再接下来就是Dropout层,该层的目的就是为了防止模型过拟合。这其中有一个dropout_ration的设置一般为0.5即可。
再接下来就是"fc7",这一层跟"fc6"相同。然后就是"relu7"、"drop7"都是相同的。然后就是"fc8"也与之前相同。
再接下来就是Accuracy,这个层是用来计算网络输出相对目标值的准确率,它实际上并不是一个损失层,所以没有反传操作。但是在caffe官网中,它在损失层这一部分。所以在deploy.prototxt文件中,这一层的定义是没有的。
再接下来train_val的最后一个层是"SoftmaxWithLoss"层,也是简单的定义了name,type,bottom,top就完了。而这一块的内容也不在deploy.prototxt文件中。
而在deploy.prototxt文件中直接定义了一个type:"Softmax"。
通过对CaffeNet这两个文件的查看发现deploy.prototxt文件和train_val.prototxt文件之间的差异在很多层里面牵扯到训练部分的都会被删除,然后就是反向传播训练部分会被删除。
其中,这里面有一个区别在里头,就是为什么train_val里面的是SoftmaxWithLoss而deploy里面的是Softmax层(两个都是损失层,都没有任何参数):
这里面其实都是softmax回归的应用,只是在定义成Softmax时直接计算了概率室友forward部分,而在SoftmaxWithLoss部分时是还有backward的部分。所以这里就出现了区别,具体的区别可以看这两个文件的C++定义。
下表左边的是train_val.prototxt文件,右边是deploy.prototxt文件。
————————————————
版权声明:本文为CSDN博主「不破楼兰终不还」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/fx409494616/article/details/53008971
lenet_solver.prototxt
solver.prototxt的主要作用就是交替调用前向算法和后向算法来更新参数,从而最小化loss,实际上就是一种迭代的优化算法。
solver.prototxt中定义了loss优化器、模型保存路径、最大迭代次数、基础学习率、学习率衰减策略、模型运算是GPU还是CPU等超参数。
# the definition of neural network model
net: "train_val.prototxt" # 网络结构路径
# test_iter is related to batch_size in test layer, test_iter * batch_size = the number of test data
test_iter: 2000 # 测试次数
# carry out test once every 5 training iterations
test_interval: 50 # 每多少次进行一次测试
# exclude test phase when test_initialization = false
# test_initialization: false
# display information once every 10 training iterations
display: 10 # 训练多少次显示一次
average_loss: 40
# the initial learning rate
base_lr: 0.0000001 # 基础学习率
lr_policy: "poly" # 学习率更新策略
stepsize: 1000 # 每1000次学习率更新一次
gamma: 0.96 # 学习率更新的超参
# The max number of iterations
max_iter: 50000 # 最大迭代次数
power: 1.0 # 学习率更新超参
momentum: 0.9 # 动量设置
# weight decay item, in case of overfitting
weight_decay: 0.0002 # 正则化设置
# save once every 50 training iterations
snapshot: 400 # 训练多少次保存一次模型
# save path
snapshot_prefix: "snapshot/resnet_50_ft" # 训练模型保存路径
solver_mode: GPU # 采用GPU训练,也可改为CPU
lenet_train_test.prototxt
name: "LeNet"
layer {
name: "mnist" #输入层的名称mnist
type: "Data" #输入层的类型data层
top: "data" #层的输出blob有两个:data和label
top: "label"
include {
phase: TRAIN #训练阶段,该层参数只在训练阶段有效
}
transform_param {
scale: 0.00390625 #输入像素归一化到【0,1】 1/256=0.00390625
}
data_param {
source: "examples/mnist/mnist_train_lmdb" #LMDB的路径
batch_size: 64 #一次读取64张图
backend: LMDB #数据格式为LMDB
}
}
layer { #一个新数据层,名字也叫作mnist,输出blob也是data和label,但是这里定义的参数只在分类阶段有效
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 #batchsize大小,乘以test_iter = 测试集大小
backend: LMDB
}
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data" #本层使用上一层的data,生成下一层conv1的blob
top: "conv1"
param {
lr_mult: 1 #权重参数w的学习率倍数,1表示保持与全局参数一致
}
param {
lr_mult: 2 #偏置参数b的学习率倍数,是全局参数的2倍
}
convolution_param {
num_output: 20 #输出单元数20
kernel_size: 5 #卷积核大小为5*5
stride: 1 #步长为1
weight_filler { #权值使用xavier填充器
type: "xavier"
}
bias_filler { #bias使用常数填充器,默认为0
type: "constant"
}
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1" #本层的上一层是conv1,生成下一层Pool1的blob
top: "pool1"
pooling_param { #下采样参数
pool: MAX #使用最大值下采样方法
kernel_size: 2 #pooling核是2*2
stride: 2 #pooling步长是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 { #新的全连接层,输入blob为pool2,输出blob为ip1
name: "ip1"
type: "InnerProduct"
bottom: "pool2"
top: "ip1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param { #全连接层的参数
num_output: 5 #输出500个节点
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer { #新的非线性层,用RELU方法
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 #输出10个单元
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer { #分类准确率层(计算网络输出相对目标值的准确率),只在testing阶段有效,输入blob为iP2和label,输出blob为accuracy
name: "accuracy" #该层用于计算分类准确率
type: "Accuracy"
bottom: "ip2"
bottom: "label"
top: "accuracy"
include {
phase: TEST
}
}
layer { #损失层,损失函数采用softmaxloss,输入blob为iP2和label,输出blob为loss
name: "loss"
type: "SoftmaxWithLoss"
bottom: "ip2"
bottom: "label"
top: "loss"
}
deploy.prototxt
name: "LeNet"
layer {
name: "data"
type: "Input"
top: "data"
input_param {shape:{dim:1 dim:1 dim:28 dim:28}}
# dim:1 batchsize dim:1 number of colour channels - rgb
# dim:28 width dim:28 height
}
layer{
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 20
kernel_size: 5
stride: 1
}
}
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
}
}
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
}
}
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
}
}
layer {
name: "prob"
type: "Softmax"
bottom: "ip2"
top: "prob"
}
结尾loss部分:
layer {
name: "loss1/loss1"
type: "SoftmaxWithLoss" # 采用SoftmaxWithLoss
bottom: "my-classifier"
bottom: "label"
top: "loss1/loss1"
loss_weight: 0.3 # 训练输出的loss所占的权重
}
layer {
name: "test/loss"
type: "SoftmaxWithLoss" # 采用SoftmaxWithLoss
bottom: "my-classifier"
bottom: "label"
top: "test/loss"
include {
phase: TEST # 验证时的loss参与训练权重参数的更新
}
}
layer {
name: "accuracy"
type: "Accuracy" # 测试时的精度输出
bottom: "my-classifier"
bottom: "label"
top: "accuracy"
include {
phase: TEST
}
}
deploy.prototxt是测试时用的文件。可以看出,lenet_train_test.prototxt删除再改变一些东西就变成了deploy.prototxt文件,最大的区别就是deploy.prototxt文件删除了lenet_train_test.prototxt文件开始的输入数据test部分;删除了分类准确率层accuracy;把trian部分的输入数据部分修改,告诉我们输入维度;将损失层loss改成了prob。