zoukankan      html  css  js  c++  java
  • 根据 train_test.prototxt文件生成 deploy.prototxt文件

    本文参考博文

    (1)介绍 *_train_test.prototxt文件与 *_deploy.prototxt文件的不同:http://blog.csdn.net/sunshine_in_moon/article/details/49472901    

    (2)生成deploy文件的Python代码:http://www.cnblogs.com/denny402/p/5685818.html       

    *_train_test.prototxt文件

    这是训练与测试网络配置文件


    *_deploy.prototxt文件
    这是模型构造文件

    在博文http://www.cnblogs.com/denny402/p/5685818.html     中给出了生成 deploy.prototxt文件的Python源代码,但是每个网络不同,修改起来比较麻烦,下面给出该博文中以mnist为例生成deploy文件的源代码,可根据自己网络的设置做出相应修改:(下方代码未测试)

    # -*- coding: utf-8 -*-
    
    from caffe import layers as L,params as P,to_proto
    root='/home/xxx/'
    deploy=root+'mnist/deploy.prototxt' #文件保存路径
    
    def create_deploy():
    #少了第一层,data层
    conv1=L.Convolution(bottom='data', kernel_size=5, stride=1,num_output=20, pad=0,weight_filler=dict(type='xavier'))
    pool1=L.Pooling(conv1, pool=P.Pooling.MAX, kernel_size=2, stride=2)
    conv2=L.Convolution(pool1, kernel_size=5, stride=1,num_output=50, pad=0,weight_filler=dict(type='xavier'))
    pool2=L.Pooling(conv2, pool=P.Pooling.MAX, kernel_size=2, stride=2)
    fc3=L.InnerProduct(pool2, num_output=500,weight_filler=dict(type='xavier'))
    relu3=L.ReLU(fc3, in_place=True)
    fc4 = L.InnerProduct(relu3, num_output=10,weight_filler=dict(type='xavier'))
    #最后没有accuracy层,但有一个Softmax层
    prob=L.Softmax(fc4)
    return to_proto(prob)
    def write_deploy(): 
    with open(deploy, 'w') as f:
    f.write('name:"Lenet"
    ')
    f.write('input:"data"
    ')
    f.write('input_dim:1
    ')
    f.write('input_dim:3
    ')
    f.write('input_dim:28
    ')
    f.write('input_dim:28
    ')
    f.write(str(create_deploy()))
    if __name__ == '__main__':
    write_deploy()
    

      


    用代码生成deploy文件还是比较麻烦。我们在构建深度学习网络时,肯定会先定义好训练与测试网络的配置文件——*_train_test.prototxt文件,我们可以通过修改*_train_test.prototxt文件 来生成 deploy 文件。以cifar10为例先简单介绍一下两者的区别。

    (1)deploy 文件中的数据层更为简单,即将*_train_test.prototxt文件中的输入训练数据lmdb与输入测试数据lmdb这两层删除,取而代之的是,

    layer {
    name: "data"
    type: "Input"
    top: "data"
    input_param { shape: { dim: 1 dim: 3 dim: 32 dim: 32 } }
    }
    

      


    注:shape: { dim: 1 dim: 3 dim: 32 dim: 32 }代表含义:

    shape {
    dim: 1 #num,对待识别样本进行数据增广的数量,可自行定义。一般会进行5次crop,之后分别flip。如果该值为10则表示一个样本会变成10个,之后输入到网络进行识别。如果不进行数据增广,可以设置成1
    dim: 3 #通道数,表示RGB三个通道
    dim: 32 #图像的长和宽,通过 *_train_test.prototxt文件中数据输入层的crop_size获取
    dim: 32}
    

      

    (2)卷积层和全连接层中weight_filler{}与bias_filler{}两个参数不用再填写,因为这两个参数的值,由已经训练好的模型*.caffemodel文件提供。如下所示代码,将*_train_test.prototxt文件中的weight_filler、bias_filler全部删除。

    layer {                              # weight_filler、bias_filler删除
      name: "ip2"
      type: "InnerProduct"
      bottom: "ip1"
      top: "ip2"
      param {
        lr_mult: 1   #权重w的学习率倍数
      }
      param {
        lr_mult: 2    #偏置b的学习率倍数
      }
      inner_product_param {
        num_output: 10
        weight_filler {
          type: "gaussian"
          std: 0.1
        }
        bias_filler {
          type: "constant"
        }
      }
    }
    

      

    删除后变为

    layer { 
    name: "ip2"
    type: "InnerProduct"
    bottom: "ip1"
    top: "ip2"
    param {
    lr_mult: 1
    }
    param {
    lr_mult: 2
    }
    inner_product_param {
    num_output: 10
    }
    }
    

      

    (3)输出层的变化  
         1)没有了test模块测试精度 ,将该层删除     
         2)输出层

    1)*_deploy.prototxt文件的构造和*_train_test.prototxt文件的构造最为明显的不同点是,deploy文件没有test网络中的test模块,只有训练模块,即将*_train_test.prototxt中最后部分的test模块测试精度删除,即将如下代码删除。

    layer { #删除该层
    name: "accuracy"
    type: "Accuracy"
    bottom: "ip2"
    bottom: "label"
    top: "accuracy"
    include {
    phase: TEST
    }
    }
    

      

    2) 输出层 

    *_train_test.prototxt文件

    layer{
    name: "loss" #注意此处层名称与下面的不同
    type: "SoftmaxWithLoss" #注意此处与下面的不同
    bottom: "ip2"
    bottom: "label" #注意标签项在下面没有了,因为下面的预测属于哪个标签,因此不能提供标签
    top: "loss"
    }
    

      

    *_deploy.prototxt文件

    layer {
    name: "prob"
    type: "Softmax"
    bottom: "ip2"
    top: "prob"
    }
    

      


    注意在两个文件中输出层的类型都发生了变化一个是SoftmaxWithLoss,另一个是Softmax。另外为了方便区分训练与应用输出,训练是输出时是loss,应用时是prob。


    下面给出CIFAR10中的配置文件cifar10_quick_train_test.prototxt与其模型构造文件  cifar10_quick.prototxt 直观展示两者的区别。

    cifar10_quick_train_test.prototxt文件代码

    name: "CIFAR10_quick"
    layer {               #该层去掉
      name: "cifar"
      type: "Data"
      top: "data"
      top: "label"
      include {
        phase: TRAIN
      }
      transform_param {
        mean_file: "examples/cifar10/mean.binaryproto"
      }
      data_param {
        source: "examples/cifar10/cifar10_train_lmdb"
        batch_size: 100
        backend: LMDB
      }
    }
    layer {             #该层去掉
      name: "cifar"
      type: "Data"
      top: "data"
      top: "label"
      include {
        phase: TEST
      }
      transform_param {
        mean_file: "examples/cifar10/mean.binaryproto"
      }
      data_param {
        source: "examples/cifar10/cifar10_test_lmdb"
        batch_size: 100
        backend: LMDB
      }
    }
    layer {                        #将下方的weight_filler、bias_filler全部删除
      name: "conv1"
      type: "Convolution"
      bottom: "data"
      top: "conv1"
      param {
        lr_mult: 1
      }
      param {
        lr_mult: 2
      }
      convolution_param {
        num_output: 32
        pad: 2
        kernel_size: 5
        stride: 1
        weight_filler {
          type: "gaussian"
          std: 0.0001
        }
        bias_filler {
          type: "constant"
        }
      }
    }
    layer {
      name: "pool1"
      type: "Pooling"
      bottom: "conv1"
      top: "pool1"
      pooling_param {
        pool: MAX
        kernel_size: 3
        stride: 2
      }
    }
    layer {
      name: "relu1"
      type: "ReLU"
      bottom: "pool1"
      top: "pool1"
    }
    layer {                         #weight_filler、bias_filler删除
      name: "conv2"
      type: "Convolution"
      bottom: "pool1"
      top: "conv2"
      param {
        lr_mult: 1
      }
      param {
        lr_mult: 2
      }
      convolution_param {
        num_output: 32
        pad: 2
        kernel_size: 5
        stride: 1
        weight_filler {
          type: "gaussian"
          std: 0.01
        }
        bias_filler {
          type: "constant"
        }
      }
    }
    layer {
      name: "relu2"
      type: "ReLU"
      bottom: "conv2"
      top: "conv2"
    }
    layer {
      name: "pool2"
      type: "Pooling"
      bottom: "conv2"
      top: "pool2"
      pooling_param {
        pool: AVE
        kernel_size: 3
        stride: 2
      }
    }
    layer {                         #weight_filler、bias_filler删除
      name: "conv3"
      type: "Convolution"
      bottom: "pool2"
      top: "conv3"
      param {
        lr_mult: 1
      }
      param {
        lr_mult: 2
      }
      convolution_param {
        num_output: 64
        pad: 2
        kernel_size: 5
        stride: 1
        weight_filler {
          type: "gaussian"
          std: 0.01
        }
        bias_filler {
          type: "constant"
        }
      }
    }
    layer {
      name: "relu3"
      type: "ReLU"
      bottom: "conv3"
      top: "conv3"
    }
    layer {
      name: "pool3"
      type: "Pooling"
      bottom: "conv3"
      top: "pool3"
      pooling_param {
        pool: AVE
        kernel_size: 3
        stride: 2
      }
    }
    layer {                       #weight_filler、bias_filler删除
      name: "ip1"
      type: "InnerProduct"
      bottom: "pool3"
      top: "ip1"
      param {
        lr_mult: 1
      }
      param {
        lr_mult: 2
      }
      inner_product_param {
        num_output: 64
        weight_filler {
          type: "gaussian"
          std: 0.1
        }
        bias_filler {
          type: "constant"
        }
      }
    }
    layer {                              # weight_filler、bias_filler删除
      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: "gaussian"
          std: 0.1
        }
        bias_filler {
          type: "constant"
        }
      }
    }
    layer {                                  #将该层删除
      name: "accuracy"
      type: "Accuracy"
      bottom: "ip2"
      bottom: "label"
      top: "accuracy"
      include {
        phase: TEST
      }
    }
    layer {                                 #修改
      name: "loss"       #---loss  修改为  prob 
      type: "SoftmaxWithLoss"             # SoftmaxWithLoss 修改为 softmax
      bottom: "ip2"
      bottom: "label"          #去掉
      top: "loss"
    }
    

      

    以下为cifar10_quick.prototxt

    layer {               #将两个输入层修改为该层
      name: "data"
      type: "Input"
      top: "data"
      input_param { shape: { dim: 1 dim: 3 dim: 32 dim: 32 } }     #注意shape中变量值的修改,CIFAR10中的 *_train_test.protxt文件中没有 crop_size
    }
    layer {
      name: "conv1"
      type: "Convolution"
      bottom: "data"
      top: "conv1"
      param {
        lr_mult: 1   #权重W的学习率倍数
    }
      param {
        lr_mult: 2   #偏置b的学习率倍数
      }
      convolution_param {
        num_output: 32
        pad: 2   #加边为2
       kernel_size: 5
        stride: 1
      }
    }
    layer {
      name: "pool1"
      type: "Pooling"
      bottom: "conv1"
      top: "pool1"
      pooling_param {
        pool: MAX    #Max Pooling
       kernel_size: 3
        stride: 2
      }
    }
    layer {
      name: "relu1"
      type: "ReLU"
      bottom: "pool1"
      top: "pool1"
    }
    layer {
      name: "conv2"
      type: "Convolution"
      bottom: "pool1"
      top: "conv2"
      param {
        lr_mult: 1
      }
      param {
        lr_mult: 2
      }
      convolution_param {
        num_output: 32
        pad: 2
        kernel_size: 5
        stride: 1
      }
    }
    layer {
      name: "relu2"
      type: "ReLU"
      bottom: "conv2"
      top: "conv2"
    }
    layer {
      name: "pool2"
      type: "Pooling"
      bottom: "conv2"
      top: "pool2"
      pooling_param {
        pool: AVE   #均值池化
        kernel_size: 3
        stride: 2
      }
    }
    layer {
      name: "conv3"
      type: "Convolution"
      bottom: "pool2"
      top: "conv3"
      param {
        lr_mult: 1
      }
      param {
        lr_mult: 2
      }
      convolution_param {
        num_output: 64
        pad: 2
        kernel_size: 5
        stride: 1
      }
    }
    layer {
      name: "relu3"
      type: "ReLU"  #使用ReLU激励函数,这里需要注意的是,本层的bottom和top都是conv3>
      bottom: "conv3"
      top: "conv3"
    }
    layer {
      name: "pool3"
      type: "Pooling"
      bottom: "conv3"
      top: "pool3"
      pooling_param {
        pool: AVE 
    kernel_size: 3
        stride: 2
      }
    }
    layer {
      name: "ip1"
      type: "InnerProduct"
      bottom: "pool3"
      top: "ip1"
      param {
        lr_mult: 1
      }
      param {
        lr_mult: 2
      }
      inner_product_param {
        num_output: 64
      }
    }
    layer {
      name: "ip2"
      type: "InnerProduct"
      bottom: "ip1"
      top: "ip2"
      param {
        lr_mult: 1
      }
      param {
        lr_mult: 2
      }
      inner_product_param {
        num_output: 10
      }
    }
    layer {
      name: "prob"
      type: "Softmax"
      bottom: "ip2"
      top: "prob"
    }
    

      


    ---------------------
    作者:修炼打怪的小乌龟
    来源:CSDN
    原文:https://blog.csdn.net/u010417185/article/details/52137825
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    c语言中malloc函数的使用
    C语言的头文件和宏定义详解
    CUDA程序闪退时的处理方法【转】
    Shell面试,笔试整理
    阿里云系统安装部署Freeswitch
    汇编——根据偏移地址索取到的字数据
    一个典型的空语句(c,c++)
    关于64位系统的debug使用方法
    隐藏表单域、URL重写、cookie、session
    MVC的路由
  • 原文地址:https://www.cnblogs.com/sddai/p/10421697.html
Copyright © 2011-2022 走看看