手记

[Caffe]:关于caffe新手入门

Caffe的几个重要文件

用了这么久Caffe都没好好写过一篇新手入门的博客,最近应实验室小师妹要求,打算写一篇简单、快熟入门的科普文。
利用Caffe进行深度神经网络训练第一步需要搞懂几个重要文件:

  1. solver.prototxt

  2. train_val.prototxt

  3. 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官方文档给的例子。

train.sh

这个脚本文件可写,可不写。每次运行需要写一样的命令,所以建议写一下。

TOOLS=/path/to/your/caffe/build/toolsGLOG_logtostderr=0 GLOG_log_dir=log/ \ #该行用于调用glog进行训练日志保存,使用时请把该行注释删除,否则会出错$TOOLS/caffe train --solver=/path/to/your/solver.prototxt #--snapshot=/path/to/your/snapshot or --weights=/path/to/your/caffemodel ,snapshot和weights两者只是选一,两个参数都可以用来继续训练,区别在于是否保存solver状态

数据准备

这里我们举个简单的例子,改代码是Caffe官方文档提供的,但只能用于单标签的任务,多标签得对源码进行修改。该脚本是对图片数据生成对应的lmdb文件,博主一般使用原图,即数据层类型用ImageData。

#!/usr/bin/env sh# Create the imagenet lmdb inputs# N.B. set the path to the imagenet train + val data dirsset -eEXAMPLE=""                            #存储路径DATA=""                               #数据路径TOOLS=/path/to/your/caffe/build/tools #caffe所在目录TRAIN_DATA_ROOT=""                   #训练数据根目录VAL_DATA_ROOT=""                     #测试数据根目录# RESIZE=true to resize the images to 256x256. Leave as false if images have# already been resized using another tool.RESIZE=false                         #重新调整图片大小if $RESIZE; then
  RESIZE_HEIGHT=256
  RESIZE_WIDTH=256else
  RESIZE_HEIGHT=0
  RESIZE_WIDTH=0fi#检测路径是否存在if [ ! -d "$TRAIN_DATA_ROOT" ]; then
  echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
  echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \       "where the ImageNet training data is stored."
  exit 1fiif [ ! -d "$VAL_DATA_ROOT" ]; then
  echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
  echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \       "where the ImageNet validation data is stored."
  exit 1fiecho "Creating train lmdb..."GLOG_logtostderr=1 $TOOLS/convert_imageset \
    --resize_height=$RESIZE_HEIGHT \
    --resize_width=$RESIZE_WIDTH \
    --shuffle \    $TRAIN_DATA_ROOT \    $DATA/train.txt \                #训练图片列表,运行时请把该行注释删除,否则会出错
    $EXAMPLE/mnist_train_lmdbecho "Creating val lmdb..."GLOG_logtostderr=1 $TOOLS/convert_imageset \
    --resize_height=$RESIZE_HEIGHT \
    --resize_width=$RESIZE_WIDTH \
    --shuffle \    $VAL_DATA_ROOT \    $DATA/val.txt \    $EXAMPLE/mnist_test_lmdbecho "Done."

这样,我们就可以愉快的开始训练啦。


        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css">
            </div>

               

原文出处

       



1人推荐
随时随地看视频
慕课网APP