diff --git a/src/caffe/test/test_crop_layer.cpp b/src/caffe/test/test_crop_layer.cpp index ba962e4c6f1..45f24e2ee8d 100644 --- a/src/caffe/test/test_crop_layer.cpp +++ b/src/caffe/test/test_crop_layer.cpp @@ -18,18 +18,18 @@ class CropLayerTest : public MultiDeviceTest { protected: CropLayerTest() - : blob_bottom_0_(new Blob(2, 5, 6, 5)), - blob_bottom_1_(new Blob(2, 4, 5, 3)), + : blob_bottom_0_(new Blob(2, 4, 5, 4)), + blob_bottom_1_(new Blob(2, 3, 4, 2)), blob_top_(new Blob()) {} virtual void SetUp() { // fill the values - for (int i = 0; i < this->blob_bottom_0_->count(); ++i) { - this->blob_bottom_0_->mutable_cpu_data()[i] = i; - } - + FillerParameter filler_param; + GaussianFiller filler(filler_param); + filler.Fill(this->blob_bottom_0_); + filler.Fill(this->blob_bottom_1_); - blob_bottom_vec_0_.push_back(blob_bottom_0_); - blob_bottom_vec_0_.push_back(blob_bottom_1_); + blob_bottom_vec_.push_back(blob_bottom_0_); + blob_bottom_vec_.push_back(blob_bottom_1_); blob_top_vec_.push_back(blob_top_); } @@ -41,7 +41,7 @@ class CropLayerTest : public MultiDeviceTest { Blob* const blob_bottom_0_; Blob* const blob_bottom_1_; Blob* const blob_top_; - vector*> blob_bottom_vec_0_; + vector*> blob_bottom_vec_; vector*> blob_top_vec_; }; @@ -51,11 +51,10 @@ TYPED_TEST_CASE(CropLayerTest, TestDtypesAndDevices); TYPED_TEST(CropLayerTest, TestSetupShapeAll) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; - // Crop all dimensions layer_param.mutable_crop_param()->set_axis(0); CropLayer layer(layer_param); - layer.SetUp(this->blob_bottom_vec_0_, this->blob_top_vec_); + layer.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); for (int i = 0; i < this->blob_top_->num_axes(); ++i) { EXPECT_EQ(this->blob_bottom_1_->shape(i), this->blob_top_->shape(i)); } @@ -66,7 +65,7 @@ TYPED_TEST(CropLayerTest, TestSetupShapeDefault) { LayerParameter layer_param; // Crop last two dimensions, axis is 2 by default CropLayer layer(layer_param); - layer.SetUp(this->blob_bottom_vec_0_, this->blob_top_vec_); + layer.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); for (int i = 0; i < this->blob_top_->num_axes(); ++i) { if (i < 2) { EXPECT_EQ(this->blob_bottom_0_->shape(i), this->blob_top_->shape(i)); @@ -82,7 +81,7 @@ TYPED_TEST(CropLayerTest, TestSetupShapeNegativeIndexing) { // Crop last dimension by negative indexing layer_param.mutable_crop_param()->set_axis(-1); CropLayer layer(layer_param); - layer.SetUp(this->blob_bottom_vec_0_, this->blob_top_vec_); + layer.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); for (int i = 0; i < this->blob_top_->num_axes(); ++i) { if (i < 3) { EXPECT_EQ(this->blob_bottom_0_->shape(i), this->blob_top_->shape(i)); @@ -92,15 +91,13 @@ TYPED_TEST(CropLayerTest, TestSetupShapeNegativeIndexing) { } } - -TYPED_TEST(CropLayerTest, TestForwardNum) { +TYPED_TEST(CropLayerTest, TestCropAll) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; layer_param.mutable_crop_param()->set_axis(0); - CropLayer layer(layer_param); - layer.SetUp(this->blob_bottom_vec_0_, this->blob_top_vec_); - layer.Forward(this->blob_bottom_vec_0_, this->blob_top_vec_); + layer.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); + layer.Forward(this->blob_bottom_vec_, this->blob_top_vec_); for (int n = 0; n < this->blob_bottom_0_->num(); ++n) { for (int c = 0; c < this->blob_bottom_0_->channels(); ++c) { for (int h = 0; h < this->blob_bottom_0_->height(); ++h) { @@ -118,7 +115,7 @@ TYPED_TEST(CropLayerTest, TestForwardNum) { } } -TYPED_TEST(CropLayerTest, TestForwardNumOffsets) { +TYPED_TEST(CropLayerTest, TestCropAllOffset) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; layer_param.mutable_crop_param()->set_axis(0); @@ -127,8 +124,8 @@ TYPED_TEST(CropLayerTest, TestForwardNumOffsets) { layer_param.mutable_crop_param()->add_offset(1); layer_param.mutable_crop_param()->add_offset(2); CropLayer layer(layer_param); - layer.SetUp(this->blob_bottom_vec_0_, this->blob_top_vec_); - layer.Forward(this->blob_bottom_vec_0_, this->blob_top_vec_); + layer.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); + layer.Forward(this->blob_bottom_vec_, this->blob_top_vec_); for (int n = 0; n < this->blob_bottom_0_->num(); ++n) { for (int c = 0; c < this->blob_bottom_0_->channels(); ++c) { for (int h = 0; h < this->blob_bottom_0_->height(); ++h) { @@ -138,7 +135,7 @@ TYPED_TEST(CropLayerTest, TestForwardNumOffsets) { h < this->blob_top_->shape(2) && w < this->blob_top_->shape(3) ) { EXPECT_EQ(this->blob_top_->data_at(n, c, h, w), - this->blob_bottom_0_->data_at(n+0, c+1, h+1, w+2)); + this->blob_bottom_0_->data_at(n, c+1, h+1, w+2)); } } } @@ -146,36 +143,25 @@ TYPED_TEST(CropLayerTest, TestForwardNumOffsets) { } } -TYPED_TEST(CropLayerTest, TestGradientNum) { +TYPED_TEST(CropLayerTest, TestCropHW) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; + layer_param.mutable_crop_param()->set_axis(2); + layer_param.mutable_crop_param()->add_offset(1); + layer_param.mutable_crop_param()->add_offset(2); CropLayer layer(layer_param); - - layer.SetUp(this->blob_bottom_vec_0_, this->blob_top_vec_); - layer.Forward(this->blob_bottom_vec_0_, this->blob_top_vec_); - - // Copy top data into diff - caffe_copy(this->blob_top_->count(), this->blob_top_->cpu_data(), - this->blob_top_->mutable_cpu_diff()); - - // Do backward pass - vector propagate_down(2, true); - layer.Backward(this->blob_top_vec_, propagate_down, this->blob_bottom_vec_0_); - - - // Check results + layer.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); + layer.Forward(this->blob_bottom_vec_, this->blob_top_vec_); for (int n = 0; n < this->blob_bottom_0_->num(); ++n) { for (int c = 0; c < this->blob_bottom_0_->channels(); ++c) { for (int h = 0; h < this->blob_bottom_0_->height(); ++h) { for (int w = 0; w < this->blob_bottom_0_->width(); ++w) { - if ( n < this->blob_top_->shape(0) && + if (n < this->blob_top_->shape(0) && c < this->blob_top_->shape(1) && h < this->blob_top_->shape(2) && - w < this->blob_top_->shape(3) ) { - EXPECT_EQ(this->blob_bottom_0_->diff_at(n, c, h, w), - this->blob_bottom_0_->data_at(n, c, h, w)); - } else { - EXPECT_EQ(this->blob_bottom_0_->diff_at(n, c, h, w), 0); + w < this->blob_top_->shape(3)) { + EXPECT_EQ(this->blob_top_->data_at(n, c, h, w), + this->blob_bottom_0_->data_at(n, c, h+1, w+2)); } } } @@ -183,41 +169,50 @@ TYPED_TEST(CropLayerTest, TestGradientNum) { } } -TYPED_TEST(CropLayerTest, TestGradientNumOffset) { +TYPED_TEST(CropLayerTest, TestCrop5D) { typedef typename TypeParam::Dtype Dtype; + // Add dimension to each bottom for >4D check + vector bottom_0_shape = this->blob_bottom_0_->shape(); + vector bottom_1_shape = this->blob_bottom_1_->shape(); + bottom_0_shape.push_back(2); + bottom_1_shape.push_back(1); + this->blob_bottom_0_->Reshape(bottom_0_shape); + this->blob_bottom_1_->Reshape(bottom_1_shape); + FillerParameter filler_param; + GaussianFiller filler(filler_param); + filler.Fill(this->blob_bottom_0_); + filler.Fill(this->blob_bottom_1_); + // Make layer LayerParameter layer_param; - layer_param.mutable_crop_param()->set_axis(0); - layer_param.mutable_crop_param()->add_offset(0); - layer_param.mutable_crop_param()->add_offset(1); + layer_param.mutable_crop_param()->set_axis(2); layer_param.mutable_crop_param()->add_offset(1); layer_param.mutable_crop_param()->add_offset(2); + layer_param.mutable_crop_param()->add_offset(0); CropLayer layer(layer_param); - - layer.SetUp(this->blob_bottom_vec_0_, this->blob_top_vec_); - layer.Forward(this->blob_bottom_vec_0_, this->blob_top_vec_); - - // Copy top data into diff - caffe_copy(this->blob_top_->count(), this->blob_top_->cpu_data(), - this->blob_top_->mutable_cpu_diff()); - - // Do backward pass - vector propagate_down(2, true); - layer.Backward(this->blob_top_vec_, propagate_down, this->blob_bottom_vec_0_); - - - // Check results - for (int n = 0; n < this->blob_bottom_0_->num(); ++n) { - for (int c = 0; c < this->blob_bottom_0_->channels(); ++c) { - for (int h = 0; h < this->blob_bottom_0_->height(); ++h) { - for (int w = 0; w < this->blob_bottom_0_->width(); ++w) { - if ( 0 <= n && n < 0 + this->blob_top_->shape(0) && - 1 <= c && c < 1 + this->blob_top_->shape(1) && - 1 <= h && h < 1 + this->blob_top_->shape(2) && - 2 <= w && w < 2 + this->blob_top_->shape(3) ) { - EXPECT_EQ(this->blob_bottom_0_->diff_at(n, c, h, w), - this->blob_bottom_0_->data_at(n, c, h, w)); - } else { - EXPECT_EQ(this->blob_bottom_0_->diff_at(n, c, h, w), 0); + layer.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); + layer.Forward(this->blob_bottom_vec_, this->blob_top_vec_); + vector bottom_idx = vector(5, 0); + vector top_idx = vector(5, 0); + for (int n = 0; n < this->blob_bottom_0_->shape(0); ++n) { + for (int c = 0; c < this->blob_bottom_0_->shape(1); ++c) { + for (int z = 0; z < this->blob_bottom_0_->shape(2); ++z) { + for (int h = 0; h < this->blob_bottom_0_->shape(3); ++h) { + for (int w = 0; w < this->blob_bottom_0_->shape(4); ++w) { + if (n < this->blob_top_->shape(0) && + c < this->blob_top_->shape(1) && + z < this->blob_top_->shape(2) && + h < this->blob_top_->shape(3) && + w < this->blob_top_->shape(4)) { + bottom_idx[0] = top_idx[0] = n; + bottom_idx[1] = top_idx[1] = c; + bottom_idx[2] = z; + bottom_idx[3] = h; + bottom_idx[4] = top_idx[4] = w; + top_idx[2] = z+1; + top_idx[3] = h+2; + EXPECT_EQ(this->blob_top_->data_at(bottom_idx), + this->blob_bottom_0_->data_at(top_idx)); + } } } } @@ -225,4 +220,46 @@ TYPED_TEST(CropLayerTest, TestGradientNumOffset) { } } +TYPED_TEST(CropLayerTest, TestCropAllGradient) { + typedef typename TypeParam::Dtype Dtype; + LayerParameter layer_param; + layer_param.mutable_crop_param()->set_axis(0); + CropLayer layer(layer_param); + GradientChecker checker(1e-2, 1e-3); + checker.CheckGradientExhaustive(&layer, this->blob_bottom_vec_, + this->blob_top_vec_); +} + +TYPED_TEST(CropLayerTest, TestCropHWGradient) { + typedef typename TypeParam::Dtype Dtype; + LayerParameter layer_param; + layer_param.mutable_crop_param()->set_axis(2); + layer_param.mutable_crop_param()->add_offset(1); + layer_param.mutable_crop_param()->add_offset(2); + CropLayer layer(layer_param); + GradientChecker checker(1e-2, 1e-3); + checker.CheckGradientExhaustive(&layer, this->blob_bottom_vec_, + this->blob_top_vec_); +} + +TYPED_TEST(CropLayerTest, TestCrop5DGradient) { + typedef typename TypeParam::Dtype Dtype; + LayerParameter layer_param; + layer_param.mutable_crop_param()->set_axis(2); + layer_param.mutable_crop_param()->add_offset(1); + layer_param.mutable_crop_param()->add_offset(2); + layer_param.mutable_crop_param()->add_offset(0); + CropLayer layer(layer_param); + // Add dimension to each bottom for >4D check + vector bottom_0_shape = this->blob_bottom_0_->shape(); + vector bottom_1_shape = this->blob_bottom_1_->shape(); + bottom_0_shape.push_back(2); + bottom_1_shape.push_back(1); + this->blob_bottom_0_->Reshape(bottom_0_shape); + this->blob_bottom_1_->Reshape(bottom_1_shape); + GradientChecker checker(1e-2, 1e-3); + checker.CheckGradientExhaustive(&layer, this->blob_bottom_vec_, + this->blob_top_vec_); +} + } // namespace caffe