抽取任意層特徵---caffe使用MemoryDataLayer從記憶體中載入資料

查志強發表於2015-08-27

【原文:http://blog.csdn.net/lien0906/article/details/47971451

最近在搞caffe的應用,因為很多時候我們需要進行伺服器來進行特徵的抽取,所以我們需要很將單張圖片丟入caffe的網路進行一次傳遞,這樣就誕生了一個從記憶體中如何載入資料進入caffe的需求,這裡我直接貼出程式碼來先:


  1. #include <boost/make_shared.hpp>  
  2.   
  3.   
  4. // these need to be included after boost on OS X  
  5. #include <string>  // NOLINT(build/include_order)  
  6. #include <vector>  // NOLINT(build/include_order)  
  7. #include <fstream>  // NOLINT  
  8.   
  9.   
  10. #include "caffe/caffe.hpp"  
  11. #include <opencv.hpp>  
  12.   
  13.   
  14. static void CheckFile(const std::string& filename) {  
  15.     std::ifstream f(filename.c_str());  
  16.     if (!f.good()) {  
  17.         f.close();  
  18.         throw std::runtime_error("Could not open file " + filename);  
  19.     }  
  20.     f.close();  
  21. }  
  22.   
  23.   
  24.   
  25.   
  26. template <typename Dtype>  
  27. caffe::Net<Dtype>* Net_Init_Load(  
  28.     std::string param_file, std::string pretrained_param_file, caffe::Phase phase)  
  29. {  
  30.     CheckFile(param_file);  
  31.     CheckFile(pretrained_param_file);  
  32.   
  33.   
  34.     caffe::Net<Dtype>* net(new caffe::Net<Dtype>(param_file,phase));  
  35.       
  36.   
  37.   
  38.     net->CopyTrainedLayersFrom(pretrained_param_file,0);  
  39.     return net;  
  40. }  
  41. #define NetF float  
  42.   
  43.   
  44.   
  45.   
  46. int main()  
  47. {  
  48.     cv::Mat src1;  
  49.     src1 = cv::imread("test.png");  
  50.   
  51.   
  52.     cv::Mat rszimage;  
  53.   
  54.   
  55.     //// The mean file image size is 256x256, need to resize the input image to 256x256  
  56.     cv::resize(src1, rszimage, cv::Size(227, 227));  
  57.     std::vector<cv::Mat> dv = { rszimage }; // image is a cv::Mat, as I'm using #1416  
  58.     std::vector<int> dvl = { 0 };  
  59.       
  60.     caffe::Datum data;  
  61.     caffe::ReadFileToDatum("D:/work/DestImage/crop/CH0005-00-0019/00028.png", &data);  
  62.   
  63.   
  64.     caffe::Net<NetF>* _net = Net_Init_Load<NetF>("deploy_Test.prototxt""bvlc_alexnet.caffemodel", caffe::TEST);  
  65.     caffe::MemoryDataLayer<NetF> *m_layer_ = (caffe::MemoryDataLayer<NetF> *)_net->layers()[0].get();  
  66.     m_layer_->AddMatVector(dv, dvl);  
  67.       
  68.     /*float loss = 0.0; 
  69.     std::vector<caffe::Blob<float>*> results = _net->ForwardPrefilled(&loss);*/  
  70.     int end_ind = _net->layers().size();  
  71.     std::vector<caffe::Blob<NetF>*> input_vec;  
  72.     _net->Forward(input_vec);  
  73.     boost::shared_ptr<caffe::Blob<NetF>> outPool5 = _net->blob_by_name("pool5");  
  74.     std::cout << outPool5->shape()[0] << std::endl;  
  75.     std::cout << outPool5->shape()[1] << std::endl;  
  76.     std::cout << outPool5->shape()[2] << std::endl;  
  77.     std::cout << outPool5->shape()[3] << std::endl;  
  78.   
  79.   
  80.     std::cout << outPool5->num() << std::endl;  
  81.     std::cout << outPool5->channels() << std::endl;  
  82.     std::cout << outPool5->width() << std::endl;  
  83.     std::cout << outPool5->height() << std::endl;  
  84.     std::cout << outPool5->data_at(0, 0, 0, 0) << std::endl;  
  85.     std::cout << outPool5->data_at(0, 0, 1, 1) << std::endl;  
  86.     std::cout << outPool5->data_at(0, 95, 5, 5) << std::endl;  
  87.   
  88.   
  89.     const NetF* pstart = outPool5->cpu_data();  
  90.     std::cout << m_layer_->width() << std::endl;  
  91.       
  92.     return 0;  
  93. }  

