| 21 | namespace singa { |
| 22 | |
| 23 | Tensor Accuracy::Match(const Tensor& predict, const vector<int>& target) { |
| 24 | Tensor prediction(predict.shape()); |
| 25 | prediction.CopyData(predict); |
| 26 | size_t batchsize = target.size(); |
| 27 | size_t nb_classes = prediction.Size() / batchsize; |
| 28 | // each row of prediction is the prob distribution for one sample |
| 29 | CHECK_EQ(prediction.shape().at(0), batchsize); |
| 30 | // TODO(wangwei) CloneToDevice(host); |
| 31 | const float* prob = prediction.data<float>(); |
| 32 | float* score = new float[batchsize]; |
| 33 | memset(score, 0, batchsize * sizeof(float)); |
| 34 | for (size_t b = 0; b < batchsize; b++) { |
| 35 | vector<std::pair<float, int>> prob_class; |
| 36 | for (size_t c = 0; c < nb_classes; c++) { |
| 37 | prob_class.push_back(std::make_pair(prob[b * nb_classes + c], c)); |
| 38 | } |
| 39 | std::partial_sort(prob_class.begin(), prob_class.begin() + top_k_, |
| 40 | prob_class.end(), std::greater<std::pair<float, int>>()); |
| 41 | |
| 42 | for (size_t k = 0; k < top_k_; k++) |
| 43 | if (prob_class.at(k).second == target.at(b)) score[b] = 1; |
| 44 | } |
| 45 | Tensor ret(Shape{batchsize}); |
| 46 | ret.CopyDataFromHostPtr(score, batchsize); |
| 47 | delete [] score; |
| 48 | return ret; |
| 49 | } |
| 50 | |
| 51 | // TODO(wangwei) consider multi-label cases, where target is of shape |
| 52 | // nb_samples * nb_classes |