Caffe Solver 参数解析以及 cmdcaffe 训练测试示例


一、caffe.proto 中关于 solver 参数的定义

message SolverParameter {
  // 网络设置,不指定 net(包含 train 和 test) 的时候,可分别指定 train_net 和 test_net 进行训练
  optional string net = 24;
  optional string train_net = 1; // Proto filename for the train net.
  repeated string test_net = 2;  // Proto filenames for the test nets.


  // 测试及模型保存设置
  optional int32 display = 6;
  repeated int32 test_iter = 3;  // The number of iterations for each test net
  optional int32 test_interval = 4 [default = 0];
  optional int32 average_loss = 33 [default = 1];
  optional bool test_compute_loss = 19 [default = false];
  optional bool test_initialization = 32 [default = true];  // 默认初始化的时候进行测试
  optional int32 snapshot = 14 [default = 0]; // The snapshot interval
  optional string snapshot_prefix = 15; // The prefix for the snapshot.
  optional bool snapshot_after_train = 28 [default = true];


  // 训练相关设置
  optional int32 max_iter = 7; 
  optional SolverMode solver_mode = 17 [default = GPU];
  optional int32 device_id = 18 [default = 0];  // 可在命令行接口指定 gpu 的 id 即可
  optional string type = 40 [default = "SGD"];  // Adam、AdaDelta、RMSProp、Nesterov、AdaGrad
  optional float momentum = 11;    // The momentum value of SGD(Momentum) 
  optional int32 iter_size = 36 [default = 1];  // accumulate gradients over `iter_size` x `batch_size` instances
  optional float weight_decay = 12; // The weight decay.
  optional string regularization_type = 29 [default = "L2"];  // L1 or L2	
  optional float clip_gradients = 35 [default = -1];   // Set clip_gradients to >= 0 to clip parameter gradients to that L2 norm, whenever their actual L2 norm is larger.

  // 学习率策略设置
  optional string lr_policy = 8;        // 常用 fixed、step、multistep、inv
  optional float base_lr = 5;           // 基础学习率
  optional float gamma = 9;             // The parameter to compute the learning rate.
  optional float power = 10;            // The parameter to compute the learning rate.
  optional int32 stepsize = 13;         // the stepsize for learning rate policy "step"
  repeated int32 stepvalue = 34;        // the stepsize for learning rate policy "multistep"
  repeated int32 plateau_winsize = 43;  // the stepsize for learning rate policy "plateau"  
  
  
  // 评价类型及方式设置, 默认为 "classification",检测任务改为 "detection" 
  optional string eval_type = 41 [default = "classification"];
  optional string ap_version = 42 [default = "Integral"];  // 11point(VOC07) or MaxIntegral(VOC12) or Integral
  optional bool show_per_class_result = 44 [default = false];    // If true, display per class result.
  
  
  // 其它优化器参数设置
  optional float momentum2 = 39 [default = 0.999];     // parameters for the Adam solver
  optional float rms_decay = 38 [default = 0.99];   // RMSProp decay value, MeanSquare(t) = rms_decay*MeanSquare(t-1) + (1-rms_decay)*SquareGradient(t)
  optional float delta = 31 [default = 1e-8];  // numerical stability for RMSProp, AdaGrad and AdaDelta and Adam


  /********************** 不常用 **************************/
  // If non-negative, the seed with which the Solver will initialize the Caffe
  // random number generator -- useful for reproducible results. Otherwise,
  // (and by default) initialize using a seed derived from the system clock.
  optional int64 random_seed = 20 [default = -1];

  // If true, print information about the state of the net that may help with debugging learning problems.
  optional bool debug_info = 23 [default = false];

  // whether to snapshot diff in the results or not. Snapshotting diff will help
  // debugging but the final protocol buffer size will be much larger.
  optional bool snapshot_diff = 16 [default = false];
  enum SnapshotFormat {
    HDF5 = 0;
    BINARYPROTO = 1;
  }
  optional SnapshotFormat snapshot_format = 37 [default = BINARYPROTO];
  // the mode solver will use: 0 for CPU and 1 for GPU. Use GPU in default.
  enum SolverMode {
    CPU = 0;
    GPU = 1;
  }

二、caffe ssd 中的参数设置示例

# 网络设置
train_net: "models/VGGNet/VOC0712/SSD_300x300/train.prototxt"
test_net: "models/VGGNet/VOC0712/SSD_300x300/test.prototxt"


# 测试及模型保存设置
display: 10
test_iter: 625              # test_size=test_iter*test_batch_size
test_interval: 10000        # 每隔 10000 步测试一次
test_initialization: false  # 不做测试初始化
average_loss: 10            # 每 10 次迭代平均一下 loss,防止 loss 的跳变
snapshot: 80000			    # 每隔 80000 步保存一下
snapshot_after_train: true  # 训练完保存一下
snapshot_prefix: "models/VGGNet/VOC0712/SSD_300x300/VGG_VOC0712_SSD_300x300"


# 训练相关设置
max_iter: 120000
solver_mode: GPU            # 默认 GPU
type: "SGD"
momentum: 0.9  
iter_size: 4                # 读取 train_batch_size*iter_size 个图像才做一下 gradient decent
regularization_type: "L2"   # L2 正则化设置(默认)
weight_decay: 0.0005  


# 学习率策略设置
lr_policy: "multistep"     
base_lr: 0.001
gamma: 0.1
stepvalue: 80000            # 降为原来的 gamma 倍,0.001-->0.0001
stepvalue: 100000           # 降为原来的 gamma 倍,0.0001-->0.00001
stepvalue: 120000           # 降为原来的 gamma 倍,0.00001-->0.000001


# 评价类型及方式设置
eval_type: "detection"      # 默认为 classification
ap_version: "11point"       # 计算 ap 的方式,caffe 还支持 MaxIntegral 和 Integral 

三、学习率策略的设置

常用的学习率策略有:fixed、step、multistep、inv

  • SGD 参数学习算法的学习率策略可选择 step、multistep、inv
  • Adam、RMSProp、Adadelta 等自适应调整学习率的参数学习算法,学习率策略可设置成 fixed

迁移学习时学习率的设置:

  • 微调时,我们降低整体学习速率(base_lr),同时提高新添加层的学习速率(通过 lr_mult来设置)
  • 一般,新添加层的学习速率要是旧层学习率的10倍以上,新层:lr_mult: 10, 旧层: lr_mult : 1 or 0(不学习)

1、fixed:固定策略

# 固定学习率,像 Adam、RMSProp、Adadelta 等自适应调整学习率的参数学习算法,可设置成 fixed 
lr_policy: "fixed"  
base_lr: 0.01

2、step:均匀分步策略

# base_lr * gamma ^ (floor(iter / step))
# 采用均匀降低的方式,每迭代 stepsize(10000) 步学习率降低为原来的 gamma(0.1) 倍
lr_policy: "step"
base_lr: 0.01
stepsize: 10000  
gamma:0.1

在这里插入图片描述

3、multistep:不均匀分步策略

# 采用非均匀降低策略,指定迭代到 stepvalue 步的时候学习率降低为原来的 gamma 倍
lr_policy: "multistep"
base_lr: 0.1
gamma: 0.5
stepvalue: 10000
stepvalue: 30000
stepvalue: 60000

在这里插入图片描述

4、inv:指数变换策略

# base_lr * (1 + gamma * iter) ^ (- power)
# gamma 控制曲线下降的速率,而参数 power 控制曲线在饱和状态下学习率达到的最低值
lr_policy: "inv"
base_lr: 0.01
gamma: 0.0001
power: 0.75 or 0.25

在这里插入图片描述


四、参数学习算法 type 的选择

  • caffe 中的 参数学习算法包含:SGD(其实是 Momentum)、Adam、AdaDelta、RMSProp、Nesterov、AdaGrad
  • TensorFLow 中的参数学习算法及原理,可参考:TensorFLow 中的参数学习算法
    这里写图片描述

五、训练脚本示例

#!/usr/bin/env sh

CAFFE=/home/manzp/caffe_ssd/caffe/build/tools/caffe
LOGDIR=training_code/train_log/
SOLVER=training_code/solver.prototxt
WEIGHTS=training_code/res18.caffemodel
SNAPSHOT=training_code/train_snapshot/res18_iter_10000.solverstate

# 随机初始化训练
GLOG_log_dir=$LOGDIR $CAFFE train -solver $SOLVER -gpu all

# fine-tune 训练
GLOG_log_dir=$LOGDIR $CAFFE train -solver $SOLVER -weights $WEIGHTS -gpu all

# 从 snapshot 恢复训练
GLOG_log_dir=$LOGDIR $CAFFE train -solver $SOLVER -snapshot $SNAPSHOT -gpu all

# Note:solver 和 net 在每个 GPU 上都会实例化,因此 batch_size 在多 GPU 训练的时候会成 GPU 个数倍增加!

六、测试及 Benchmarking 示例

#!/usr/bin/env sh
CAFFE=/home/manzp/caffe_ssd/caffe/build/tools/caffe
MODEL=./train.prototxt
WEIGHTS=./res18_iter_2200.caffemodel

# 1、Testing Accuracy,test_batch_size*100 个数据的 accuracy
$CAFFE test -model $MODEL -weights $WEIGHTS -gpu 0 -iterations 100

# 2、Benchmarking:包括前向、后向以及总和的平均时间
$CAFFE time -model $MODEL -iterations 10  # CPU 上迭代 10 次所需时间
$CAFFE time -model $MODEL -gpu 0  # GPU 0,默认的迭代 50 次所需的时间
$CAFFE time -model $MODEL -weights $WEIGHTS -gpu 0 -iterations 10  # GPU 0, 迭代 10 次训练已给定权值的网络结构的时间

七、参考资料

1、https://github.com/weiliu89/caffe/blob/ssd/src/caffe/proto/caffe.proto
2、如何选择最适合你的学习率变更策略?

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页