TYPED_TEST(UpsampleLayerTest, TestForwardFromPoolOddShape) { typedef typename TypeParam::Dtype Dtype; int kernel_w = 2; int kernel_h = 2; Blob<Dtype>* input_blob = new Blob<Dtype>(); input_blob->Reshape(2, 3, 5, 4); FillerParameter filler_param; GaussianFiller<Dtype> filler(filler_param); filler.Fill(input_blob); std::vector<Blob<Dtype>*> pool_bottom_vec; pool_bottom_vec.push_back(input_blob); LayerParameter layer_param; PoolingParameter* pooling_param = layer_param.mutable_pooling_param(); pooling_param->set_kernel_h(kernel_h); pooling_param->set_kernel_w(kernel_w); pooling_param->set_stride(2); pooling_param->set_pool(PoolingParameter_PoolMethod_MAX); PoolingLayer<Dtype> pooling_layer(layer_param); pooling_layer.SetUp(pool_bottom_vec, this->blob_bottom_vec_); EXPECT_EQ(this->blob_bottom_->num(), 2); EXPECT_EQ(this->blob_bottom_->channels(), 3); EXPECT_EQ(this->blob_bottom_->height(), 3); EXPECT_EQ(this->blob_bottom_->width(), 2); EXPECT_EQ(this->blob_bottom_mask_->num(), 2); EXPECT_EQ(this->blob_bottom_mask_->channels(), 3); EXPECT_EQ(this->blob_bottom_mask_->height(), 3); EXPECT_EQ(this->blob_bottom_mask_->width(), 2); LayerParameter upsample_layer_param; UpsampleParameter* upsample_param = upsample_layer_param.mutable_upsample_param(); upsample_param->set_upsample_h(5); upsample_param->set_upsample_w(4); UpsampleLayer<Dtype> upsample_layer(upsample_layer_param); upsample_layer.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); EXPECT_EQ(this->blob_top_->num(), 2); EXPECT_EQ(this->blob_top_->channels(), 3); EXPECT_EQ(this->blob_top_->height(), 5); EXPECT_EQ(this->blob_top_->width(), 4); pooling_layer.Forward(pool_bottom_vec, this->blob_bottom_vec_); upsample_layer.Forward(this->blob_bottom_vec_, this->blob_top_vec_); const Dtype* top_data = this->blob_top_->cpu_data(); const Dtype* pool_bottom_data = input_blob->cpu_data(); int num_zeros = 0; for (int i = 0; i < this->blob_top_->count(); ++i) { if (top_data[i] != 0) { EXPECT_EQ(top_data[i], pool_bottom_data[i]); } else { ++num_zeros; } } EXPECT_EQ(num_zeros, (5*4-6)*2*3); }
// Fill the bottom blobs. void Fill(bool share_location) { int loc_classes = share_location ? 1 : num_classes_; // Create fake network which simulates a simple multi box network. vector<Blob<Dtype>*> fake_bottom_vec; vector<Blob<Dtype>*> fake_top_vec; LayerParameter layer_param; // Fake input (image) of size 20 x 20 Blob<Dtype>* fake_input = new Blob<Dtype>(num_, 3, 20, 20); // 1) Fill ground truth. #ifdef USE_LMDB string filename; GetTempDirname(&filename); DataParameter_DB backend = DataParameter_DB_LMDB; scoped_ptr<db::DB> db(db::GetDB(backend)); db->Open(filename, db::NEW); scoped_ptr<db::Transaction> txn(db->NewTransaction()); for (int i = 0; i < num_; ++i) { AnnotatedDatum anno_datum; // Fill data. Datum* datum = anno_datum.mutable_datum(); datum->set_channels(3); datum->set_height(20); datum->set_width(20); std::string* data = datum->mutable_data(); for (int j = 0; j < 3*20*20; ++j) { data->push_back(static_cast<uint8_t>(j/100.)); } anno_datum.set_type(AnnotatedDatum_AnnotationType_BBOX); if (i == 0 || i == 2) { AnnotationGroup* anno_group = anno_datum.add_annotation_group(); anno_group->set_group_label(1); Annotation* anno = anno_group->add_annotation(); anno->set_instance_id(0); NormalizedBBox* bbox = anno->mutable_bbox(); bbox->set_xmin(0.1); bbox->set_ymin(0.1); bbox->set_xmax(0.3); bbox->set_ymax(0.3); bbox->set_difficult(i % 2); } if (i == 2) { AnnotationGroup* anno_group = anno_datum.add_annotation_group(); anno_group->set_group_label(2); Annotation* anno = anno_group->add_annotation(); anno->set_instance_id(0); NormalizedBBox* bbox = anno->mutable_bbox(); bbox->set_xmin(0.2); bbox->set_ymin(0.2); bbox->set_xmax(0.4); bbox->set_ymax(0.4); bbox->set_difficult(i % 2); anno = anno_group->add_annotation(); anno->set_instance_id(1); bbox = anno->mutable_bbox(); bbox->set_xmin(0.6); bbox->set_ymin(0.6); bbox->set_xmax(0.8); bbox->set_ymax(0.9); bbox->set_difficult((i + 1) % 2); } string key_str = caffe::format_int(i, 3); string out; CHECK(anno_datum.SerializeToString(&out)); txn->Put(key_str, out); } txn->Commit(); db->Close(); DataParameter* data_param = layer_param.mutable_data_param(); data_param->set_batch_size(num_); data_param->set_source(filename.c_str()); data_param->set_backend(backend); AnnotatedDataLayer<Dtype> anno_data_layer(layer_param); fake_top_vec.clear(); fake_top_vec.push_back(fake_input); fake_top_vec.push_back(blob_bottom_gt_); anno_data_layer.SetUp(fake_bottom_vec, fake_top_vec); anno_data_layer.Forward(fake_bottom_vec, fake_top_vec); #else FillerParameter filler_param; GaussianFiller<Dtype> filler(filler_param); filler.Fill(fake_input); vector<int> gt_shape(4, 1); gt_shape[2] = 4; gt_shape[3] = 8; blob_bottom_gt_->Reshape(gt_shape); Dtype* gt_data = blob_bottom_gt_->mutable_cpu_data(); FillItem(gt_data, "0 1 0 0.1 0.1 0.3 0.3 0"); FillItem(gt_data + 8, "2 1 0 0.1 0.1 0.3 0.3 0"); FillItem(gt_data + 8 * 2, "2 2 0 0.2 0.2 0.4 0.4 0"); FillItem(gt_data + 8 * 3, "2 2 1 0.6 0.6 0.8 0.9 1"); #endif // USE_LMDB // Fake layer PoolingParameter* pooling_param = layer_param.mutable_pooling_param(); pooling_param->set_pool(PoolingParameter_PoolMethod_AVE); pooling_param->set_kernel_size(10); pooling_param->set_stride(10); PoolingLayer<Dtype> pooling_layer(layer_param); Blob<Dtype>* fake_blob = new Blob<Dtype>(num_, 5, height_, width_); fake_bottom_vec.clear(); fake_bottom_vec.push_back(fake_input); fake_top_vec.clear(); fake_top_vec.push_back(fake_blob); pooling_layer.SetUp(fake_bottom_vec, fake_top_vec); pooling_layer.Forward(fake_bottom_vec, fake_top_vec); // 2) Fill bbox location predictions. ConvolutionParameter* convolution_param = layer_param.mutable_convolution_param(); convolution_param->add_pad(0); convolution_param->add_kernel_size(1); convolution_param->add_stride(1); int num_output = num_priors_per_location_ * loc_classes * 4; convolution_param->set_num_output(num_output); convolution_param->mutable_weight_filler()->set_type("xavier"); convolution_param->mutable_bias_filler()->set_type("constant"); convolution_param->mutable_bias_filler()->set_value(0.1); ConvolutionLayer<Dtype> conv_layer_loc(layer_param); fake_bottom_vec.clear(); fake_bottom_vec.push_back(fake_blob); Blob<Dtype> fake_output_loc; fake_top_vec.clear(); fake_top_vec.push_back(&fake_output_loc); conv_layer_loc.SetUp(fake_bottom_vec, fake_top_vec); conv_layer_loc.Forward(fake_bottom_vec, fake_top_vec); // Use Permute and Flatten layer to prepare for MultiBoxLoss layer. PermuteParameter* permute_param = layer_param.mutable_permute_param(); permute_param->add_order(0); permute_param->add_order(2); permute_param->add_order(3); permute_param->add_order(1); PermuteLayer<Dtype> permute_layer(layer_param); fake_bottom_vec.clear(); fake_bottom_vec.push_back(&fake_output_loc); fake_top_vec.clear(); Blob<Dtype> fake_permute_loc; fake_top_vec.push_back(&fake_permute_loc); permute_layer.SetUp(fake_bottom_vec, fake_top_vec); permute_layer.Forward(fake_bottom_vec, fake_top_vec); FlattenParameter* flatten_param = layer_param.mutable_flatten_param(); flatten_param->set_axis(1); FlattenLayer<Dtype> flatten_layer(layer_param); vector<int> loc_shape(4, 1); loc_shape[0] = num_; loc_shape[1] = num_output * height_ * width_; blob_bottom_loc_->Reshape(loc_shape); fake_bottom_vec.clear(); fake_bottom_vec.push_back(&fake_permute_loc); fake_top_vec.clear(); fake_top_vec.push_back(blob_bottom_loc_); flatten_layer.SetUp(fake_bottom_vec, fake_top_vec); flatten_layer.Forward(fake_bottom_vec, fake_top_vec); // 3) Fill bbox confidence predictions. convolution_param->set_num_output(num_priors_per_location_ * num_classes_); ConvolutionLayer<Dtype> conv_layer_conf(layer_param); fake_bottom_vec.clear(); fake_bottom_vec.push_back(fake_blob); num_output = num_priors_per_location_ * num_classes_; Blob<Dtype> fake_output_conf; fake_top_vec.clear(); fake_top_vec.push_back(&fake_output_conf); conv_layer_conf.SetUp(fake_bottom_vec, fake_top_vec); conv_layer_conf.Forward(fake_bottom_vec, fake_top_vec); fake_bottom_vec.clear(); fake_bottom_vec.push_back(&fake_output_conf); fake_top_vec.clear(); Blob<Dtype> fake_permute_conf; fake_top_vec.push_back(&fake_permute_conf); permute_layer.SetUp(fake_bottom_vec, fake_top_vec); permute_layer.Forward(fake_bottom_vec, fake_top_vec); vector<int> conf_shape(4, 1); conf_shape[0] = num_; conf_shape[1] = num_output * height_ * width_; blob_bottom_conf_->Reshape(conf_shape); fake_bottom_vec.clear(); fake_bottom_vec.push_back(&fake_permute_conf); fake_top_vec.clear(); fake_top_vec.push_back(blob_bottom_conf_); flatten_layer.SetUp(fake_bottom_vec, fake_top_vec); flatten_layer.Forward(fake_bottom_vec, fake_top_vec); // 4) Fill prior bboxes. PriorBoxParameter* prior_box_param = layer_param.mutable_prior_box_param(); prior_box_param->add_min_size(5); prior_box_param->add_max_size(10); prior_box_param->add_aspect_ratio(3.); prior_box_param->set_flip(true); PriorBoxLayer<Dtype> prior_layer(layer_param); fake_bottom_vec.clear(); fake_bottom_vec.push_back(fake_blob); fake_bottom_vec.push_back(fake_input); fake_top_vec.clear(); fake_top_vec.push_back(blob_bottom_prior_); prior_layer.SetUp(fake_bottom_vec, fake_top_vec); prior_layer.Forward(fake_bottom_vec, fake_top_vec); delete fake_blob; delete fake_input; }