#include #include #include "gtest/gtest.h" #include "caffe/blob.hpp" #include "caffe/common.hpp" #include "caffe/filler.hpp" #include "caffe/vision_layers.hpp" #include "caffe/test/test_caffe_main.hpp" #include "caffe/test/test_gradient_check_util.hpp" namespace caffe { template class TileLayerTest : public MultiDeviceTest { typedef typename TypeParam::Dtype Dtype; protected: TileLayerTest() : blob_bottom_(new Blob(2, 3, 4, 5)), blob_top_(new Blob()) {} virtual void SetUp() { blob_bottom_vec_.push_back(blob_bottom_); blob_top_vec_.push_back(blob_top_); FillerParameter filler_param; filler_param.set_mean(0.0); filler_param.set_std(1.0); GaussianFiller filler(filler_param); filler.Fill(blob_bottom_); } virtual ~TileLayerTest() { delete blob_bottom_; delete blob_top_; } Blob* const blob_bottom_; Blob* const blob_top_; vector*> blob_bottom_vec_; vector*> blob_top_vec_; }; TYPED_TEST_CASE(TileLayerTest, TestDtypesAndDevices); TYPED_TEST(TileLayerTest, TestTrivialSetup) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; const int kNumTiles = 1; layer_param.mutable_tile_param()->set_tiles(kNumTiles); for (int i = 0; i < this->blob_bottom_->num_axes(); ++i) { layer_param.mutable_tile_param()->set_axis(i); TileLayer layer(layer_param); layer.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); ASSERT_EQ(this->blob_top_->num_axes(), this->blob_bottom_->num_axes()); for (int j = 0; j < this->blob_bottom_->num_axes(); ++j) { EXPECT_EQ(this->blob_top_->shape(j), this->blob_bottom_->shape(j)); } } } TYPED_TEST(TileLayerTest, TestSetup) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; const int kNumTiles = 3; layer_param.mutable_tile_param()->set_tiles(kNumTiles); for (int i = 0; i < this->blob_bottom_->num_axes(); ++i) { layer_param.mutable_tile_param()->set_axis(i); TileLayer layer(layer_param); layer.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); ASSERT_EQ(this->blob_top_->num_axes(), this->blob_bottom_->num_axes()); for (int j = 0; j < this->blob_bottom_->num_axes(); ++j) { const int top_dim = ((i == j) ? kNumTiles : 1) * this->blob_bottom_->shape(j); EXPECT_EQ(top_dim, this->blob_top_->shape(j)); } } } TYPED_TEST(TileLayerTest, TestForwardNum) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; const int kTileAxis = 0; const int kNumTiles = 3; layer_param.mutable_tile_param()->set_axis(kTileAxis); layer_param.mutable_tile_param()->set_tiles(kNumTiles); TileLayer layer(layer_param); 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_top_->num(); ++n) { for (int c = 0; c < this->blob_top_->channels(); ++c) { for (int h = 0; h < this->blob_top_->height(); ++h) { for (int w = 0; w < this->blob_top_->width(); ++w) { const int bottom_n = n % this->blob_bottom_->num(); EXPECT_EQ(this->blob_bottom_->data_at(bottom_n, c, h, w), this->blob_top_->data_at(n, c, h, w)); } } } } } TYPED_TEST(TileLayerTest, TestForwardChannels) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; const int kNumTiles = 3; layer_param.mutable_tile_param()->set_tiles(kNumTiles); TileLayer layer(layer_param); 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_top_->num(); ++n) { for (int c = 0; c < this->blob_top_->channels(); ++c) { for (int h = 0; h < this->blob_top_->height(); ++h) { for (int w = 0; w < this->blob_top_->width(); ++w) { const int bottom_c = c % this->blob_bottom_->channels(); EXPECT_EQ(this->blob_bottom_->data_at(n, bottom_c, h, w), this->blob_top_->data_at(n, c, h, w)); } } } } } TYPED_TEST(TileLayerTest, TestTrivialGradient) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; const int kNumTiles = 1; layer_param.mutable_tile_param()->set_tiles(kNumTiles); TileLayer layer(layer_param); GradientChecker checker(1e-2, 1e-2); checker.CheckGradientExhaustive(&layer, this->blob_bottom_vec_, this->blob_top_vec_); } TYPED_TEST(TileLayerTest, TestGradientNum) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; const int kTileAxis = 0; const int kNumTiles = 3; layer_param.mutable_tile_param()->set_axis(kTileAxis); layer_param.mutable_tile_param()->set_tiles(kNumTiles); TileLayer layer(layer_param); GradientChecker checker(1e-2, 1e-2); checker.CheckGradientExhaustive(&layer, this->blob_bottom_vec_, this->blob_top_vec_); } TYPED_TEST(TileLayerTest, TestGradientChannels) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; const int kTileAxis = 1; const int kNumTiles = 3; layer_param.mutable_tile_param()->set_axis(kTileAxis); layer_param.mutable_tile_param()->set_tiles(kNumTiles); TileLayer layer(layer_param); GradientChecker checker(1e-2, 1e-2); checker.CheckGradientExhaustive(&layer, this->blob_bottom_vec_, this->blob_top_vec_); } } // namespace caffe