作为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,晕~~