【问题标题】:Setting input layer in CAFFE with C++使用 C++ 在 CAFFE 中设置输入层
【发布时间】:2019-01-15 19:59:16
【问题描述】:

我正在使用 CAFFE 编写 C++ 代码来预测单个(目前)图像。图像已经过预处理,为 .png 格式。我创建了一个 Net 对象并在训练好的模型中读取。现在,我需要使用 .png 图像作为输入层并调用 net.Forward() - 但有人可以帮我弄清楚如何设置输入层吗?

我在网上找到了一些示例,但没有一个有效,而且几乎所有示例都使用了已弃用的功能。根据:Berkeley's Net API,不推荐使用“ForwardPrefilled”,不推荐使用“Forward(vector, float*)”。 API 表示应该“设置输入 blob,然后改用 Forward()”。这是有道理的,但是“设置输入 blob”部分没有展开,我找不到一个很好的 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(&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 的调用出现了段错误。我想知道这是否与我的 prototxt 格式有关?这是我的 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,关于“源”字段在 prototxt 中很重要...

【问题讨论】:

  • 您可以在 net.prototxt 中使用 ImageData 层。该层可以读取您的图像列表并像数据层一样进行一些转换。

标签: c++ caffe


【解决方案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

【讨论】:

  • 出于某种原因,我的 memory_data_layer 被设置为空 ptr,即使该层在我的 prototxt 中正确命名为 data。仍在工作,因为这似乎是正确的方向..
  • 在调试器中,看起来层名称是“输入”而不是数据 - 它没有在 prototxt 中指定为层,它以“输入:“数据”开头,所以我想“数据”是名称..更改使 memory_data_layer 成为有效指针。无论如何,我将数据放在一个向量中并将向量传递给 AddDatumVector,但由于我没有找到原因,现在这是段错误 - gdb 在这里没有帮助,因为那里似乎没有调试符号......跨度>
  • 我的内存数据层有问题,有没有其他选择避免使用这个层?
  • 有ImageData层、InputData层等可以代替内存数据层使用
【解决方案2】:

这是我位于 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);

【讨论】:

  • 谢谢 - 我找到了那个例子,但是根据我上面链接的 API,它使用了已弃用的 Forward() 版本。试图避免使用它.. 无论如何我已经尝试过一段时间但仍然没有成功,但在我看到该调用已被弃用后,我承认并没有玩太多。
【解决方案3】:

怎么样:

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

【讨论】:

    猜你喜欢
    • 2018-01-09
    • 2017-07-25
    • 2017-08-01
    • 1970-01-01
    • 2016-09-25
    • 2019-06-24
    • 2017-11-29
    • 2018-04-23
    • 1970-01-01
    相关资源
    最近更新 更多