如何理解 Cifar10 预测输出?

Posted

技术标签:

【中文标题】如何理解 Cifar10 预测输出?【英文标题】:How to understand the Cifar10 prediction output? 【发布时间】:2015-08-12 18:09:57 【问题描述】:

我已经为两类分类训练了Cifar10(caffe) 模型。行人和非行人。训练看起来不错,我在caffemodel 文件中更新了权重。我使用了两个标签,1 用于行人,2 用于非行人,以及行人图像 (64 x 160) 和背景图像 (64 x 160)。 训练后,我用正图像(行人图像)和负图像(背景图像)进行测试。我的测试prototxt文件如下所示

name: "CIFAR10_quick_test"
layers 

  name: "data"
  type: MEMORY_DATA
  top: "data"
  top: "label"
  memory_data_param 
  
    batch_size: 1
    channels: 3
    height: 160
    width: 64
  
  transform_param 
  
    crop_size: 64
    mirror: false
    mean_file: "../../examples/cifar10/mean.binaryproto"
  

layers 
  name: "conv1"
  type: CONVOLUTION
  bottom: "data"
  top: "conv1"
  blobs_lr: 1
  blobs_lr: 2
  convolution_param 
    num_output: 32
    pad: 2
    kernel_size: 5
    stride: 1
  

layers 
  name: "pool1"
  type: POOLING
  bottom: "conv1"
  top: "pool1"
  pooling_param 
    pool: MAX
    kernel_size: 3
    stride: 2
  

layers 
  name: "relu1"
  type: RELU
  bottom: "pool1"
  top: "pool1"

layers 
  name: "conv2"
  type: CONVOLUTION
  bottom: "pool1"
  top: "conv2"
  blobs_lr: 1
  blobs_lr: 2
  convolution_param 
    num_output: 32
    pad: 2
    kernel_size: 5
    stride: 1
  

layers 
  name: "relu2"
  type: RELU
  bottom: "conv2"
  top: "conv2"

layers 
  name: "pool2"
  type: POOLING
  bottom: "conv2"
  top: "pool2"
  pooling_param 
    pool: AVE
    kernel_size: 3
    stride: 2
  

layers 
  name: "conv3"
  type: CONVOLUTION
  bottom: "pool2"
  top: "conv3"
  blobs_lr: 1
  blobs_lr: 2
  convolution_param 
    num_output: 64
    pad: 2
    kernel_size: 5
    stride: 1
  

layers 
  name: "relu3"
  type: RELU
  bottom: "conv3"
  top: "conv3"

layers 
  name: "pool3"
  type: POOLING
  bottom: "conv3"
  top: "pool3"
  pooling_param 
    pool: AVE
    kernel_size: 3
    stride: 2
  

layers 
  name: "ip1"
  type: INNER_PRODUCT
  bottom: "pool3"
  top: "ip1"
  blobs_lr: 1
  blobs_lr: 2
  inner_product_param 
    num_output: 64
  

layers 
  name: "ip2"
  type: INNER_PRODUCT
  bottom: "ip1"
  top: "ip2"
  blobs_lr: 1
  blobs_lr: 2
  inner_product_param 
    num_output: 10
  

layers 
  name: "prob"
  type: SOFTMAX
  bottom: "ip2"
  top: "prob"

为了测试,我使用了test_predict_imagenet.cpp 并做了一些修改,尤其是路径和图像大小。

我无法弄清楚测试输出。当我使用正面图像进行测试时,我得到的输出为

I0813 01:55:30.378114  7668 test_predict_cifarnet.cpp:72] 1
I0813 01:55:30.379082  7668 test_predict_cifarnet.cpp:72] 3.90971e-007
I0813 01:55:30.381088  7668 test_predict_cifarnet.cpp:72] 0.00406029
I0813 01:55:30.383090  7668 test_predict_cifarnet.cpp:72] 0.995887
I0813 01:55:30.384119  7668 test_predict_cifarnet.cpp:72] 1.96203e-006
I0813 01:55:30.385095  7668 test_predict_cifarnet.cpp:72] 3.50333e-005
I0813 01:55:30.386119  7668 test_predict_cifarnet.cpp:72] 1.2796e-008
I0813 01:55:30.387097  7668 test_predict_cifarnet.cpp:72] 1.48836e-005
I0813 01:55:30.389093  7668 test_predict_cifarnet.cpp:72] 1.12237e-007
I0813 01:55:30.390100  7668 test_predict_cifarnet.cpp:72] 4.71238e-008
I0813 01:55:30.391101  7668 test_predict_cifarnet.cpp:72] 9.04134e-008

