我正在使用CAFFE编写C ++代码来预测单个(现在)图像。图像已经过预处理,格式为.png。我创建了一个Net对象并在训练模型中读取。现在,我需要使用.png图像作为输入层并调用net.Forward() - 但是有人可以帮我弄清楚如何设置输入层吗?
我在网上找到了一些示例,但它们都没有用,而且几乎所有示例都使用了已弃用的功能。根据:Berkeley's Net API,不推荐使用“ForwardPrefilled”,并且不推荐使用“Forward(vector,float *)”。 API表示应该“设置输入blob,然后使用Forward()”。这是有道理的,但“set input blobs”部分没有扩展,我找不到一个关于如何做到这一点的好C ++示例。
我不确定是否使用caffe :: Datum是正确的方式,但我一直在玩这个:
float lossVal = 0.0; caffe::Datum datum; caffe::ReadImageToDatum("myImg.png", 1, imgDims[0], imgDims[1], &datum); caffe::Blob< float > *imgBlob = new caffe::Blob< float >(1, datum.channels(), datum.height(), datum.width()); //How to get the image data into the blob, and the blob into the net as input layer??? const vector< caffe::Blob< float >* > &result = caffeNet.Forward(&lossVal);
同样,我想按照API设置输入blob的方向,然后使用(不推荐的)caffeNet.Forward(&amp; lossVal)来获得结果,而不是使用已弃用的东西。
编辑:
根据以下答案,我更新了以下内容:
caffe::MemoryDataLayer<unsigned char> *memory_data_layer = (caffe::MemoryDataLayer<unsigned char> *)caffeNet.layer_by_name("input").get(); vector< caffe::Datum > datumVec; datumVec.push_back(datum); memory_data_layer->AddDatumVector(datumVec);
但是现在对AddDatumVector的调用是seg faulting ..我想知道这是否与我的prototxt格式有关?这是我的原型文本的顶部:
name: "deploy"
input: "data"
input_shape {
dim: 1
dim: 3
dim: 100
dim: 100
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
我将这部分问题基于this discussion关于原型文本中重要的“源”字段...
答案 0 :(得分:1)
caffe::Datum datum;
caffe::ReadImageToDatum("myImg.png", 1, imgDims[0], imgDims[1], &datum);
MemoryDataLayer<float> *memory_data_layer = (MemoryDataLayer<float> *)caffeNet->layer_by_name("data").get();
memory_data_layer->AddDatumVector(datum);
const vector< caffe::Blob< float >* > &result = caffeNet.Forward(&lossVal);
这样的事情可能会有用。在这里,您必须使用MemoryData层作为输入层。我希望图层名称可以命名为data
。
使用datum
变量的方式可能不正确。如果我的记忆是正确的,我想,你必须使用基准数据向量。
我认为这应该让你开始。
快乐酿造。 :d
答案 1 :(得分:1)
以下是我的代码here的摘录,我在C ++代码中使用了Caffe。我希望这会有所帮助。
Net<float> caffe_test_net("models/sudoku/deploy.prototxt", caffe::TEST);
caffe_test_net.CopyTrainedLayersFrom("models/sudoku/sudoku_iter_10000.caffemodel");
// Get datum
Datum datum;
if (!ReadImageToDatum("examples/sudoku/cell.jpg", 1, 28, 28, false, &datum)) {
LOG(ERROR) << "Error during file reading";
}
// Get the blob
Blob<float>* blob = new Blob<float>(1, datum.channels(), datum.height(), datum.width());
// Get the blobproto
BlobProto blob_proto;
blob_proto.set_num(1);
blob_proto.set_channels(datum.channels());
blob_proto.set_height(datum.height());
blob_proto.set_width(datum.width());
int size_in_datum = std::max<int>(datum.data().size(),
datum.float_data_size());
for (int ii = 0; ii < size_in_datum; ++ii) {
blob_proto.add_data(0.);
}
const string& data = datum.data();
if (data.size() != 0) {
for (int ii = 0; ii < size_in_datum; ++ii) {
blob_proto.set_data(ii, blob_proto.data(ii) + (uint8_t)data[ii]);
}
}
// Set data into blob
blob->FromProto(blob_proto);
// Fill the vector
vector<Blob<float>*> bottom;
bottom.push_back(blob);
float type = 0.0;
const vector<Blob<float>*>& result = caffe_test_net.Forward(bottom, &type);
答案 2 :(得分:0)
那又怎么样:
Caffe::set_mode(Caffe::CPU);
caffe_net.reset(new caffe::Net<float>("your_arch.prototxt", caffe::TEST));
caffe_net->CopyTrainedLayersFrom("your_model.caffemodel");
Blob<float> *your_blob = caffe_net->input_blobs()[0];
your_blob->set_cpu_data(your_image_data_as_pointer_to_float);
caffe_net->Forward();