From 6ea7a661379571a4e912f59a73c9c2037671eb21 Mon Sep 17 00:00:00 2001 From: max argus Date: Sun, 22 Feb 2015 21:00:38 +0000 Subject: [PATCH] AccuracyLayer: add ignore_label param --- include/caffe/loss_layers.hpp | 6 ++++++ src/caffe/layers/accuracy_layer.cpp | 19 ++++++++++++++++--- src/caffe/proto/caffe.proto | 3 +++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/include/caffe/loss_layers.hpp b/include/caffe/loss_layers.hpp index da2c4be1e61..d3eecd2e510 100644 --- a/include/caffe/loss_layers.hpp +++ b/include/caffe/loss_layers.hpp @@ -79,7 +79,13 @@ class AccuracyLayer : public Layer { } int label_axis_, outer_num_, inner_num_; + int top_k_; + + /// Whether to ignore instances with a certain label. + bool has_ignore_label_; + /// The label indicating that an instance should be ignored. + int ignore_label_; }; /** diff --git a/src/caffe/layers/accuracy_layer.cpp b/src/caffe/layers/accuracy_layer.cpp index 6084ee7524b..90aad675ed3 100644 --- a/src/caffe/layers/accuracy_layer.cpp +++ b/src/caffe/layers/accuracy_layer.cpp @@ -14,6 +14,12 @@ template void AccuracyLayer::LayerSetUp( const vector*>& bottom, const vector*>& top) { top_k_ = this->layer_param_.accuracy_param().top_k(); + + has_ignore_label_ = + this->layer_param_.accuracy_param().has_ignore_label(); + if (has_ignore_label_) { + ignore_label_ = this->layer_param_.accuracy_param().ignore_label(); + } } template @@ -44,8 +50,16 @@ void AccuracyLayer::Forward_cpu(const vector*>& bottom, const int num_labels = bottom[0]->shape(label_axis_); vector maxval(top_k_+1); vector max_id(top_k_+1); + 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(bottom_label[i * inner_num_ + j]); + if (has_ignore_label_ && label_value == ignore_label_) { + continue; + } + DCHECK_GE(label_value, 0); + DCHECK_LT(label_value, num_labels); // Top-k accuracy std::vector > bottom_data_vector; for (int k = 0; k < num_labels; ++k) { @@ -56,19 +70,18 @@ void AccuracyLayer::Forward_cpu(const vector*>& bottom, bottom_data_vector.begin(), bottom_data_vector.begin() + top_k_, bottom_data_vector.end(), std::greater >()); // check if true label is in top k predictions - const int label_value = - static_cast(bottom_label[i * inner_num_ + j]); for (int k = 0; k < top_k_; k++) { if (bottom_data_vector[k].second == label_value) { ++accuracy; break; } } + ++count; } } // LOG(INFO) << "Accuracy: " << accuracy; - top[0]->mutable_cpu_data()[0] = accuracy / outer_num_ / inner_num_; + top[0]->mutable_cpu_data()[0] = accuracy / count; // Accuracy layer should not be used as a loss function. } diff --git a/src/caffe/proto/caffe.proto b/src/caffe/proto/caffe.proto index 7792695abfa..e523efa50f1 100644 --- a/src/caffe/proto/caffe.proto +++ b/src/caffe/proto/caffe.proto @@ -374,6 +374,9 @@ message AccuracyParameter { // (N x C x H x W), the label blob is expected to contain N*H*W ground truth // labels with integer values in {0, 1, ..., C-1}. optional int32 axis = 2 [default = 1]; + + // If specified, ignore instances with the given label. + optional int32 ignore_label = 3; } // Message that stores parameters used by ArgMaxLayer