当我使用负片进行测试时,我得到的输出为

I0813 01:53:40.896139 10856 test_predict_cifarnet.cpp:72] 1
I0813 01:53:40.897117 10856 test_predict_cifarnet.cpp:72] 6.20882e-006
I0813 01:53:40.898115 10856 test_predict_cifarnet.cpp:72] 7.10468e-005
I0813 01:53:40.900184 10856 test_predict_cifarnet.cpp:72] 0.999911
I0813 01:53:40.901185 10856 test_predict_cifarnet.cpp:72] 3.4275e-006
I0813 01:53:40.902189 10856 test_predict_cifarnet.cpp:72] 2.38526e-007
I0813 01:53:40.903192 10856 test_predict_cifarnet.cpp:72] 2.29073e-007
I0813 01:53:40.905187 10856 test_predict_cifarnet.cpp:72] 1.7243e-006
I0813 01:53:40.906188 10856 test_predict_cifarnet.cpp:72] 5.40765e-007
I0813 01:53:40.908195 10856 test_predict_cifarnet.cpp:72] 1.57534e-006
I0813 01:53:40.909195 10856 test_predict_cifarnet.cpp:72] 3.72312e-006

如何理解测试输出?

有没有更有效的测试算法来测试视频源中的模型(从视频剪辑中逐帧)?

【问题讨论】:

【参考方案1】:

为什么最后一层ip2num_output: 10?你只需要2路分类器?为什么使用标签 1 和 2 而不是 0 和 1?

你得到了什么:你有 11 个输出:一个是数据层的"label" 输出,另外 10 个输出是 softmax 层的 10-vector 输出。不清楚 10 向量的值是什么,因为您只使用两个标签进行训练,因此 10 个条目中有 8 个根本没有受到监督。此外,从第一个输出来看,似乎两个测试都是带有标签1 而不是2 的样本。

你应该怎么做: 1. 将最顶层的全连接层更改为只有两个输出(我也更改了格式以匹配新版本的protobuff)

layer 
  name: "ip2/pedestrains"
  type: "InnerProduct"
  bottom: "ip1"
  top: "ip2"
  param 
    lr_mult: 1
    decay_mult: 1
  
  param 
    lr_mult: 2
    decay_mult: 0
  
  inner_product_param 
    num_output: 2 # This is what you need changing
  

2。将训练数据中的二进制标签更改为 0/1 而不是 1/2。

现在你可以再次训练,看看你得到了什么。

【讨论】:

谢谢 Shai,现在我明白了。原prototxt中是blobs_lr:1 blobs_lr:2,和你换成param lr_mult: 1 decay_mult: 1 param lr_mult: 2 decay_mult: 0 有什么区别? @batuman 有几个变化w.r.t。旧的 prototxt。请注意,“layers”现在只是“layer”,'type:' 是字符串而不是枚举,blobs_lrdeacy_mult 现在在每个 blob 的 param 下。 谢谢Shai,我应该换到所有图层还是只有最顶层就足够了? 要迁移到新的 prototxt 格式,您可以使用实用程序 ./build/tools/upgrade_net_proto_text 抱歉,它现在正在工作。我忘了在训练中将输出数量更改为 2 :)

以上是关于如何理解 Cifar10 预测输出?的主要内容,如果未能解决你的问题,请参考以下文章

Pytorch CIFAR10图像分类 GoogLeNet篇

Pytorch CIFAR10图像分类 AlexNet篇

Pytorch CIFAR10图像分类 VGG篇

Pytorch CIFAR10图像分类 MobileNet v1篇

Pytorch CIFAR10图像分类 自定义网络篇

Pytorch CIFAR10图像分类 LeNet5篇