| 46 | |
| 47 | template <typename Dtype> |
| 48 | void AccuracyLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, |
| 49 | const vector<Blob<Dtype>*>& top) { |
| 50 | Dtype accuracy = 0; |
| 51 | const Dtype* bottom_data = bottom[0]->cpu_data(); |
| 52 | const Dtype* bottom_label = bottom[1]->cpu_data(); |
| 53 | const int dim = bottom[0]->count() / outer_num_; |
| 54 | const int num_labels = bottom[0]->shape(label_axis_); |
| 55 | vector<Dtype> maxval(top_k_+1); |
| 56 | vector<int> max_id(top_k_+1); |
| 57 | if (top.size() > 1) { |
| 58 | caffe_set(nums_buffer_.count(), Dtype(0), nums_buffer_.mutable_cpu_data()); |
| 59 | caffe_set(top[1]->count(), Dtype(0), top[1]->mutable_cpu_data()); |
| 60 | } |
| 61 | int count = 0; |
| 62 | for (int i = 0; i < outer_num_; ++i) { |
| 63 | for (int j = 0; j < inner_num_; ++j) { |
| 64 | const int label_value = |
| 65 | static_cast<int>(bottom_label[i * inner_num_ + j]); |
| 66 | if (has_ignore_label_ && label_value == ignore_label_) { |
| 67 | continue; |
| 68 | } |
| 69 | if (top.size() > 1) ++nums_buffer_.mutable_cpu_data()[label_value]; |
| 70 | DCHECK_GE(label_value, 0); |
| 71 | DCHECK_LT(label_value, num_labels); |
| 72 | // Top-k accuracy |
| 73 | std::vector<std::pair<Dtype, int> > bottom_data_vector; |
| 74 | for (int k = 0; k < num_labels; ++k) { |
| 75 | bottom_data_vector.push_back(std::make_pair( |
| 76 | bottom_data[i * dim + k * inner_num_ + j], k)); |
| 77 | } |
| 78 | std::partial_sort( |
| 79 | bottom_data_vector.begin(), bottom_data_vector.begin() + top_k_, |
| 80 | bottom_data_vector.end(), std::greater<std::pair<Dtype, int> >()); |
| 81 | // check if true label is in top k predictions |
| 82 | for (int k = 0; k < top_k_; k++) { |
| 83 | if (bottom_data_vector[k].second == label_value) { |
| 84 | ++accuracy; |
| 85 | if (top.size() > 1) ++top[1]->mutable_cpu_data()[label_value]; |
| 86 | break; |
| 87 | } |
| 88 | } |
| 89 | ++count; |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | // LOG(INFO) << "Accuracy: " << accuracy; |
| 94 | top[0]->mutable_cpu_data()[0] = accuracy / count; |
| 95 | if (top.size() > 1) { |
| 96 | for (int i = 0; i < top[1]->count(); ++i) { |
| 97 | top[1]->mutable_cpu_data()[i] = |
| 98 | nums_buffer_.cpu_data()[i] == 0 ? 0 |
| 99 | : top[1]->cpu_data()[i] / nums_buffer_.cpu_data()[i]; |
| 100 | } |
| 101 | } |
| 102 | // Accuracy layer should not be used as a loss function. |
| 103 | } |
| 104 | |
| 105 | INSTANTIATE_CLASS(AccuracyLayer); |