特别声明,这篇是我自己看的,有很多观点我自己都拿不准,要是不对,一定要跟我说下,我好改,咱互相学习。
直接看代码啊
accuracy_layer.cpp
用的是lenet5网络 batch_size=100;类=10
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();//100*10
const Dtype* bottom_label = bottom[1]->cpu_data();//100*1,100个图像对应的类
const int dim = bottom[0]->count() / outer_num_;//dim=10
const int num_labels = bottom[0]->shape(label_axis_);
//全连接后的blob数据都是2维的,label_axis_=1,所以shape就应该是N*D中的D(这块可以看我上一篇文章)
//所以bottom[0]->shape(1)=10,也就是类别数
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) {//outer_num_=100
for (int j = 0; j < inner_num_; ++j) {//inner_num_为每个图像所对应的类别数,所以=1
const int label_value =
static_cast<int>(bottom_label[i * inner_num_ + j]);
//将bottom_label的值赋给label_value,[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);//label_value(0~9)肯定小于 num_labels(10)
// Top-k accuracy // top_k为取前k个最高评分(的预测标签)
std::vector<std::pair<Dtype, int> > bottom_data_vector;
//这个主要就是用于对接下来两步把测试评分与类别ID挂勾,并对评分排序(这里我其实是比较迷糊的,测试评分指的是bottom_data,难道说经过全连接后,得到的向量就是测试评分? 迷糊中~~~)
for (int k = 0; k < num_labels; ++k) {
bottom_data_vector.push_back(std::make_pair(
bottom_data[i * dim + k * inner_num_ + j], k));
//把测试评分与类别ID挂勾,
}
std::partial_sort(
bottom_data_vector.begin(), bottom_data_vector.begin() + top_k_,
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;
.second指的是类别,如果跟label_value相等,那就说明准确
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.
}