然後是配置檔案:

[plain] view plaincopy
  1. name: "CaffeNet"  
  2.   
  3.   
  4. layers   
  5. {  
  6.   name: "data"  
  7.   type: MEMORY_DATA  
  8.   top: "data"  
  9.   top: "label"  
  10.   memory_data_param   
  11.   {  
  12.     batch_size: 1  
  13.     channels: 3  
  14.     height: 227  
  15.     width: 227  
  16.   }  
  17.   transform_param   
  18.   {  
  19.     crop_size: 227  
  20.     mirror: false  
  21.     #mean_file:"imagenet_mean.binaryproto"  
  22.     mean_value: 104  
  23.     mean_value: 117  
  24.     mean_value: 123  
  25.   }  
  26. }  
  27.   
  28.   
  29. layers {  
  30.   name: "`"  
  31.   type: CONVOLUTION  
  32.   bottom: "data"         
  33.   top: "conv1"           
  34.   blobs_lr: 1  
  35.   blobs_lr: 2  
  36.   weight_decay: 1  
  37.   weight_decay: 0  
  38.   convolution_param {  
  39.     num_output: 96  
  40.     kernel_size: 11  
  41.     stride: 4  
  42.   }  
  43. }  
  44. layers {  
  45.   name: "relu1"  
  46.   type: RELU  
  47.   bottom: "conv1"        
  48.   top: "conv1"           
  49. }  
  50. layers {  
  51.   name: "pool1"  
  52.   type: POOLING  
  53.   bottom: "conv1"  
  54.   top: "pool1"  
  55.   pooling_param {  
  56.     pool: MAX  
  57.     kernel_size: 3  
  58.     stride: 2  
  59.   }  
  60. }  
  61. layers {  
  62.   name: "norm1"  
  63.   type: LRN  
  64.   bottom: "pool1"  
  65.   top: "norm1"  
  66.   lrn_param {  
  67.     local_size: 5  
  68.     alpha: 0.0001  
  69.     beta: 0.75  
  70.   }  
  71. }  
  72. layers {  
  73.   name: "conv2"  
  74.   type: CONVOLUTION  
  75.   bottom: "norm1"  
  76.   top: "conv2"  
  77.   blobs_lr: 1  
  78.   blobs_lr: 2  
  79.   weight_decay: 1  
  80.   weight_decay: 0  
  81.   convolution_param {  
  82.     num_output: 256  
  83.     pad: 2  
  84.     kernel_size: 5  
  85.     group: 2  
  86.   }  
  87. }  
  88. layers {  
  89.   name: "relu2"  
  90.   type: RELU  
  91.   bottom: "conv2"  
  92.   top: "conv2"  
  93. }  
  94. layers {  
  95.   name: "pool2"  
  96.   type: POOLING  
  97.   bottom: "conv2"  
  98.   top: "pool2"  
  99.   pooling_param {  
  100.     pool: MAX  
  101.     kernel_size: 3  
  102.     stride: 2  
  103.   }  
  104. }  
  105. layers {  
  106.   name: "norm2"  
  107.   type: LRN  
  108.   bottom: "pool2"  
  109.   top: "norm2"  
  110.   lrn_param {  
  111.     local_size: 5  
  112.     alpha: 0.0001  
  113.     beta: 0.75  
  114.   }  
  115. }  
  116. layers {  
  117.   name: "conv3"  
  118.   type: CONVOLUTION  
  119.   bottom: "norm2"  
  120.   top: "conv3"  
  121.   blobs_lr: 1  
  122.   blobs_lr: 2  
  123.   weight_decay: 1  
  124.   weight_decay: 0  
  125.   convolution_param {  
  126.     num_output: 384  
  127.     pad: 1  
  128.     kernel_size: 3  
  129.   }  
  130. }  
  131. layers {  
  132.   name: "relu3"  
  133.   type: RELU  
  134.   bottom: "conv3"  
  135.   top: "conv3"  
  136. }  
  137. layers {  
  138.   name: "conv4"  
  139.   type: CONVOLUTION  
  140.   bottom: "conv3"  
  141.   top: "conv4"  
  142.   blobs_lr: 1  
  143.   blobs_lr: 2  
  144.   weight_decay: 1  
  145.   weight_decay: 0  
  146.   convolution_param {  
  147.     num_output: 384  
  148.     pad: 1  
  149.     kernel_size: 3  
  150.     group: 2  
  151.   }  
  152. }  
  153. layers {  
  154.   name: "relu4"  
  155.   type: RELU  
  156.   bottom: "conv4"  
  157.   top: "conv4"  
  158. }  
  159. layers {  
  160.   name: "conv5"  
  161.   type: CONVOLUTION  
  162.   bottom: "conv4"  
  163.   top: "conv5"  
  164.   blobs_lr: 1  
  165.   blobs_lr: 2  
  166.   weight_decay: 1  
  167.   weight_decay: 0  
  168.   convolution_param {  
  169.     num_output: 256  
  170.     pad: 1  
  171.     kernel_size: 3  
  172.     group: 2  
  173.   }  
  174. }  
  175. layers {  
  176.   name: "relu5"  
  177.   type: RELU  
  178.   bottom: "conv5"  
  179.   top: "conv5"  
  180. }  
  181. layers {  
  182.   name: "pool5"  
  183.   type: POOLING  
  184.   bottom: "conv5"  
  185.   top: "pool5"  
  186.   pooling_param {  
  187.     pool: MAX  
  188.     kernel_size: 3  
  189.     stride: 2  
  190.   }  
  191. }  
  192. layers {  
  193.   name: "fc6"  
  194.   type: INNER_PRODUCT  
  195.   bottom: "pool5"  
  196.   top: "fc6"  
  197.   blobs_lr: 1  
  198.   blobs_lr: 2  
  199.   weight_decay: 1  
  200.   weight_decay: 0  
  201.   inner_product_param {  
  202.     num_output: 4096  
  203.   }  
  204. }  
  205. layers {  
  206.   name: "relu6"  
  207.   type: RELU  
  208.   bottom: "fc6"  
  209.   top: "fc6"  
  210. }  
  211. layers {  
  212.   name: "drop6"  
  213.   type: DROPOUT  
  214.   bottom: "fc6"  
  215.   top: "fc6"  
  216.   dropout_param {  
  217.     dropout_ratio: 0.5  
  218.   }  
  219. }  
  220. layers {  
  221.   name: "fc7"  
  222.   type: INNER_PRODUCT  
  223.   bottom: "fc6"  
  224.   top: "fc7"  
  225.   blobs_lr: 1  
  226.   blobs_lr: 2  
  227.   weight_decay: 1  
  228.   weight_decay: 0  
  229.   inner_product_param {  
  230.     num_output: 4096  
  231.   }  
  232. }  
  233. layers {  
  234.   name: "relu7"  
  235.   type: RELU  
  236.   bottom: "fc7"  
  237.   top: "fc7"  
  238. }  
  239. layers {  
  240.   name: "drop7"  
  241.   type: DROPOUT  
  242.   bottom: "fc7"  
  243.   top: "fc7"  
  244.   dropout_param {  
  245.     dropout_ratio: 0.5  
  246.   }  
  247. }  
  248. layers {  
  249.   name: "fc8"  
  250.   type: INNER_PRODUCT  
  251.   bottom: "fc7"  
  252.   top: "fc8"  
  253.   blobs_lr: 1  
  254.   blobs_lr: 2  
  255.   weight_decay: 1  
  256.   weight_decay: 0  
  257.   inner_product_param {  
  258.     num_output: 1000  
  259.   }  
  260. }  
  261.   
  262. layers   
  263. {  
  264.   name: "prob"  
  265.   type: SOFTMAX  
  266.   bottom: "fc8"  
  267.   top: "prob"  
  268. }  
  269.   
  270. layers   
  271. {  
  272.   name: "output"  
  273.   type: ARGMAX  
  274.   bottom: "prob"  
  275.   top: "output"  
  276. }  

我的模型使用的是alexnet,例子是用來抽取一個圖片在pool5那一層的特徵。這樣大家使用這個例子可以利用caffe的任意模型抽取任意圖片的特徵。


相關文章