Prediction in Caffe - Exception: Input blob arguments do not match net inputs

后端 未结 4 1089
忘了有多久
忘了有多久 2021-02-14 02:02

I\'m using Caffe for classifying non-image data using a quite simple CNN structure. I\'ve had no problems training my network on my HDF5-data with dimensions n x 1 x 156 x 12. H

相关标签:
4条回答
  • 2021-02-14 02:16

    Only due to my own experimental experience, it's not a very good idea to specify train and test net in one file using {PHASE} clause. I got many weird errors when I used net file like that, but when I used older version of net files which contain two files separately, train and test, it worked. However I was using caffe version in Nov 2014, perhaps there's some bug or compatible issues there.

    Well, when the model is used for prediction, shouldn't there be a deploy file specifying the net structure? If you look at ImageNet you should find imagenet_deploy.prototxt there. Although deploy file is similar to train/test file, I heard it's a bit different due to some fillers. I don't know if it's the problem, but any discussion is welcome, I need to learn new caffe schema if there exist too

    0 讨论(0)
  • 2021-02-14 02:32

    Here is the answer from Evan Shelhamer I got on the Caffe Google Groups:

    self._inputs is indeed for the manual or "deploy" inputs as defined by the input fields in a prototxt. To run a net with data layers in through pycaffe, just call net.forward() without arguments. No need to change the definition of your train or test nets.

    See for instance code cell [10] of the Python LeNet example.

    In fact I think it's clearer in the Instant Recognition with Caffe tutorial, cell 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()))
    

    In other words, to generate the predicted outputs as well as their probabilities using pycaffe, once you have trained your model, you have to first feed the data layer with your input, then perform a forward pass with net.forward().


    Alternatively, as pointed out in other answers, you can use a deploy prototxt that is similar to the one you use to define the trained network but removing the input and output layers, and add the following at the beginning (obviously adapting according to your input dimension):

    name: "your_net"
    input: "data"
    input_dim: 1
    input_dim: 1
    input_dim: 1
    input_dim: 250
    

    That's what they use in the CIFAR10 tutorial.

    (pycaffe really ought to be better documented…)

    0 讨论(0)
  • 2021-02-14 02:39
    Even small hints would be greatly appreciated!
    

    I am stuck too so not much help, sorry. Might want to skip to the end.

    net.inputs is a @property function which supposedly generated the names of the input layer(s).

    @property
    def _Net_inputs(self):
        return [list(self.blobs.keys())[i] for i in self._inputs]
    

    Where list(self.blobs.keys()) for you would be

    ['data', 'feature_conv', 'conv1', 'pool1', 'conv2', 'fc1', 'accuracy', 'loss']
    

    Since inputs has to match kwargs.keys() = ['data'] we can conclude that net._inputs should have been [0]. Somehow.

    Since _inputs isn't used anywhere else in pycaffe.py I have a look at _caffe.cpp. Around line 222 it says

    .add_property("_inputs", p::make_function(&Net<Dtype>::input_blob_indices,
        bp::return_value_policy<bp::copy_const_reference>()))
    

    So _inputs are the input_blob_indices and it makes sense that these should be [0] for your network.

    input_blob_indices in turn is simply a function that returns net_input_blob_indices_ in include/caffe/net.hpp

    inline const vector<int>& input_blob_indices() const { return net_input_blob_indices_; }
    

    ...which is only used in src/caffe/net.cpp, but I can't find it being defined or assigned anywhere.

    I have tried with type: Data and type: MemoryData but that doesn't make a difference. What does work is using

    input: "data"
    input_dim: 1
    input_dim: 3
    input_dim: 227
    input_dim: 227
    

    ...instead of a layer. In that case net._inputs = [0] and net.inputs = ['data'] (actually net._inputs is a caffe._caffe.IntVec object but list(net._inputs) = [0]).

    TLDR: It is starting to look a lot like a bug so I submitted it: https://github.com/BVLC/caffe/issues/2246

    P.s. it seems like you are converting ndarray to datum and then back again. Does this have a purpose?

    0 讨论(0)
  • 2021-02-14 02:42

    I have exactly the same problem. This is what fixed it.

    First, take the same prototext file as you used to train, remove the two data layers.

    Then add the block as Mark's above

    name: "Name_of_your_net"
    input: "data"
    input_dim: 64 
    input_dim: 1
    input_dim: 28
    input_dim: 28
    

    where my input_dim are for mnist, change them to your dim.

    Everything works.

    0 讨论(0)
提交回复
热议问题