zoukankan      html  css  js  c++  java
  • 21天学习caffe(二)

    本文大致记录使用caffe的一次完整流程

    Process

    1 下载mnist数据集(数据量很小),解压放在data/mnist文件夹中;
    2 运行create_mnist.sh,生成lmdb格式的数据(data+label);
    $CAFFEROOT/build/tools/convert_imageset 可以用来做把原始图片转换为LevelDB或者 Lmdb格式。

    3 运行build/tools/caffe train --solver=examples/mnist/lenet_solver.prototxt

    usage: caffe <command> <args>
    commands:
    train train or finetune a model
    test score a model
    device_query show GPU diagnostic information
    time benchmark model execution time
    caffe的args采用第三方库gflags解析,具体可以在tools/caffe.cpp中找到定义。
    使用方法
    --solver=examples/mnist/lenet_solver.prototxt


    -solver (The solver definition protocol buffer text file.)
    type: string
    DEFINE_string(solver, "",
    "The solver definition protocol buffer text file.");

    #note#
    A 需要在caffe的根目录下运行example中的脚本,因为脚本的相对路径都是相当于caffe根目录写的;
    B 运行shell脚本的时候,可能会出一些小问题,阅读脚本源码很容易排除;
    C 报错: Cannot use GPU in CPU-only Caffe: check mode.
    修改定义训练超参数的prototxt(lenet_solver.prototxt)中的训练模式
    # solver mode: CPU or GPU
    solver_mode: CPU;
    D 关于第三方库 gflags
    API
    //显示信息
    gflags::SetUsageMessage("information");

    //instance
    //定义可在命令行调用时出现的变量
    DEFINE_bool(isvip, false, "If Is VIP");
    DEFINE_string(ip, "127.0.0.1", "connect ip");
    DEFINE_int32(port, 80, "listen port");
    //main函数接受参数之后,启动库的解析功能
    google::ParseCommandLineFlags(&argc, &argv, true);
    //读取相应的变量
    std::cout<<"ip:"<<FLAGS_ip<<std::endl;
    std::cout<<"port:"<<FLAGS_port<<std::endl;
    google::ParseCommandLineFlags(&argc, &argv, true);


    4 讲训练之后的权值参数应用到项目中去,使用matlab实现网络,并使用权值参数用于测试应用

    熟练的使用这一套流程,最好的方式就是参考一篇论文
    Image Super-Resolution Using Deep Convolutional Networks
    这篇文章将CNN应用到超分辨率中,网络结构简单,代码可得,很适合初学者阅读

    解决问题:
    回顾caffe的prototxt的写法
    使用matlab,构建定义的网络,并且利用训练好的权重参数

    #prototxt#

    网络中的数据抽象成Blob, 各层网络抽象成Layer,整个网络抽象成Net,网络模型的求解方法抽象成Solver

    Blob 主要用来表示网络中的数据,包括训练数据,网络各层自身的参数,网络之间传递的数据都是通过 Blob 来实现的,同时 Blob 数据也支持在 CPU 与 GPU 上存储,能够在两者之间做同步。
    Layer 是对神经网络中各种层的一个抽象,包括我们熟知的卷积层和下采样层,还有全连接层和各种激活函数层等等。同时每种 Layer 都实现了前向传播和反向传播,并通过 Blob 来传递数据。
    Net 是对整个网络的表示,由各种 Layer 前后连接组合而成,也是我们所构建的网络模型。
    Solver 定义了针对 Net 网络模型的求解方法,记录网络的训练过程,保存网络模型参数,中断并恢复网络的训练过程。自定义 Solver 能够实现不同的网络求解方式。


    prototxt的解析用到了第三方库protobuffer。具体,在caffe中怎么写prototxt文件,看几个例子你就会了,其实examples里的给的就还不错。
    主要有两个地方需要用到,一个是定义网络结构,一个是确定训练的超参数。
    相关reference:
    layer的介绍
    http://caffe.berkeleyvision.org/tutorial/layers.html
    layer定义时,可定义的参数参考
    https://github.com/BVLC/caffe/blob/master/src/caffe/proto/caffe.proto

    训练超参数参考(以下一页足矣)
    https://github.com/BVLC/caffe/wiki/Solver-Prototxt

    下面看几个例子
    1 prototxt about network structure
    文件结构
    name: xxx #定义网络名称
    layer{} #逐层定义网络

    layer{}惯常结构
    name,类型,输入bottom,输出top,然后定义一些不同类型layer独有的parameter


    常见layer
    输入层,分为lmdb和hdf5两种类型
    layer {
    name: "data"
    type: "HDF5Data"
    top: "data"
    top: "label"
    hdf5_data_param {
    source: "examples/SRCNN/test.txt"
    batch_size: 2
    }
    include: { phase: TEST } #声明该层使用在test还是train
    }


    layer {
    name: "mnist"
    type: "Data"
    top: "data"
    top: "label"
    include {
    phase: TRAIN
    }
    transform_param {
    scale: 0.00390625
    }
    data_param {
    source: "examples/mnist/mnist_train_lmdb"
    batch_size: 64
    backend: LMDB
    }
    }


    卷积层
    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"
    }

    The solver.prototxt is a configuration file used to tell caffe how you want the network trained.
    (这个例子取自 https://zhuanlan.zhihu.com/p/23445640)
    net: "models/bvlc_alexnet/train_val.prototxt" #声明定义网络结构的prototxt的位置,这里使用的是相对路径,运行caffe时的路径就要注意在相应的目录下
    test_iter: 1000 # 测试时,需要迭代的次数
    test_interval: 1000 # 训练,每迭代test_interval次就进行一次测试
    base_lr: 0.01 # 开始的学习率
    lr_policy: "step" # 学习率的drop是以gamma在每一次迭代中
    gamma: 0.1
    stepsize: 100000 # 每stepsize的迭代降低学习率:乘以gamma
    display: 20 # 每display次打印显示loss
    max_iter: 450000 # train 最大迭代max_iter
    momentum: 0.9 #
    weight_decay: 0.0005 #

    #snapshot
    This parameter indicates how often caffe should output a model and solverstate.
    snapshot: 10000
    snapshot_prefix: "models/bvlc_reference_caffenet/caffenet_train"

    solver_mode: GPU # 使用的模式是GPU

    使用matlab复现网络结构,下一篇讲述吧


    5 test
    使用命令
    caffe test
    -model xxxx.prototxt(原先定义网络结构的prototxt,该文件中有定义输入数据的batch_size,批处理的数量)
    -weights xxxx.caffemodel(训练好的参数)
    -iterations 100 (确定训练迭代的次数,iteration×batch_size=样本容量)


    补充小细节
    # 从训练一半的模型快照中恢复训练 (参数:求解文件 快照)
    -snapshot (Optional; the snapshot solver state to resume training.)

    caffe train -solver examples/mnist/lenet_solver.prototxt -snapshot examples/mnist/lenet_iter_5000.solverstate

    # 由其它训练好的模型 fine-tune (参数:求解文件 其它训练好的模型参数)
    -weights (Optional; the pretrained weights to initialize finetuning
    可以使用预训练或者之前迭代过的参数,继续训练
    caffe train -solver examples/finetuning_on_flickr_style/solver.prototxt -weights models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel


    蛮不错的,有助于理解的文章
    https://zhuanlan.zhihu.com/p/24087905
    没事可以多逛caffe中文社区

    另外caffe除了上述命令行的形式,还提供了python和matlab的使用接口

    下文预告:
    如何使用matlab复现网络,如何使用.caffemodel文件

    在此,感谢以下链接
    基础知识补充
    21天实战caffe 赵永科
    有助于理解
    https://zhuanlan.zhihu.com/p/24087905
    有关prototxt、caffe wiki都在github上的wiki
    https://github.com/BVLC/caffe/wiki
    官方的说明参考,包括python、matlab接口使用
    http://caffe.berkeleyvision.org/tutorial/interfaces.html

  • 相关阅读:
    linux 中rz sz 文件传输
    linux find 命令
    深度学习的博客
    cifar10数据的转换、代码解释
    gflags的使用实例(转载)
    leveldb使用 (转载)
    (转载+整理)Leveldb安装及例子
    2013-09-25-【随笔】-Roy
    2013-09-22 [随笔]-Roy
    2013-08-12【随笔2】-Roy
  • 原文地址:https://www.cnblogs.com/ceo1207/p/7145108.html
Copyright © 2011-2022 走看看