#include #include "gtest/gtest.h" #include "caffe/blob.hpp" #include "caffe/common.hpp" #include "caffe/filler.hpp" #include "caffe/layers/pooling_layer.hpp" #ifdef USE_CUDNN #include "caffe/layers/cudnn_pooling_layer.hpp" #endif #include "caffe/test/test_caffe_main.hpp" #include "caffe/test/test_gradient_check_util.hpp" namespace caffe { typedef ::testing::Types > float_only; #define TestDtypesAndDevices float_only #define SET_LAYER(name) \ layer_param.set_type(#name);\ shared_ptr > new_layer=\ LayerRegistry::CreateLayer(layer_param);\ shared_ptr< name ## Layer > layer= \ boost::static_pointer_cast< name ## Layer > (new_layer);\ if(0) layer=shared_ptr >(new name ## Layer(layer_param));\ layer->SetUp(this->blob_bottom_vec_, this->blob_top_vec_); template class PoolingLayerTest : public MultiDeviceTest { typedef typename TypeParam::Dtype Dtype; protected: PoolingLayerTest() : blob_bottom_(new Blob()), blob_top_(new Blob()), blob_top_mask_(new Blob()) {} virtual void SetUp() { Caffe::set_random_seed(1701); blob_bottom_->Reshape(2, 3, 6, 5); // fill the values FillerParameter filler_param; GaussianFiller filler(filler_param); filler.Fill(this->blob_bottom_); blob_bottom_vec_.push_back(blob_bottom_); blob_top_vec_.push_back(blob_top_); } virtual ~PoolingLayerTest() { delete blob_bottom_; delete blob_top_; delete blob_top_mask_; } Blob* const blob_bottom_; Blob* const blob_top_; Blob* const blob_top_mask_; vector*> blob_bottom_vec_; vector*> blob_top_vec_; // Test for 2x 2 square pooling layer void TestForwardSquare() { LayerParameter layer_param; PoolingParameter* pooling_param = layer_param.mutable_pooling_param(); pooling_param->set_kernel_size(2); pooling_param->set_pool(PoolingParameter_PoolMethod_MAX); const int num = 2; const int channels = 2; blob_bottom_->Reshape(num, channels, 3, 5); // Input: 2x 2 channels of: // [1 2 5 2 3] // [9 4 1 4 8] // [1 2 5 2 3] for (int i = 0; i < 15 * num * channels; i += 15) { blob_bottom_->mutable_cpu_data()[i + 0] = 1; blob_bottom_->mutable_cpu_data()[i + 1] = 2; blob_bottom_->mutable_cpu_data()[i + 2] = 5; blob_bottom_->mutable_cpu_data()[i + 3] = 2; blob_bottom_->mutable_cpu_data()[i + 4] = 3; blob_bottom_->mutable_cpu_data()[i + 5] = 9; blob_bottom_->mutable_cpu_data()[i + 6] = 4; blob_bottom_->mutable_cpu_data()[i + 7] = 1; blob_bottom_->mutable_cpu_data()[i + 8] = 4; blob_bottom_->mutable_cpu_data()[i + 9] = 8; blob_bottom_->mutable_cpu_data()[i + 10] = 1; blob_bottom_->mutable_cpu_data()[i + 11] = 2; blob_bottom_->mutable_cpu_data()[i + 12] = 5; blob_bottom_->mutable_cpu_data()[i + 13] = 2; blob_bottom_->mutable_cpu_data()[i + 14] = 3; } SET_LAYER(Pooling); EXPECT_EQ(blob_top_->num(), num); EXPECT_EQ(blob_top_->channels(), channels); EXPECT_EQ(blob_top_->height(), 2); EXPECT_EQ(blob_top_->width(), 4); if (blob_top_vec_.size() > 1) { EXPECT_EQ(blob_top_mask_->num(), num); EXPECT_EQ(blob_top_mask_->channels(), channels); EXPECT_EQ(blob_top_mask_->height(), 2); EXPECT_EQ(blob_top_mask_->width(), 4); } layer->Forward(blob_bottom_vec_, blob_top_vec_); // Expected output: 2x 2 channels of: // [9 5 5 8] // [9 5 5 8] for (int i = 0; i < 8 * num * channels; i += 8) { EXPECT_EQ(blob_top_->cpu_data()[i + 0], 9); EXPECT_EQ(blob_top_->cpu_data()[i + 1], 5); EXPECT_EQ(blob_top_->cpu_data()[i + 2], 5); EXPECT_EQ(blob_top_->cpu_data()[i + 3], 8); EXPECT_EQ(blob_top_->cpu_data()[i + 4], 9); EXPECT_EQ(blob_top_->cpu_data()[i + 5], 5); EXPECT_EQ(blob_top_->cpu_data()[i + 6], 5); EXPECT_EQ(blob_top_->cpu_data()[i + 7], 8); } if (blob_top_vec_.size() > 1) { // Expected mask output: 2x 2 channels of: // [5 2 2 9] // [5 12 12 9] for (int i = 0; i < 8 * num * channels; i += 8) { EXPECT_EQ(blob_top_mask_->cpu_data()[i + 0], 5); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 1], 2); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 2], 2); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 3], 9); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 4], 5); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 5], 12); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 6], 12); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 7], 9); } } } // Test for 3x 2 rectangular pooling layer with kernel_h > kernel_w void TestForwardRectHigh() { LayerParameter layer_param; PoolingParameter* pooling_param = layer_param.mutable_pooling_param(); pooling_param->set_kernel_h(3); pooling_param->set_kernel_w(2); pooling_param->set_pool(PoolingParameter_PoolMethod_MAX); const int num = 2; const int channels = 2; blob_bottom_->Reshape(num, channels, 6, 6); // Input: 2x 2 channels of: // [35 1 6 26 19 24] // [ 3 32 7 21 23 25] // [31 9 2 22 27 20] // [ 8 28 33 17 10 15] // [30 5 34 12 14 16] // [ 4 36 29 13 18 11] // (this is generated by magic(6) in MATLAB) for (int i = 0; i < 36 * num * channels; i += 36) { blob_bottom_->mutable_cpu_data()[i + 0] = 35; blob_bottom_->mutable_cpu_data()[i + 1] = 1; blob_bottom_->mutable_cpu_data()[i + 2] = 6; blob_bottom_->mutable_cpu_data()[i + 3] = 26; blob_bottom_->mutable_cpu_data()[i + 4] = 19; blob_bottom_->mutable_cpu_data()[i + 5] = 24; blob_bottom_->mutable_cpu_data()[i + 6] = 3; blob_bottom_->mutable_cpu_data()[i + 7] = 32; blob_bottom_->mutable_cpu_data()[i + 8] = 7; blob_bottom_->mutable_cpu_data()[i + 9] = 21; blob_bottom_->mutable_cpu_data()[i + 10] = 23; blob_bottom_->mutable_cpu_data()[i + 11] = 25; blob_bottom_->mutable_cpu_data()[i + 12] = 31; blob_bottom_->mutable_cpu_data()[i + 13] = 9; blob_bottom_->mutable_cpu_data()[i + 14] = 2; blob_bottom_->mutable_cpu_data()[i + 15] = 22; blob_bottom_->mutable_cpu_data()[i + 16] = 27; blob_bottom_->mutable_cpu_data()[i + 17] = 20; blob_bottom_->mutable_cpu_data()[i + 18] = 8; blob_bottom_->mutable_cpu_data()[i + 19] = 28; blob_bottom_->mutable_cpu_data()[i + 20] = 33; blob_bottom_->mutable_cpu_data()[i + 21] = 17; blob_bottom_->mutable_cpu_data()[i + 22] = 10; blob_bottom_->mutable_cpu_data()[i + 23] = 15; blob_bottom_->mutable_cpu_data()[i + 24] = 30; blob_bottom_->mutable_cpu_data()[i + 25] = 5; blob_bottom_->mutable_cpu_data()[i + 26] = 34; blob_bottom_->mutable_cpu_data()[i + 27] = 12; blob_bottom_->mutable_cpu_data()[i + 28] = 14; blob_bottom_->mutable_cpu_data()[i + 29] = 16; blob_bottom_->mutable_cpu_data()[i + 30] = 4; blob_bottom_->mutable_cpu_data()[i + 31] = 36; blob_bottom_->mutable_cpu_data()[i + 32] = 29; blob_bottom_->mutable_cpu_data()[i + 33] = 13; blob_bottom_->mutable_cpu_data()[i + 34] = 18; blob_bottom_->mutable_cpu_data()[i + 35] = 11; } SET_LAYER(Pooling); EXPECT_EQ(blob_top_->channels(), channels); EXPECT_EQ(blob_top_->height(), 4); EXPECT_EQ(blob_top_->width(), 5); if (blob_top_vec_.size() > 1) { EXPECT_EQ(blob_top_mask_->num(), num); EXPECT_EQ(blob_top_mask_->channels(), channels); EXPECT_EQ(blob_top_mask_->height(), 4); EXPECT_EQ(blob_top_mask_->width(), 5); } layer->Forward(blob_bottom_vec_, blob_top_vec_); // Expected output: 2x 2 channels of: // [35 32 26 27 27] // [32 33 33 27 27] // [31 34 34 27 27] // [36 36 34 18 18] for (int i = 0; i < 20 * num * channels; i += 20) { EXPECT_EQ(blob_top_->cpu_data()[i + 0], 35); EXPECT_EQ(blob_top_->cpu_data()[i + 1], 32); EXPECT_EQ(blob_top_->cpu_data()[i + 2], 26); EXPECT_EQ(blob_top_->cpu_data()[i + 3], 27); EXPECT_EQ(blob_top_->cpu_data()[i + 4], 27); EXPECT_EQ(blob_top_->cpu_data()[i + 5], 32); EXPECT_EQ(blob_top_->cpu_data()[i + 6], 33); EXPECT_EQ(blob_top_->cpu_data()[i + 7], 33); EXPECT_EQ(blob_top_->cpu_data()[i + 8], 27); EXPECT_EQ(blob_top_->cpu_data()[i + 9], 27); EXPECT_EQ(blob_top_->cpu_data()[i + 10], 31); EXPECT_EQ(blob_top_->cpu_data()[i + 11], 34); EXPECT_EQ(blob_top_->cpu_data()[i + 12], 34); EXPECT_EQ(blob_top_->cpu_data()[i + 13], 27); EXPECT_EQ(blob_top_->cpu_data()[i + 14], 27); EXPECT_EQ(blob_top_->cpu_data()[i + 15], 36); EXPECT_EQ(blob_top_->cpu_data()[i + 16], 36); EXPECT_EQ(blob_top_->cpu_data()[i + 17], 34); EXPECT_EQ(blob_top_->cpu_data()[i + 18], 18); EXPECT_EQ(blob_top_->cpu_data()[i + 19], 18); } if (blob_top_vec_.size() > 1) { // [ 1 8 4 17 17] // [ 8 21 21 17 17] // [13 27 27 17 17] // [32 32 27 35 35] for (int i = 0; i < 20 * num * channels; i += 20) { EXPECT_EQ(blob_top_mask_->cpu_data()[i + 0], 0); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 1], 7); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 2], 3); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 3], 16); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 4], 16); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 5], 7); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 6], 20); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 7], 20); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 8], 16); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 9], 16); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 10], 12); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 11], 26); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 12], 26); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 13], 16); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 14], 16); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 15], 31); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 16], 31); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 17], 26); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 18], 34); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 19], 34); } } } // Test for rectangular pooling layer with kernel_w > kernel_h void TestForwardRectWide() { LayerParameter layer_param; PoolingParameter* pooling_param = layer_param.mutable_pooling_param(); pooling_param->set_kernel_h(2); pooling_param->set_kernel_w(3); pooling_param->set_pool(PoolingParameter_PoolMethod_MAX); const int num = 2; const int channels = 2; blob_bottom_->Reshape(num, channels, 6, 6); // Input: 2x 2 channels of: // [35 1 6 26 19 24] // [ 3 32 7 21 23 25] // [31 9 2 22 27 20] // [ 8 28 33 17 10 15] // [30 5 34 12 14 16] // [ 4 36 29 13 18 11] // (this is generated by magic(6) in MATLAB) for (int i = 0; i < 36 * num * channels; i += 36) { blob_bottom_->mutable_cpu_data()[i + 0] = 35; blob_bottom_->mutable_cpu_data()[i + 1] = 1; blob_bottom_->mutable_cpu_data()[i + 2] = 6; blob_bottom_->mutable_cpu_data()[i + 3] = 26; blob_bottom_->mutable_cpu_data()[i + 4] = 19; blob_bottom_->mutable_cpu_data()[i + 5] = 24; blob_bottom_->mutable_cpu_data()[i + 6] = 3; blob_bottom_->mutable_cpu_data()[i + 7] = 32; blob_bottom_->mutable_cpu_data()[i + 8] = 7; blob_bottom_->mutable_cpu_data()[i + 9] = 21; blob_bottom_->mutable_cpu_data()[i + 10] = 23; blob_bottom_->mutable_cpu_data()[i + 11] = 25; blob_bottom_->mutable_cpu_data()[i + 12] = 31; blob_bottom_->mutable_cpu_data()[i + 13] = 9; blob_bottom_->mutable_cpu_data()[i + 14] = 2; blob_bottom_->mutable_cpu_data()[i + 15] = 22; blob_bottom_->mutable_cpu_data()[i + 16] = 27; blob_bottom_->mutable_cpu_data()[i + 17] = 20; blob_bottom_->mutable_cpu_data()[i + 18] = 8; blob_bottom_->mutable_cpu_data()[i + 19] = 28; blob_bottom_->mutable_cpu_data()[i + 20] = 33; blob_bottom_->mutable_cpu_data()[i + 21] = 17; blob_bottom_->mutable_cpu_data()[i + 22] = 10; blob_bottom_->mutable_cpu_data()[i + 23] = 15; blob_bottom_->mutable_cpu_data()[i + 24] = 30; blob_bottom_->mutable_cpu_data()[i + 25] = 5; blob_bottom_->mutable_cpu_data()[i + 26] = 34; blob_bottom_->mutable_cpu_data()[i + 27] = 12; blob_bottom_->mutable_cpu_data()[i + 28] = 14; blob_bottom_->mutable_cpu_data()[i + 29] = 16; blob_bottom_->mutable_cpu_data()[i + 30] = 4; blob_bottom_->mutable_cpu_data()[i + 31] = 36; blob_bottom_->mutable_cpu_data()[i + 32] = 29; blob_bottom_->mutable_cpu_data()[i + 33] = 13; blob_bottom_->mutable_cpu_data()[i + 34] = 18; blob_bottom_->mutable_cpu_data()[i + 35] = 11; } SET_LAYER(Pooling); EXPECT_EQ(blob_top_->num(), num); EXPECT_EQ(blob_top_->channels(), channels); EXPECT_EQ(blob_top_->height(), 5); EXPECT_EQ(blob_top_->width(), 4); if (blob_top_vec_.size() > 1) { EXPECT_EQ(blob_top_mask_->num(), num); EXPECT_EQ(blob_top_mask_->channels(), channels); EXPECT_EQ(blob_top_mask_->height(), 5); EXPECT_EQ(blob_top_mask_->width(), 4); } layer->Forward(blob_bottom_vec_, blob_top_vec_); // Expected output: 2x 2 channels of: // [35 32 26 26] // [32 32 27 27] // [33 33 33 27] // [34 34 34 17] // [36 36 34 18] for (int i = 0; i < 20 * num * channels; i += 20) { EXPECT_EQ(blob_top_->cpu_data()[i + 0], 35); EXPECT_EQ(blob_top_->cpu_data()[i + 1], 32); EXPECT_EQ(blob_top_->cpu_data()[i + 2], 26); EXPECT_EQ(blob_top_->cpu_data()[i + 3], 26); EXPECT_EQ(blob_top_->cpu_data()[i + 4], 32); EXPECT_EQ(blob_top_->cpu_data()[i + 5], 32); EXPECT_EQ(blob_top_->cpu_data()[i + 6], 27); EXPECT_EQ(blob_top_->cpu_data()[i + 7], 27); EXPECT_EQ(blob_top_->cpu_data()[i + 8], 33); EXPECT_EQ(blob_top_->cpu_data()[i + 9], 33); EXPECT_EQ(blob_top_->cpu_data()[i + 10], 33); EXPECT_EQ(blob_top_->cpu_data()[i + 11], 27); EXPECT_EQ(blob_top_->cpu_data()[i + 12], 34); EXPECT_EQ(blob_top_->cpu_data()[i + 13], 34); EXPECT_EQ(blob_top_->cpu_data()[i + 14], 34); EXPECT_EQ(blob_top_->cpu_data()[i + 15], 17); EXPECT_EQ(blob_top_->cpu_data()[i + 16], 36); EXPECT_EQ(blob_top_->cpu_data()[i + 17], 36); EXPECT_EQ(blob_top_->cpu_data()[i + 18], 34); EXPECT_EQ(blob_top_->cpu_data()[i + 19], 18); } if (blob_top_vec_.size() > 1) { // [ 1 8 4 4] // [ 8 8 17 17] // [21 21 21 17] // [27 27 27 22] // [32 32 27 35] for (int i = 0; i < 20 * num * channels; i += 20) { EXPECT_EQ(blob_top_mask_->cpu_data()[i + 0], 0); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 1], 7); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 2], 3); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 3], 3); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 4], 7); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 5], 7); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 6], 16); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 7], 16); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 8], 20); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 9], 20); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 10], 20); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 11], 16); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 12], 26); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 13], 26); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 14], 26); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 15], 21); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 16], 31); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 17], 31); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 18], 26); EXPECT_EQ(blob_top_mask_->cpu_data()[i + 19], 34); } } } }; TYPED_TEST_CASE(PoolingLayerTest, TestDtypesAndDevices); TYPED_TEST(PoolingLayerTest, TestSetup) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; PoolingParameter* pooling_param = layer_param.mutable_pooling_param(); pooling_param->set_kernel_size(3); pooling_param->set_stride(2); SET_LAYER(Pooling); //PoolingLayer layer(layer_param); //layer.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); EXPECT_EQ(this->blob_top_->num(), this->blob_bottom_->num()); EXPECT_EQ(this->blob_top_->channels(), this->blob_bottom_->channels()); EXPECT_EQ(this->blob_top_->height(), 3); EXPECT_EQ(this->blob_top_->width(), 2); } TYPED_TEST(PoolingLayerTest, TestSetupPadded) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; PoolingParameter* pooling_param = layer_param.mutable_pooling_param(); pooling_param->set_kernel_size(3); pooling_param->set_stride(2); pooling_param->set_pad(1); pooling_param->set_pool(PoolingParameter_PoolMethod_AVE); // PoolingLayer layer(layer_param); // layer.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); SET_LAYER(Pooling); EXPECT_EQ(this->blob_top_->num(), this->blob_bottom_->num()); EXPECT_EQ(this->blob_top_->channels(), this->blob_bottom_->channels()); EXPECT_EQ(this->blob_top_->height(), 4); EXPECT_EQ(this->blob_top_->width(), 3); } TYPED_TEST(PoolingLayerTest, TestSetupGlobalPooling) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; PoolingParameter* pooling_param = layer_param.mutable_pooling_param(); pooling_param->set_global_pooling(true); pooling_param->set_pool(PoolingParameter_PoolMethod_AVE); // PoolingLayer layer(layer_param); // layer.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); SET_LAYER(Pooling); EXPECT_EQ(this->blob_top_->num(), this->blob_bottom_->num()); EXPECT_EQ(this->blob_top_->channels(), this->blob_bottom_->channels()); EXPECT_EQ(this->blob_top_->height(), 1); EXPECT_EQ(this->blob_top_->width(), 1); } TYPED_TEST(PoolingLayerTest, TestForwardMax) { this->TestForwardSquare(); this->TestForwardRectHigh(); this->TestForwardRectWide(); } TYPED_TEST(PoolingLayerTest, TestForwardMaxTopMask) { this->blob_top_vec_.push_back(this->blob_top_mask_); this->TestForwardSquare(); this->TestForwardRectHigh(); this->TestForwardRectWide(); } TYPED_TEST(PoolingLayerTest, TestForwardMaxPadded) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; PoolingParameter* pooling_param = layer_param.mutable_pooling_param(); pooling_param->set_kernel_size(3); pooling_param->set_stride(2); pooling_param->set_pad(2); pooling_param->set_pool(PoolingParameter_PoolMethod_MAX); this->blob_bottom_->Reshape(1, 1, 3, 3); // Input: // [ 1 2 4 ] // [ 2 3 2 ] // [ 4 2 1 ] this->blob_bottom_->mutable_cpu_data()[0] = 1; this->blob_bottom_->mutable_cpu_data()[1] = 2; this->blob_bottom_->mutable_cpu_data()[2] = 4; this->blob_bottom_->mutable_cpu_data()[3] = 2; this->blob_bottom_->mutable_cpu_data()[4] = 3; this->blob_bottom_->mutable_cpu_data()[5] = 2; this->blob_bottom_->mutable_cpu_data()[6] = 4; this->blob_bottom_->mutable_cpu_data()[7] = 2; this->blob_bottom_->mutable_cpu_data()[8] = 1; SET_LAYER(Pooling); EXPECT_EQ(this->blob_top_->num(), 1); EXPECT_EQ(this->blob_top_->channels(), 1); EXPECT_EQ(this->blob_top_->height(), 3); EXPECT_EQ(this->blob_top_->width(), 3); layer->Forward(this->blob_bottom_vec_, this->blob_top_vec_); Dtype epsilon = 1e-8; // Output: // [ 1 4 4 ] // [ 4 4 4 ] // [ 4 4 1 ] EXPECT_NEAR(this->blob_top_->cpu_data()[0], 1, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[1], 4, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[2], 4, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[3], 4, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[4], 4, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[5], 4, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[6], 4, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[7], 4, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[8], 1, epsilon); } template void fill_bottom_data(Blob* bottom) { for(int i=0;inum();i++) for(int j=0;jchannels();j++) for(int l=0;lheight();l++) for(int k=0;kwidth();k++) { int offset; Dtype * ptr; offset=i*bottom->channels()*bottom->height()*bottom->width()+ j*bottom->height()*bottom->width()+ l*bottom->width()+k; ptr=bottom->mutable_cpu_data(); ptr[offset]=offset; } } template void check_top_data(Blob* bottom, Blob* top, int kernel_size, int stride) { Dtype epsilon = 1e-5; int error_count=0; for(int i=0;inum();i++) for(int j=0;jchannels();j++) for(int l=0;lheight();l++) for(int k=0;kwidth();k++) { Dtype pool_data=top->data_at(i,j,l,k); Dtype max_bottom_data=-100000000; int top_h=stride*l; int top_w=stride*k; /* calculate max **/ for(int x=0;xdata_at(i,j,top_h+x,top_w+y); if(d>max_bottom_data) max_bottom_data=d; } Dtype offset=pool_data-max_bottom_data; if(offset>epsilon || offset<-epsilon) { std::cout<set_kernel_size(kernel_size); pooling_param->set_stride(stride); pooling_param->set_pad(0); pooling_param->set_pool(PoolingParameter_PoolMethod_MAX); this->blob_bottom_->Reshape(1, channel_number, h, w); FillerParameter filler_param; filler_param.set_value(Dtype(2)); GaussianFiller filler(filler_param); filler.Fill(this->blob_bottom_); SET_LAYER(Pooling); //fill_bottom_data(this->blob_bottom_); #if 0 EXPECT_EQ(this->blob_top_->num(), 1); EXPECT_EQ(this->blob_top_->channels(), 96); EXPECT_EQ(this->blob_top_->height(), 27); EXPECT_EQ(this->blob_top_->width(), 27); #endif layer->Forward(this->blob_bottom_vec_, this->blob_top_vec_); check_top_data(this->blob_bottom_,this->blob_top_,kernel_size,stride); } TYPED_TEST(PoolingLayerTest, TestForwardAve) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; PoolingParameter* pooling_param = layer_param.mutable_pooling_param(); pooling_param->set_kernel_size(3); pooling_param->set_stride(1); pooling_param->set_pad(1); pooling_param->set_pool(PoolingParameter_PoolMethod_AVE); this->blob_bottom_->Reshape(1, 1, 3, 3); FillerParameter filler_param; filler_param.set_value(Dtype(2)); ConstantFiller filler(filler_param); filler.Fill(this->blob_bottom_); PoolingLayer 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(), 3); EXPECT_EQ(this->blob_top_->width(), 3); layer.Forward(this->blob_bottom_vec_, this->blob_top_vec_); Dtype epsilon = 1e-5; EXPECT_NEAR(this->blob_top_->cpu_data()[0], 8.0 / 9, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[1], 4.0 / 3, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[2], 8.0 / 9, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[3], 4.0 / 3, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[4], 2.0 , epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[5], 4.0 / 3, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[6], 8.0 / 9, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[7], 4.0 / 3, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[8], 8.0 / 9, epsilon); } } // namespace caffe