caffe入门:参数介绍

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/MOU_IT/article/details/82389576

caffe训练模型需要三个文件,分别是solver.prototxt、train_val.prototxt、train.sh,下面我们依次介绍。

1、solver.prototxt

 solver.prototxt这个文件主要存放模型训练所用到的一些超参数:
    net := 指定待训练模型结构文件,即train_val.prototxt
    test_interval := 测试间隔,即每隔多少次迭代进行一次测试。
    test_initialization := 指定是否进行初始测试,即模型未进行训练时的测试
    test_iteration := 指定测试时进行的迭代次数,即test_iter* batchsize(测试集的)=测试集的大小,测试集的 batchsize可以在prototx文件里设置。
    base_lr := 指定基本学习率
    lr_policy := 学习率变更策略,这个参数代表的是learning rate应该遵守什么样的变化规则,这个参数对应的是字符串,选项及说明如下:
        “step” - 需要设置一个stepsize参数,返回base_lr * gamma ^ ( floor ( iter / stepsize ) ),iter为当前迭代次数
        “multistep” - 和step相近,但是需要stepvalue参数,step是均匀等间隔变化,而multistep是根据stepvalue的值进行变化
        “fixed” - 保持base_lr不变
        “exp” - 返回base_lr * gamma ^ iter, iter为当前迭代次数
        “poly” - 学习率进行多项式误差衰减,返回 base_lr ( 1 - iter / max_iter ) ^ ( power )
        “sigmoid” - 学习率进行sigmod函数衰减,返回 base_lr ( 1/ 1+exp ( -gamma * ( iter - stepsize ) ) )
    gamma := 学习率变更策略需要用到的参数
    power := 同上
    stepsize := 学习率变更策略Step的变更步长(固定步长),每stepsize次迭代减少学习率,这一项和lr_policy有关
    stepvalue := 学习率变更策略Multistep的变更步长(可变步长)

   iter_size: iter_size,iter_size:iter_size*batch size=实际使用的batch size。 相当于读取batchsize*itersize个图像才做一下gradient decent。 这个参数可以规避由于gpu不足而导致的batchsize的限制 因为你可以用多个iteration做到很大的batch 即使单次batch有限
    max_iter := 模型训练的最大迭代次数
    momentum := 动量,这是优化策略(Adam, SGD, … )用到的参数,灵感来自于牛顿第一定律,基本思路是为寻优加入了“惯性”的影响,这样一来,当误差曲面中存在平坦区的时候,SGD可以更快的速度学习。
    momentum2 := 优化策略Adam用到的参数
    weight_decay := 权重衰减率,用于防止过拟合。使用方式:样本越多,该值越小,模型参数越多,该值越大。一般建议值:weight_decay: 0.0005。
    clip_gradients := 固定梯度范围
    display := 每隔几次迭代显示一次结果
    snapshot := 快照,每隔几次保存一次模型参数
    snapshot_prefix := 保存模型文件的前缀,可以是路径
    type := solver优化策略,即SGD、Adam、AdaGRAD、RMSProp、NESTROVE、ADADELTA等,在solver配置文件中,通过设置type类型来选择:
        Stochastic Gradient Descent (type: "SGD"),
        AdaDelta (type: "AdaDelta"),
        Adaptive Gradient (type: "AdaGrad"),
        Adam (type: "Adam"),
        Nesterov’s Accelerated Gradient (type: "Nesterov") and
        RMSprop (type: "RMSProp")
    solver_mode := 指定训练模式,即GPU/CPU
    debug_info := 指定是否打印调试信息,这里有对启用该功能的输出作介绍
    device_id := 指定设备号(使用GPU模式),选择几块GPU,默认为0

2、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
    mirror: true                                # 是否做镜像
    crop_size: 227                              # 对图像做裁剪
    mean_file: "data/ilsvrc12/imagenet_mean.binaryproto"   # 减去均值文件
  }   
  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  }                  #TRAIN:=用于训练,TEST:=用于测试,表明这是在测试阶段才包括进去
  transform_param {
    scale: 0.00390625                           # 对数据进行scale
    mirror: true                                # 是否做镜像
    crop_size: 227                              # 对图像做裁剪
    mean_file: "data/ilsvrc12/imagenet_mean.binaryproto"   # 减去均值文件
  } 
  data_param {                                 # 数据层配置 
    source: "examples/mnist/mnist_test_lmdb"   # 数据存放路径
    batch_size: 100                            # 指定batch大小
    backend: LMDB                              # 指定数据库格式,LMDB/LevelDB
  }
}
layer{                                      # 这里为第一个卷积层
    name:"conv1"                               # 卷积层名
    type:"Convolution"                         # 卷积层类型:卷积层
    bottom:"data"                              # 上一层的输出作为输入
    top:"conv1"                                # 这一层的输出,conv1
    param{
     name:"conv1_w"                            # 卷积层参数w(权重)的名称、
     lr_mult:1                                 # 卷积层参数w学习率,最终的学习率需要乘以 solver.prototxt 配置文件中的base_lr
     decay_mult:1                              # 卷积层参数w的衰减率,最终的衰减率需要乘以 solver.prototxt 配置文件中的weight_decay
   }                            
    param{
     name:"conv1_b"                            # 卷积层参数b(偏置)的名称,学习率和衰减率
     lr_mult:2                                 # 偏置设为2倍学习率,能够加速收敛
     decay_mult:0} 
    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 {                                   # 第二个batchnorm层
    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"
}

 3、train.sh

    这个脚本文件可写,可不写。每次运行需要写一样的命令,所以建议写一下。这里我们举个简单的例子,改代码是Caffe官方文档提供的,但只能用于单标签的任务,多标签得对源码进行修改。该脚本是对图片数据生成对应的lmdb文件,博主一般使用原图,即数据层类型用ImageData。

#!/usr/bin/env sh
# Create the imagenet lmdb inputs
# N.B. set the path to the imagenet train + val data dirs
set -e

EXAMPLE=""                            #存储路径
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=256
else
  RESIZE_HEIGHT=0
  RESIZE_WIDTH=0
fi

#检测路径是否存在
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 1
fi

if [ ! -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 1
fi

echo "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_lmdb

echo "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_lmdb

echo "Done."

参考:https://blog.csdn.net/cham_3/article/details/72141753

猜你喜欢

转载自blog.csdn.net/MOU_IT/article/details/82389576