Caffe中deploy.prototxt 和 train_val.prototxt 区别
之前用deploy.prototxt 还原train_val.prototxt过程中,遇到了坑,所以打算总结一下
本人以熟悉的LeNet网络结构为例子
不同点主要在一前一后,相同点都在中间
train_val.prototxt 中的开头
看这个名字也知道,里面定义的是训练和验证时候的网络,所以在开始的时候要定义训练集和验证集的来源
name: "LeNet" layer { name: "mnist" type: "Data" top: "data" top: "label" include { phase: TRAIN } transform_param { scale: 0.00390625 } data_param { # 这里定义了之前将数据集转成lmdb数据格式的文件位置 source: "examples/mnist/mnist_train_lmdb" # 这个定义了一次行送入网络的图像个数 batch_size: 64 backend: 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 } }
deploy.prototxt 中的开头
看这个名字也知道,这个配置文件适用于部署,也就是用于实际场景时候的配置文件,所以开始的时候不必在定义数据集的来源,但是需要定义输入数据的大小格式。
name: "LeNet" layer { name: "data" type: "Input" top: "data" # 输入数据的batch size, channel, width, height input_param { shape: { dim: 64 dim: 1 dim: 28 dim: 28 } } }
train_val.prototxt 中的结尾
如果是一般的卷积网络的话,最后面都是用一个全连接,将feature map 转成固定长度的向量,然后输出种类的个数。所以在最后的时候,需要说明输出种类的个数。
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" bottom: "ip2" bottom: "label" top: "accuracy" include { phase: TEST } }
最后还有一个不同就是,因为是训练模型,所以包括forward和backward,所以最后需要定义一个损失函数。这里用的是SoftmaxWithLoss,而在deploy.prototxt,因为只有forward,所以定义的是Softmax,也就是分类器。
layer { name: "loss" # 定义的是损失函数 type: "SoftmaxWithLoss" bottom: "ip2" bottom: "label" top: "loss" }
deploy.prototxt 中的最后
这里定义了Softmax分类器,输出最后各类的概率值。
layer { name: "prob" # 定义的是分类器 type: "Softmax" bottom: "ip2" top: "prob" }
train_val.prototxt 和 deploy.prototxt中间部分
两个的中间部分都是一样的,定义了一些卷积、激活、池化、Dropout、LRN(local response normalization)、全连接等操作。
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 weight_filler { type: "xavier" } bias_filler { type: "constant" } } } 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" 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" } } }
如果这篇文章帮助到了你,你可以请作者喝一杯咖啡
![](https://img2020.cnblogs.com/blog/938105/202010/938105-20201013171833350-276632012.png)