使用C ++在CAFFE中设置输入层

时间:2016-07-28 12:56:24

标签: c++ caffe

我正在使用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关于原型文本中重要的“源”字段...

3 个答案:

答案 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();