本文以OpenPose的网络结构为例对各层参数进行解析
训练的网络文件
layer { name: "data" 表示该层名字 type: "CPMData" 层有多种类型,比如:Data、Convolution、Pooling,Data表示数据来源于Leveldb或者LMDB top: "data" 每一层用top来输出数据,只有top没有bottom,则这一层只有输出没有输入,反之亦然 top: "label" 如果有多个top和bottom,表示有多个blobs数据的输入输出 data_param { source: "/mnt/sdb/yangbin/COCO_kpt/lmdb" 包含数据库的目录名称 batch_size: 10 每次处理数据的个数 backend: LMDB 选择采用Leveldb还是LMDB,默认采用leveldb cpm_transform_param { 自定义层,之后会进行补充 stride: 8 max_rotate_degree: 40 visualize: false crop_size_x: 368 crop_size_y: 368 scale_prob: 1 scale_min: 0.5 scale_max: 1.1 target_dist: 0.6 center_perterb_max: 40 do_clahe: false num_parts: 56 np_in_lmdb: 17Eltwise层
layer { name: "weight_stage1_L2" 官方注释:http://caffe.berkeleyvision.org/tutorial/layers/eltwise.html type: "Eltwise" 按元素操作层 bottom: "conv5_5_CPM_L2" bottom: "heat_weight" top: "weight_stage1_L2" eltwise_param { operation: PROD 支持三种基本操作:1.PROD - 按元素乘积; 2.SUM - 按元素求和(默认,若实现相减,设置第一个coeff参数为1,第二个coeff参数为-1); 3.MAX - 保存元素大者EuclideanLoss层
layer { name: "loss_stage1_L1" 官方注释:http://caffe.berkeleyvision.org/tutorial/layers/euclideanloss.html type: "EuclideanLoss" 源码分析:https://blog.csdn.net/seashell_9/article/details/68064294 bottom: "weight_stage1_L1" bottom: "label_vec" top: "loss_stage1_L1" loss_weight: 1 默认为1BatchNorm层
BN层的设定一般按照conv→BN→scale→relu的顺序来形成一个block
https://www.cnblogs.com/makefile/p/batch-norm.html?utm_source=debugrun&utm_medium=referrallayer { name: "conv1/bn" type: "BatchNorm" bottom: "conv1" top: "conv1" #inplace param { #均值 lr_mult: 0 decay_mult: 0 param { lr_mult: 0 #方差 decay_mult: 0 param { lr_mult: 0 #Scale decay_mult: 0 batch_norm_param { use_global_stats: true #训练的时候要设置为false,测试时设置为true eps: 1e-5 #分母附加值,防止除以方差时出现除0操作,默认为1e-5VGG19前十层
OpenPose采用VGG19模型的前十层网络进行初始化
layer { name: "conv1_1" #表示该层的名称 type: "Convolution" #层类型 bottom: "image" #输入 top: "conv1_1" #输出 param { lr_mult: 1.0 #权值的学习率,最终的学习率是这个系数乘以solver.prototxt配置文件中的base_Ir decay_mult: 1 #权值衰减系数 param { lr_mult: 2.0 #如果有两个Ir_mult,则第二个代表偏置项的学习率,一般来说偏置项的学习率是权值学习率的两倍 decay_mult: 0 convolution_param { num_output: 64 #卷积核的个数,convolution_param主要用于设定卷积层的特有参数 pad: 1 kernel_size: 3 weight_filler { #权值初始化 type: "gaussian" #默认为“constant”,值为0,“gaussian”使用高斯分布初始化权值 std: 0.01 #std是参数初始化成是高斯分布的标准差,std越小,证明高斯曲线越平滑,各个权重值基本相同 详见https://blog.csdn.net/kenny_star/article/details/69949846 bias_filler { type: "constant" #偏置项的初始化,一般设置为“constant”,值全为0layer { name: "relu1_1" 对输入数据进行激活操作(一种函数变换),从bottom得到一个blob数据输入,运算后,从top输出一个blob数据 type: "ReLU" 在运算过程中,只对输入数据逐个元素进行函数变化,不改变数据维度大小 bottom: "conv1_1" 输入:n*c*h*w 输出:n*c*h*w top: "conv1_1" Relu层支持in-place计算,因此Relu层的输入输出可以相同,这意味着该层的输入输出可以共享同一块内存,减少内存消耗,其它层不支持layer { name: "pool1_stage1" type: "Pooling" #层类型 bottom: "conv1_2" top: "pool1_stage1" pooling_param { pool: MAX #池化方法,默认为MAX,其他还有AVE、STOCHASTIC(随机采样池化) kernel_size: 2 stride: 2layer { name: "concat_stage2" #输入:n_i * c_i * h * w for each input blob i from 1 to K. type: "Concat" bottom: "conv5_5_CPM_L1" bottom: "conv5_5_CPM_L2" bottom: "conv4_4_CPM" top: "concat_stage2" concat_param { https://blog.csdn.net/u012426298/article/details/80743284 axis: 1 if axis = 0: (n_1 + n_2 + ... + n_K) * c_1 * h * w, and all input c_i should be the same if axis = 1: n_1 * (c_1 + c_2 + ... + c_K) * h * w, and all input n_i should be the same