diff --git a/include/caffe/loss_layers.hpp b/include/caffe/loss_layers.hpp index 9fe58cd97bc..89c43c69415 100644 --- a/include/caffe/loss_layers.hpp +++ b/include/caffe/loss_layers.hpp @@ -41,8 +41,15 @@ class AccuracyLayer : public Layer { return LayerParameter_LayerType_ACCURACY; } - virtual inline int ExactNumBottomBlobs() const { return 2; } - virtual inline int ExactNumTopBlobs() const { return 1; } + // AccuracyLayer takes 2-3 bottom Blobs; if there are 3 the second and third + // are compared to compute a 0/1 label. (Otherwise the label comes directly + // from the second.) + virtual inline int ExactNumBottomBlobs() const { return -1; } + virtual inline int MinBottomBlobs() const { return 2; } + virtual inline int MaxBottomBlobs() const { return 3; } + + private: + int ComputeLabel(const vector*>& bottom, int i); protected: /** diff --git a/src/caffe/layers/accuracy_layer.cpp b/src/caffe/layers/accuracy_layer.cpp index 399cf2a3585..ce6d50be670 100644 --- a/src/caffe/layers/accuracy_layer.cpp +++ b/src/caffe/layers/accuracy_layer.cpp @@ -10,6 +10,23 @@ namespace caffe { +template +int AccuracyLayer::ComputeLabel(const vector*>& bottom, int i) { + int label; + if (bottom.size() == 2) { + label = static_cast(bottom[1]->cpu_data()[i]); + } else { // bottom.size() == 3 + // label == 1 if bottom[1] == bottom[2] (same) + // label == 0 if bottom[1] != bottom[2] (not same) + label = (bottom[1]->cpu_data()[i] == + bottom[2]->cpu_data()[i]) ? 1 : 0; + + if (i == 0) { + } + } + return label; +} + template void AccuracyLayer::LayerSetUp( const vector*>& bottom, const vector*>& top) { @@ -34,12 +51,13 @@ void AccuracyLayer::Forward_cpu(const vector*>& bottom, const vector*>& top) { Dtype accuracy = 0; const Dtype* bottom_data = bottom[0]->cpu_data(); - const Dtype* bottom_label = bottom[1]->cpu_data(); int num = bottom[0]->num(); int dim = bottom[0]->count() / bottom[0]->num(); vector maxval(top_k_+1); vector max_id(top_k_+1); + int label; for (int i = 0; i < num; ++i) { + label = ComputeLabel(bottom, i); // Top-k accuracy std::vector > bottom_data_vector; for (int j = 0; j < dim; ++j) { @@ -51,7 +69,7 @@ void AccuracyLayer::Forward_cpu(const vector*>& bottom, bottom_data_vector.end(), std::greater >()); // check if true label is in top k predictions for (int k = 0; k < top_k_; k++) { - if (bottom_data_vector[k].second == static_cast(bottom_label[i])) { + if (bottom_data_vector[k].second == label) { ++accuracy; break; }