1 #include "caffe2/operators/apmeter_op.h" 6 void APMeterOp<float, CPUContext>::BufferPredictions(
11 if (buffers_.empty()) {
13 buffers_.resize(D, std::vector<BufferDataType>(buffer_size_));
15 DCHECK_EQ(buffers_.size(), D);
18 if (N > buffer_size_) {
19 XData = XData + (N - buffer_size_) * D;
20 labelData = labelData + (N - buffer_size_) * D;
25 int space_to_reclaim = buffer_used_ + N - buffer_size_;
26 if (space_to_reclaim > 0) {
27 for (
auto& buffer : buffers_) {
29 buffer.begin(), buffer.begin() + space_to_reclaim, buffer.end());
31 buffer_used_ -= space_to_reclaim;
35 for (
int i = 0; i < D; i++) {
36 for (
int j = 0; j < N; j++) {
37 buffers_[i][buffer_used_ + j].first = XData[j * D + i];
38 buffers_[i][buffer_used_ + j].second = labelData[j * D + i];
46 bool APMeterOp<float, CPUContext>::RunOnDevice() {
47 auto& X = Input(PREDICTION);
48 auto& label = Input(LABEL);
51 DCHECK_EQ(X.dim(), 2);
54 DCHECK_EQ(label.dim(), 2);
55 DCHECK_EQ(label.dim32(0), N);
56 DCHECK_EQ(label.dim32(1), D);
57 auto* Y = Output(0, {D}, at::dtype<float>());
59 const auto* Xdata = X.data<
float>();
60 const auto* labelData = label.data<
int>();
61 auto* Ydata = Y->template mutable_data<float>();
63 BufferPredictions(Xdata, labelData, N, D);
66 for (
int i = 0; i < D; i++) {
67 auto& buffer = buffers_[i];
71 buffer.begin() + buffer_used_,
72 [](
const BufferDataType& p1,
const BufferDataType& p2) {
73 return p1.first > p2.first;
77 float precision_sum = 0.0;
79 for (
int j = 0; j < buffer_used_; j++) {
80 tp_sum += buffer[j].second;
81 if (buffer[j].second == 1) {
83 precision_sum += tp_sum / (j + 1);
88 Ydata[i] = precision_sum / std::max(1, ntruth);
95 REGISTER_CPU_OPERATOR(APMeter, APMeterOp<float, CPUContext>);
97 OPERATOR_SCHEMA(APMeter)
100 .ScalarType(TensorProto::FLOAT)
102 APMeter computes Average Precision for binary or multi-class classification. 103 It takes two inputs: prediction scores P of size (n_samples x n_classes), and 104 true labels Y of size (n_samples x n_classes). It returns a single float number 105 per class for the average precision of that class. 109 "(int32_t) indicates how many predictions should the op buffer. " 114 "2-D tensor (Tensor<float>) of size (num_samples x" 115 "num_classes) containing prediction scores")
119 "2-D tensor (Tensor<float>) of size (num_samples) " 120 "containing true labels for each sample")
124 "1-D tensor (Tensor<float>) of size num_classes containing " 125 "average precision for each class");
127 SHOULD_NOT_DO_GRADIENT(APMeter);
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...