Caffe中的预测 - 异常:输入blob参数与净输入不匹配

pir*_*pir 11 python deep-learning caffe

我正在使用Caffe使用非常简单的CNN结构对非图像数据进行分类.我在使用尺寸为nx 1 x 156 x 12的HDF5数据上训练我的网络没有任何问题.但是,我在分类新数据时遇到了困难.

如何在没有任何预处理的情况下进行简单的正向传递?我的数据已经标准化并且具有Caffe的正确尺寸(它已经被用于训练网络).下面是我的代码和CNN结构.

编辑:我已将问题隔离到pycaffe.py中的函数'_Net_forward',并发现问题出现在self.input dict为空.谁能解释为什么会这样?该集合应该等于来自新测试数据的集合:

if set(kwargs.keys()) != set(self.inputs):
            raise Exception('Input blob arguments do not match net inputs.')
Run Code Online (Sandbox Code Playgroud)

我的代码已经改变了一点,因为我现在使用IO方法将数据转换为数据(见下文).通过这种方式,我用正确的数据填充了kwargs变量.

即使是小提示也会非常感激!

    import numpy as np
    import matplotlib
    import matplotlib.pyplot as plt

    # Make sure that caffe is on the python path:
    caffe_root = ''  # this file is expected to be run from {caffe_root}
    import sys
    sys.path.insert(0, caffe_root + 'python')

    import caffe

    import os
    import subprocess
    import h5py
    import shutil
    import tempfile

    import sklearn
    import sklearn.datasets
    import sklearn.linear_model
    import skimage.io



    def LoadFromHDF5(dataset='test_reduced.h5', path='Bjarke/hdf5_classification/data/'):

        f   = h5py.File(path + dataset, 'r')
        dat = f['data'][:]
        f.close()   

        return dat;

    def runModelPython():
        model_file = 'Bjarke/hdf5_classification/conv_v2_simple.prototxt'
        pretrained = 'Bjarke/hdf5_classification/data/train_iter_10000.caffemodel'
        test_data = LoadFromHDF5()

        net = caffe.Net(model_file, pretrained)
        caffe.set_mode_cpu()
        caffe.set_phase_test()  

        user = test_data[0,:,:,:] 
        datum = caffe.io.array_to_datum(user.astype(np.uint8))
        user_dat = caffe.io.datum_to_array(datum)
        user_dat = user_dat.astype(np.uint8)
        out = net.forward_all(data=np.asarray([user_dat]))

if __name__ == '__main__':
    runModelPython()
Run Code Online (Sandbox Code Playgroud)

CNN Prototext

name: "CDR-CNN"
layers {
  name: "data"
  type: HDF5_DATA
  top: "data"
  top: "label"
  hdf5_data_param {
    source: "Bjarke/hdf5_classification/data/train.txt"
    batch_size: 10
  }
  include: { phase: TRAIN }
}
layers {
  name: "data"
  type: HDF5_DATA
  top: "data"
  top: "label"
  hdf5_data_param {
    source: "Bjarke/hdf5_classification/data/test.txt"
    batch_size: 10
  }
  include: { phase: TEST }
}

layers {
  name: "feature_conv"
  type: CONVOLUTION
  bottom: "data"
  top: "feature_conv"
  blobs_lr: 1
  blobs_lr: 2
  convolution_param {
    num_output: 10
    kernel_w: 12
    kernel_h: 1
    stride_w: 1
    stride_h: 1
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
    }
  }
}
layers {
  name: "conv1"
  type: CONVOLUTION
  bottom: "feature_conv"
  top: "conv1"
  blobs_lr: 1
  blobs_lr: 2
  convolution_param {
    num_output: 14
    kernel_w: 1
    kernel_h: 4
    stride_w: 1
    stride_h: 1
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
    }
  }
}
layers {
  name: "pool1"
  type: POOLING
  bottom: "conv1"
  top: "pool1"
  pooling_param {
    pool: MAX
    kernel_w: 1
    kernel_h: 3
    stride_w: 1
    stride_h: 3
  }
}
layers {
  name: "conv2"
  type: CONVOLUTION
  bottom: "pool1"
  top: "conv2"
  blobs_lr: 1
  blobs_lr: 2
  convolution_param {
    num_output: 120
    kernel_w: 1
    kernel_h: 5
    stride_w: 1
    stride_h: 1
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
    }
  }
}
layers {
  name: "fc1"
  type: INNER_PRODUCT
  bottom: "conv2"
  top: "fc1"
  blobs_lr: 1
  blobs_lr: 2
  weight_decay: 1
  weight_decay: 0
  inner_product_param {
    num_output: 84
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layers {
  name: "accuracy"
  type: ACCURACY
  bottom: "fc1"
  bottom: "label"
  top: "accuracy"
  include: { phase: TEST }
}
layers {
  name: "loss"
  type: SOFTMAX_LOSS
  bottom: "fc1"
  bottom: "label"
  top: "loss"
}
Run Code Online (Sandbox Code Playgroud)

Fra*_*urt 8

以下是我加入Caffe Google网上论坛的答案:Evan Shelhamer:

self._inputs确实适用于原型文本中输入字段定义的手动或"部署"输入.要通过pycaffe运行带有数据层的网络,只需调用net.forward()不带参数.无需更改火车或测试网的定义.

例如,参见Python LeNet示例的代码单元[10] .

事实上,我认为在使用Caffe即时识别教程中,单元格6 更清晰:

# Feed in the image (with some preprocessing) and classify with a forward pass.
net.blobs['data'].data[...] = transformer.preprocess('data', caffe.io.load_image(caffe_root + 'examples/images/cat.jpg'))
out = net.forward()
print("Predicted class is #{}.".format(out['prob'].argmax()))
Run Code Online (Sandbox Code Playgroud)

换句话说,要使用pycaffe生成预测输出及其概率,一旦训练了模型,就必须首先使用输入提供数据层,然后执行前向传递net.forward().


或者,正如其他答案中所指出的,您可以使用类似于用于定义训练网络的部署原型,但删除输入和输出层,并在开头添加以下内容(显然根据您的输入进行调整)尺寸):

name: "your_net"
input: "data"
input_dim: 1
input_dim: 1
input_dim: 1
input_dim: 250
Run Code Online (Sandbox Code Playgroud)

这就是他们在CIFAR10教程中使用的内容.

(pycaffe确实应该更好地记录......)