AccuracyLayer 是计算分类准确率的层。输出分类准确率。
1. AccuracyLayer 的成员:
topK : 计算 topK 的准确率。默认为1,即 top1 的准确率。
topK准确率准则下,分类正确的定义如下:在你模型对一个样本进行分类时,对于每一类都有产生一 个概率,取topK 个概率对应的predicted label,如果这topK个 predicted label 中包含 ground truth label,则认为这次分类正确。
2. forward()
AccuracyLayer 只能计算准确率,不需要也不能后向传播。当只有一个top时,会记录一个总的分类准确率,当有两个top时,另一个top会记录每一类各自的准确率。
template <typename Dtype>
void AccuracyLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
Dtype accuracy = 0;
const Dtype* bottom_data = bottom[0]->cpu_data();
const Dtype* bottom_label = bottom[1]->cpu_data();
const int dim = bottom[0]->count() / outer_num_;
const int num_labels = bottom[0]->shape(label_axis_);
vector<Dtype> maxval(top_k_+1);
vector<int> max_id(top_k_+1);
if (top.size() > 1) {
caffe_set(nums_buffer_.count(), Dtype(0), nums_buffer_.mutable_cpu_data());
caffe_set(top[1]->count(), Dtype(0), top[1]->mutable_cpu_data());
}
int count = 0;
for (int i = 0; i < outer_num_; ++i) {
for (int j = 0; j < inner_num_; ++j) {
const int label_value =
static_cast<int>(bottom_label[i * inner_num_ + j]);
if (has_ignore_label_ && label_value == ignore_label_) {
continue;
}
if (top.size() > 1) ++nums_buffer_.mutable_cpu_data()[label_value];
DCHECK_GE(label_value, 0);
DCHECK_LT(label_value, num_labels);
// Top-k accuracy
std::vector<std::pair<Dtype, int> > bottom_data_vector;
for (int k = 0; k < num_labels; ++k) {
bottom_data_vector.push_back(std::make_pair( //用bottom_data_vector记录该样本分类 每一类的概率。
bottom_data[i * dim + k * inner_num_ + j], k));
}
std::partial_sort(
bottom_data_vector.begin(), bottom_data_vector.begin() + top_k_, //topK排序
bottom_data_vector.end(), std::greater<std::pair<Dtype, int> >());
// check if true label is in top k predictions
for (int k = 0; k < top_k_; k++) {
if (bottom_data_vector[k].second == label_value) { //累计分类准确的个数
++accuracy;
if (top.size() > 1) ++top[1]->mutable_cpu_data()[label_value]; //累计每一类的分类准确的个数
break;
}
}
++count;
}
}
// LOG(INFO) << "Accuracy: " << accuracy;
top[0]->mutable_cpu_data()[0] = accuracy / count; //计算分类准确率,分类正确数除以总数
if (top.size() > 1) {
for (int i = 0; i < top[1]->count(); ++i) { //计算每一类的分类准确率
top[1]->mutable_cpu_data()[i] =
nums_buffer_.cpu_data()[i] == 0 ? 0
: top[1]->cpu_data()[i] / nums_buffer_.cpu_data()[i];
}
}
// Accuracy layer should not be used as a loss function.
}
std::partial_sort() 函数原型有:
partial_sort(begin,mid,end)
partial_sort(begin,mid,end,comp)
顾名思义,这是个局部排序,底层实现是推排序,得到 前(mid - begin) 个结果,排序方式按comp进行。
std::greater<std::pair<Dtype, int> >() 函数 则按 pair.first 进行降序排序。