如何在caffe中使用c ++从多个图层中获取要素

时间:2016-12-02 18:03:24

标签: machine-learning deep-learning caffe conv-neural-network

如何在使用C ++进行一次正向传递后,在caffe中同时获得4096 dim功能层和1000 dim类图层?

我试图在extract_features.cpp中查找它,但它使用了一些奇怪的datum对象,所以我无法理解它是如何工作的。

到目前为止,我只是将我的prototxt文件裁剪到我想要提取和使用的图层

[...]
net->ForwardPrefilled();
Blob<float> *output_layer = net->output_blobs()[0];
const float *begin = output_layer->cpu_data();
const float *end = begin + output_layer->channels();
return vector<float>(begin, end);

但如果我想同时提取两个特定图层(例如&#34;概率&#34;和#34; fc7&#34;),则无法使用。

1 个答案:

答案 0 :(得分:2)

更新

extract_feature.cpp的简单工作流程(假设您在c ++中有shared_ptr<Net<float> > net个对象):

  1. 执行net forward以处理输入:net->Forward()。 在此步骤中,Data中有net层来读取输入图像。因此,如果您希望在自己的应用/代码中将图片读取到cv::Mat image并将其提供给net,则可以编写如下代码:

    // for data preprocess
    shared_ptr<caffe::DataTransformer<float> > data_transformer;
    caffe::TransformationParameter trans_para;
    // set mean
    trans_para.set_mean_file("/path/to/image_mean.binaryproto");
    // set crop size, e.g.here is cropping 227x227
    trans_para.set_crop_size(227);
    // instantiate a DataTransformer using trans_para for image preprocess
    data_transformer.reset(new caffe::DataTransformer<float>(trans_para, caffe::TEST));
    const std::vector<caffe::Blob<float> *> net_input = net->input_blobs();
    // maybe you need to resize image before this step
    data_transformer->Transform(image, *net_input[0]);
    net->Forward();
    

    net.prototxt应该有一个Input图层作为第一层,例如这deploy.prototxt

  2. 根据名称获取功能blob:const boost::shared_ptr<Blob<Dtype> > feature_blob = net->blob_by_name(blob_names[i])
  3. 从您所获得的blob中提取要素数据,例如: arry,一个简单的示例代码可以是:

    count = feature_blob->channels() * feature_blob->height() * 
        feature_blob->width();
    float* feature_array = new float[count]; 
    const float* feature_blob_data = feature_blob->cpu_data() +
        feature_blob->offset(n); // feature data generated from 
                                 // the nth input image within a batch 
    memcpy(feature_array, feature_blob_data, count * sizeof(float)); 
    ...// other operations
    delete [] feature_array;        
    
  4. 请注意,feature_blob_data存储的数据位于row-major order

    extract_feature.cpp的用法应该与您的任务类似:

    path/to/extract_features your_pretrained_model.caffemodel \
        net.prototxt 4096_dim_feature_blob_name,1000_dim_class_feature_blob_name \
        saved_4096_dim_feature_database,saved_1000_dim_class_feature_database \
        num_mini_batches(times for forward pass) lmdb(or leveldb) GPU(or CPU)
    

    net.prototxt应包含可以读取输入图像数据的数据层。

    运行时,它将首先从net.prototxt内的数据层读取图像数据并执行前向传递的num_mini_batches次,并提取2两个要素blob 4096_dim_feature_blob_name,{{将数据输入1000_dim_class_feature_blob_name类型的结构中,然后将其序列化以保存在Datumsaved_4096_dim_feature_database的数据库中saved_1000_dim_class_feature_databaselmdb {1}}。

    完成后,您可以分别使用leveldb中的数据层从saved_4096_dim_feature_databasesaved_1000_dim_class_feature_database读取保存的要素数据。

    BTW,net.prototxt是一种结构,可以存储最多4D数据以及数据的形状和标签信息等。它在datum中定义,使用{{3}生成并且便于caffe和数据库之间的数据交换,如caffe.protoLMDB