Add more test cases for the accuracy layer
authorKai Li <kaili_kloud@163.com>
Thu, 10 Jul 2014 01:38:03 +0000 (09:38 +0800)
committerKai Li <kaili_kloud@163.com>
Sat, 19 Jul 2014 16:26:41 +0000 (00:26 +0800)
src/caffe/test/test_accuracy_layer.cpp

index 40b0874..5023a80 100644 (file)
@@ -9,6 +9,7 @@
 #include "caffe/blob.hpp"
 #include "caffe/common.hpp"
 #include "caffe/filler.hpp"
+#include "caffe/util/rng.hpp"
 #include "caffe/vision_layers.hpp"
 
 #include "caffe/test/test_caffe_main.hpp"
@@ -19,8 +20,8 @@ template <typename Dtype>
 class AccuracyLayerTest : public ::testing::Test {
  protected:
   AccuracyLayerTest()
-      : blob_bottom_data_(new Blob<Dtype>(2, 10, 1, 1)),
-        blob_bottom_label_(new Blob<Dtype>(2, 1, 1, 1)),
+      : blob_bottom_data_(new Blob<Dtype>(100, 10, 1, 1)),
+        blob_bottom_label_(new Blob<Dtype>(100, 1, 1, 1)),
         blob_top_(new Blob<Dtype>()),
         top_k_(3) {
     // fill the probability values
@@ -28,28 +29,14 @@ class AccuracyLayerTest : public ::testing::Test {
     GaussianFiller<Dtype> filler(filler_param);
     filler.Fill(this->blob_bottom_data_);
 
-    // set the labels; first label is set to max-probability index
-    Dtype m_val = -FLT_MAX;
-    int m_id = 0;
-    for (int i = 0; i < 10; i++)
-      if (blob_bottom_data_->data_at(0, i, 0, 0) > m_val) {
-        m_val = blob_bottom_data_->data_at(0, i, 0, 0);
-        m_id = i;
-      }
+    const unsigned int prefetch_rng_seed = caffe_rng_rand();
+    shared_ptr<Caffe::RNG> rng(new Caffe::RNG(prefetch_rng_seed));
+    caffe::rng_t* prefetch_rng =
+          static_cast<caffe::rng_t*>(rng->generator());
     Dtype* label_data = blob_bottom_label_->mutable_cpu_data();
-    int offset = blob_bottom_label_->offset(0);
-    label_data[offset] = m_id;
-
-    // set the labels; second label is set to min-probability index
-    m_val = FLT_MAX;
-    m_id = 0;
-    for (int i = 0; i < 10; i++)
-      if (blob_bottom_data_->data_at(1, i, 0, 0) < m_val) {
-        m_val = blob_bottom_data_->data_at(1, i, 0, 0);
-        m_id = i;
-      }
-    offset = blob_bottom_label_->offset(1);
-    label_data[offset] = m_id;
+    for (int i = 0; i < 100; ++i) {
+      label_data[i] = (*prefetch_rng)() % 10;
+    }
 
     blob_bottom_vec_.push_back(blob_bottom_data_);
     blob_bottom_vec_.push_back(blob_bottom_label_);
@@ -70,16 +57,85 @@ class AccuracyLayerTest : public ::testing::Test {
 
 TYPED_TEST_CASE(AccuracyLayerTest, TestDtypes);
 
+TYPED_TEST(AccuracyLayerTest, TestSetup) {
+  LayerParameter layer_param;
+  AccuracyLayer<TypeParam> layer(layer_param);
+  layer.SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
+  EXPECT_EQ(this->blob_top_->num(), 1);
+  EXPECT_EQ(this->blob_top_->channels(), 1);
+  EXPECT_EQ(this->blob_top_->height(), 1);
+  EXPECT_EQ(this->blob_top_->width(), 1);
+}
+
+TYPED_TEST(AccuracyLayerTest, TestSetupTopK) {
+  LayerParameter layer_param;
+  AccuracyParameter* accuracy_param =
+      layer_param.mutable_accuracy_param();
+  accuracy_param->set_top_k(5);
+  AccuracyLayer<TypeParam> layer(layer_param);
+  layer.SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
+  EXPECT_EQ(this->blob_top_->num(), 1);
+  EXPECT_EQ(this->blob_top_->channels(), 1);
+  EXPECT_EQ(this->blob_top_->height(), 1);
+  EXPECT_EQ(this->blob_top_->width(), 1);
+}
+
 TYPED_TEST(AccuracyLayerTest, TestForwardCPU) {
   LayerParameter layer_param;
+  Caffe::set_mode(Caffe::CPU);
+  AccuracyLayer<TypeParam> layer(layer_param);
+  layer.SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
+  layer.Forward(this->blob_bottom_vec_, &(this->blob_top_vec_));
+
+  TypeParam max_value;
+  int max_id;
+  int num_correct_labels = 0;
+  for (int i = 0; i < 100; ++i) {
+    max_value = -FLT_MAX;
+    max_id = 0;
+    for (int j = 0; j < 10; ++j) {
+      if (this->blob_bottom_data_->data_at(i, j, 0, 0) > max_value) {
+        max_value = this->blob_bottom_data_->data_at(i, j, 0, 0);
+        max_id = j;
+      }
+    }
+    if (max_id == this->blob_bottom_label_->data_at(i, 0, 0, 0)) {
+      ++num_correct_labels;
+    }
+  }
+  EXPECT_NEAR(this->blob_top_->data_at(0, 0, 0, 0),
+              num_correct_labels / 100.0, 1e-4);
+}
+
+TYPED_TEST(AccuracyLayerTest, TestForwardCPUTopK) {
+  LayerParameter layer_param;
   AccuracyParameter* accuracy_param = layer_param.mutable_accuracy_param();
   accuracy_param->set_top_k(this->top_k_);
   AccuracyLayer<TypeParam> layer(layer_param);
   layer.SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
   layer.Forward(this->blob_bottom_vec_, &(this->blob_top_vec_));
 
-  // Output accuracy should be ~0.5
-  EXPECT_NEAR(this->blob_top_->data_at(0, 0, 0, 0), 0.5, 1e-4);
+  TypeParam current_value;
+  int current_rank;
+  int num_correct_labels = 0;
+  for (int i = 0; i < 100; ++i) {
+    for (int j = 0; j < 10; ++j) {
+      current_value = this->blob_bottom_data_->data_at(i, j, 0, 0);
+      current_rank = 0;
+      for (int k = 0; k < 10; ++k) {
+        if (this->blob_bottom_data_->data_at(i, k, 0, 0) > current_value) {
+          ++current_rank;
+        }
+      }
+      if (current_rank < this->top_k_ &&
+          j == this->blob_bottom_label_->data_at(i, 0, 0, 0)) {
+        ++num_correct_labels;
+      }
+    }
+  }
+
+  EXPECT_NEAR(this->blob_top_->data_at(0, 0, 0, 0),
+              num_correct_labels / 100.0, 1e-4);
 }
 
 }  // namespace caffe