void AccuracyLayer<Ftype, Btype>::Forward_cpu(const vector<Blob*>& bottom, const vector<Blob*>& top) { float accuracy = 0.F; const Ftype* bottom_data = bottom[0]->cpu_data<Ftype>(); const Ftype* bottom_label = bottom[1]->cpu_data<Ftype>(); const int dim = bottom[0]->count() / outer_num_; const int num_labels = bottom[0]->shape(label_axis_); if (top.size() > 1) { nums_buffer_.set_data(0.F); top[1]->set_data(0.F); } std::vector<std::pair<float, int>> bottom_data_vector(num_labels); 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 for (int k = 0; k < num_labels; ++k) { bottom_data_vector[k] = std::make_pair( static_cast<float>(bottom_data[i * dim + k * inner_num_ + j]), k); } std::partial_sort( bottom_data_vector.begin(), bottom_data_vector.begin() + top_k_, bottom_data_vector.end(), std::greater<std::pair<float, 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 += 1.F; if (top.size() > 1) { Ftype* top_label = top[1]->mutable_cpu_data<Ftype>(); top_label[label_value] = top_label[label_value] + 1.; } break; } } ++count; } } top[0]->mutable_cpu_data<Ftype>()[0] = accuracy / count; if (top.size() > 1) { for (int i = 0; i < top[1]->count(); ++i) { const float num = nums_buffer_.cpu_data()[i]; Ftype* top_label = top[1]->mutable_cpu_data<Ftype>(); top_label[i] = num == 0.F ? 0. : top_label[i] / num; } } // Accuracy layer should not be used as a loss function. }
void ArgMaxLayer<Dtype, MItype, MOtype>::Forward_cpu( const vector<Blob<MItype>*>& bottom, const vector<Blob<MOtype>*>& top) { const Dtype* bottom_data = bottom[0]->cpu_data(); Dtype* top_data = top[0]->mutable_cpu_data(); int_tp dim, axis_dist; if (has_axis_) { dim = bottom[0]->shape(axis_); // Distance between values of axis in blob axis_dist = bottom[0]->count(axis_) / dim; } else { dim = bottom[0]->count(1); axis_dist = 1; } int_tp num = bottom[0]->count() / dim; vector<std::pair<Dtype, int_tp> > bottom_data_vector(dim); for (int_tp i = 0; i < num; ++i) { for (int_tp j = 0; j < dim; ++j) { bottom_data_vector[j] = make_pair( bottom_data[(i / axis_dist * dim + j) * axis_dist + i % axis_dist], j); } std::partial_sort( bottom_data_vector.begin(), bottom_data_vector.begin() + top_k_, bottom_data_vector.end(), std::greater<std::pair<Dtype, int_tp> >()); for (int_tp j = 0; j < top_k_; ++j) { if (out_max_val_) { if (has_axis_) { // Produces max_val per axis top_data[(i / axis_dist * top_k_ + j) * axis_dist + i % axis_dist] = bottom_data_vector[j].first; } else { // Produces max_ind and max_val top_data[2 * i * top_k_ + j] = bottom_data_vector[j].second; top_data[2 * i * top_k_ + top_k_ + j] = bottom_data_vector[j].first; } } else { // Produces max_ind per axis top_data[(i / axis_dist * top_k_ + j) * axis_dist + i % axis_dist] = bottom_data_vector[j].second; } } } }