作為caffe初學者,特徵提取python官方給的教程比較好用;但是關於c++API的使用,找了一些資料,說的並不是特徵完善;項目要求,得到ImageNet映像在CaffeNet網路結構中第fc7層的特徵。
環境:window7+caffe
語言:C++
目的:測試映像某層特徵,並以儲存
可以直接執行下面的命令,(注意官方給的案例是儲存為leveldb 格式,資料庫格式不夠直觀,解析也比較麻煩,直接儲存為文本形式多好呀~另外是7個參數哦,直接弄清楚對應的參數資訊)
extract_features.exe D:/caffe-windows/examples/_temp/caffe_reference_imagenet_model D:/caffe-windows/examples/_temp/imagenet_val.prototxt fc7 D:/caffe-windows/examples/_temp/features_fc7 10 leveldb GPU
然後通過解決方案中的extract_features工程源碼extract_features.cpp進行了改進,代碼更改地區塊如下
ofstream *fout = new ofstream[num_features]; for (size_t i = 0; i < num_features; ++i) { LOG(INFO)<< "Opening dataset " << dataset_names[i]; //boost::shared_ptr<db::DB> db(db::GetDB(db_type)); // db->Open(dataset_names.at(i), db::NEW); // feature_dbs.push_back(db); // boost::shared_ptr<db::Transaction> txn(db->NewTransaction()); //txns.push_back(txn); string feat_file_name = dataset_names.at(i); feat_file_name = feat_file_name.append("/").append(blob_names[i]).append(".txt"); fout[i].open(feat_file_name); } LOG(ERROR)<< "Extacting Features"; //Datum datum; std::vector<int> image_indices(num_features, 0); for (int batch_index = 0; batch_index < num_mini_batches; ++batch_index) { feature_extraction_net->Forward(); for (int i = 0; i < num_features; ++i) { const boost::shared_ptr<Blob<Dtype> > feature_blob = feature_extraction_net->blob_by_name(blob_names[i]); //blob是一個四維的資料:n*c*w*h,“fc7”層50*1*1*4960;“conv1”層50*96*55*55; // “conv2”層50*256*27*27。 int batch_size = feature_blob->num(); //batch_size 就是blob中的n,表示feature-map的個數 LOG(ERROR) << "總的特徵塊數量:" << batch_size*num_mini_batches;//50*10 int dim_features = feature_blob->count() / batch_size; LOG(ERROR) << "dim_features:" << dim_features;//4096 const Dtype* feature_blob_data; for (int n = 0; n < batch_size; ++n) { // datum.set_height(feature_blob->height()); // datum.set_width(feature_blob->width()); // datum.set_channels(feature_blob->channels()); // datum.clear_data(); // datum.clear_float_data(); feature_blob_data = feature_blob->cpu_data() + feature_blob->offset(n); // for (int d = 0; d < dim_features; ++d) { // datum.add_float_data(feature_blob_data[d]);//寫入到文字檔中,fc7總共有4096維 if (n == 0) { for (int d = 0; d < dim_features; ++d) fout[i] << feature_blob_data[d] << " "; } // string key_str = caffe::format_int(image_indices[i], 10); //string out; // CHECK(datum.SerializeToString(&out)); // txns.at(i)->Put(key_str, out); // ++image_indices[i]; // if (image_indices[i] % 1000 == 0) { // txns.at(i)->Commit(); // txns.at(i).reset(feature_dbs.at(i)->NewTransaction()); // LOG(ERROR)<< "Extracted features of " << image_indices[i] << // " query images for feature blob " << blob_names[i]; // } } // for (int n = 0; n < batch_size; ++n) fout[i].close(); } // for (int i = 0; i < num_features; ++i) } // for (int batch_index = 0; batch_index < num_mini_batches; ++batch_index) // write the last batch // for (int i = 0; i < num_features; ++i) { // if (image_indices[i] % 1000 != 0) { // txns.at(i)->Commit(); // } // LOG(ERROR)<< "Extracted features of " << image_indices[i] << //" query images for feature blob " << blob_names[i]; //feature_dbs.at(i)->Close(); //}
代碼改寫後,得到的結果就是有文檔形式的特徵了,可以繼續接下來的專案工作了~~
fc7.txt儲存的就是4096維的float資料啦~
設定檔上傳出現問題,不能超過60M,暈~~