in caffe/tools/feature_pooling.cpp [240:310]
void feature_pooling(vector<float>& features_pool, vector<data_item>& datas_pool,
const vector<float>& features, const vector<data_item>& datas) {
int num = datas.size();
int dim = features.size() / num;
// pooling - label
int N = num / FLAGS_number;
datas_pool.resize(N);
for (int i = 0; i < N; ++i) {
datas_pool[i] = datas[i * FLAGS_number];
datas_pool[i].id_ = i;
for (int j = 1; j < FLAGS_number; ++j) {
CHECK_EQ(datas_pool[i].label_, datas[i * FLAGS_number + j].label_)
<< "Label inconsistent";
}
}
// pooling - feature
features_pool.resize(N * dim);
if (FLAGS_pooling == "max") {
for (int i = 0; i < N; ++i) {
for (int d = 0; d < dim; ++d) {
features_pool[i * dim + d] = -1.0e20;
}
for (int j = 0; j < FLAGS_number; ++j) {
int id = datas[i * FLAGS_number + j].id_;
for (int d = 0; d < dim; ++d) {
if (features[id * dim + d] > features_pool[i * dim + d])
features_pool[i * dim + d] = features[id * dim + d];
}
}
}
} else if (FLAGS_pooling == "avg") {
for (int i = 0; i < N; ++i) {
for (int d = 0; d < dim; ++d) {
features_pool[i * dim + d] = 0;
}
for (int j = 0; j < FLAGS_number; ++j) {
int id = datas[i * FLAGS_number + j].id_;
for (int d = 0; d < dim; ++d) {
features_pool[i * dim + d] += features[id * dim + d];
}
}
for (int d = 0; d < dim; ++d) {
features_pool[i * dim + d] /= (float)FLAGS_number;
}
}
} else {
LOG(ERROR) << "Only support {max, avg} pooling : " << FLAGS_pooling;
}
if (!FLAGS_poolrst.empty()) {
// dump the list files
ofstream outfile;
outfile.open(FLAGS_poolrst + "_datalist_" + FLAGS_pooling + "_pool.txt");
for (int i = 0; i < N; ++i)
outfile << datas_pool[i].name_ << " " << datas_pool[i].label_ << "\n";
outfile.close();
// dump the feature result
outfile.open(FLAGS_poolrst + "_feature_" + FLAGS_pooling + "_pool.dat", ios::binary);
outfile.write((const char*)(&N), sizeof(int));
outfile.write((const char*)(&dim), sizeof(int));
outfile.write((const char*)features_pool.data(), sizeof(float)*N * dim);
outfile.close();
}
}