zoukankan      html  css  js  c++  java
  • Caffe中deploy.prototxt 和 train_val.prototxt 区别

    之前用deploy.prototxt 还原train_val.prototxt过程中,遇到了坑,所以打算总结一下

    本人以熟悉的LeNet网络结构为例子

    不同点主要在一前一后,相同点都在中间

    train_val.prototxt 中的开头

    看这个名字也知道,里面定义的是训练和验证时候的网络,所以在开始的时候要定义训练集和验证集的来源

    name: "LeNet"
    layer {
      name: "mnist"
      type: "Data"
      top: "data"
      top: "label"
      include {
        phase: TRAIN
      }
      transform_param {
        scale: 0.00390625
      }
      data_param {
      	# 这里定义了之前将数据集转成lmdb数据格式的文件位置
        source: "examples/mnist/mnist_train_lmdb"
        # 这个定义了一次行送入网络的图像个数
        batch_size: 64
        backend: LMDB
      }
    }
    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
      }
    }
    

    deploy.prototxt 中的开头

    看这个名字也知道,这个配置文件适用于部署,也就是用于实际场景时候的配置文件,所以开始的时候不必在定义数据集的来源,但是需要定义输入数据的大小格式。

    name: "LeNet"
    layer {
      name: "data"
      type: "Input"
      top: "data"
      # 输入数据的batch size, channel, width, height
      input_param { shape: { dim: 64 dim: 1 dim: 28 dim: 28 } }
    }
    

    train_val.prototxt 中的结尾

    如果是一般的卷积网络的话,最后面都是用一个全连接,将feature map 转成固定长度的向量,然后输出种类的个数。所以在最后的时候,需要说明输出种类的个数。

    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: "accuracy"
      type: "Accuracy"
      bottom: "ip2"
      bottom: "label"
      top: "accuracy"
      include {
        phase: TEST
      }
    }
    

    最后还有一个不同就是,因为是训练模型,所以包括forward和backward,所以最后需要定义一个损失函数。这里用的是SoftmaxWithLoss,而在deploy.prototxt,因为只有forward,所以定义的是Softmax,也就是分类器。

    layer {
      name: "loss"
      # 定义的是损失函数
      type: "SoftmaxWithLoss"
      bottom: "ip2"
      bottom: "label"
      top: "loss"
    }
    

    deploy.prototxt 中的最后

    这里定义了Softmax分类器,输出最后各类的概率值。

    layer {
      name: "prob"
      # 定义的是分类器
      type: "Softmax"
      bottom: "ip2"
      top: "prob"
    }
    

    train_val.prototxt 和 deploy.prototxt中间部分

    两个的中间部分都是一样的,定义了一些卷积、激活、池化、Dropout、LRN(local response normalization)、全连接等操作。

    layer {
      name: "conv1"
      type: "Convolution"
      bottom: "data"
      top: "conv1"
      param {
        lr_mult: 1
      }
      param {
        lr_mult: 2
      }
      convolution_param {
        num_output: 20
        kernel_size: 5
        stride: 1
        weight_filler {
          type: "xavier"
        }
        bias_filler {
          type: "constant"
        }
      }
    }
    layer {
      name: "pool1"
      type: "Pooling"
      bottom: "conv1"
      top: "pool1"
      pooling_param {
        pool: MAX
        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: "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"
        }
      }
    }
    
  • 相关阅读:
    Codeforces 376A. Night at the Museum
    Assigning Workstations
    树的直径证明
    Frogger
    Circle
    HDU 1022 Train Problem I
    Argus
    树状数组总结
    C++ 容器(一):顺序容器简介
    C++ 输出缓冲区的管理
  • 原文地址:https://www.cnblogs.com/zhonghuasong/p/7353221.html
Copyright © 2011-2022 走看看