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
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
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 callnet.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…)
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?
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.