Skip to content

Commit

Permalink
improve test cases for dilated convolution
Browse files Browse the repository at this point in the history
  • Loading branch information
fyu committed Dec 17, 2015
1 parent 48e2e0c commit 8462520
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/caffe/solvers/adam_solver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void AdamSolver<Dtype>::ComputeUpdateValue(int param_id, Dtype rate) {
Blob<Dtype>* val_v = this->history_[param_id + update_history_offset].get();
Blob<Dtype>* val_t = this->temp_[param_id].get();

const int t = this->iter_ + 1;
const int t = this->iter_ + 1;
const Dtype correction = std::sqrt(Dtype(1) - pow(beta2, t)) /
(Dtype(1.) - pow(beta1, t));
const int N = net_params[param_id]->count();
Expand Down
123 changes: 115 additions & 8 deletions src/caffe/test/test_convolution_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,50 @@ TYPED_TEST(ConvolutionLayerTest, TestSimpleConvolution) {
}
}

TYPED_TEST(ConvolutionLayerTest, TestDilatedConvolution) {
typedef typename TypeParam::Dtype Dtype;
vector<int> bottom_shape;
bottom_shape.push_back(2);
bottom_shape.push_back(3);
bottom_shape.push_back(8);
bottom_shape.push_back(7);
this->blob_bottom_vec_.push_back(this->blob_bottom_2_);
this->blob_top_vec_.push_back(this->blob_top_2_);
for (int i = 0; i < this->blob_bottom_vec_.size(); ++i) {
this->blob_bottom_vec_[i]->Reshape(bottom_shape);
}
LayerParameter layer_param;
ConvolutionParameter* convolution_param =
layer_param.mutable_convolution_param();
convolution_param->add_kernel_size(3);
convolution_param->add_dilation(2);
convolution_param->set_num_output(4);
convolution_param->mutable_weight_filler()->set_type("gaussian");
convolution_param->mutable_bias_filler()->set_type("constant");
convolution_param->mutable_bias_filler()->set_value(0.1);
shared_ptr<Layer<Dtype> > layer(
new ConvolutionLayer<Dtype>(layer_param));
layer->SetUp(this->blob_bottom_vec_, this->blob_top_vec_);
layer->Forward(this->blob_bottom_vec_, this->blob_top_vec_);
// Check against reference convolution.
const Dtype* top_data;
const Dtype* ref_top_data;
caffe_conv(this->blob_bottom_, convolution_param, layer->blobs(),
this->MakeReferenceTop(this->blob_top_));
top_data = this->blob_top_->cpu_data();
ref_top_data = this->ref_blob_top_->cpu_data();
for (int i = 0; i < this->blob_top_->count(); ++i) {
EXPECT_NEAR(top_data[i], ref_top_data[i], 1e-4);
}
caffe_conv(this->blob_bottom_2_, convolution_param, layer->blobs(),
this->MakeReferenceTop(this->blob_top_2_));
top_data = this->blob_top_2_->cpu_data();
ref_top_data = this->ref_blob_top_->cpu_data();
for (int i = 0; i < this->blob_top_->count(); ++i) {
EXPECT_NEAR(top_data[i], ref_top_data[i], 1e-4);
}
}

TYPED_TEST(ConvolutionLayerTest, Test0DConvolution) {
typedef typename TypeParam::Dtype Dtype;
LayerParameter layer_param;
Expand Down Expand Up @@ -323,7 +367,6 @@ TYPED_TEST(ConvolutionLayerTest, TestSimple3DConvolution) {
layer_param.mutable_convolution_param();
convolution_param->add_kernel_size(3);
convolution_param->add_stride(2);
convolution_param->add_dilation(1);
convolution_param->set_num_output(4);
convolution_param->mutable_weight_filler()->set_type("gaussian");
convolution_param->mutable_bias_filler()->set_type("gaussian");
Expand All @@ -350,14 +393,60 @@ TYPED_TEST(ConvolutionLayerTest, TestSimple3DConvolution) {
}
}

TYPED_TEST(ConvolutionLayerTest, TestDilated3DConvolution) {
typedef typename TypeParam::Dtype Dtype;
this->blob_bottom_vec_.push_back(this->blob_bottom_2_);
this->blob_top_vec_.push_back(this->blob_top_2_);
vector<int> bottom_shape(5);
bottom_shape[0] = this->blob_bottom_vec_[0]->shape(0);
bottom_shape[1] = this->blob_bottom_vec_[0]->shape(1);
bottom_shape[2] = 6;
bottom_shape[3] = 7;
bottom_shape[4] = 8;
FillerParameter filler_param;
GaussianFiller<Dtype> filler(filler_param);
for (int i = 0; i < this->blob_bottom_vec_.size(); ++i) {
this->blob_bottom_vec_[i]->Reshape(bottom_shape);
filler.Fill(this->blob_bottom_vec_[i]);
}
LayerParameter layer_param;
ConvolutionParameter* convolution_param =
layer_param.mutable_convolution_param();
convolution_param->add_kernel_size(3);
convolution_param->add_dilation(2);
convolution_param->set_num_output(4);
convolution_param->mutable_weight_filler()->set_type("gaussian");
convolution_param->mutable_bias_filler()->set_type("gaussian");
shared_ptr<Layer<Dtype> > layer(
new ConvolutionLayer<Dtype>(layer_param));
layer->SetUp(this->blob_bottom_vec_, this->blob_top_vec_);
layer->Forward(this->blob_bottom_vec_, this->blob_top_vec_);
// Check against reference convolution.
const Dtype* top_data;
const Dtype* ref_top_data;
caffe_conv(this->blob_bottom_, convolution_param, layer->blobs(),
this->MakeReferenceTop(this->blob_top_));
top_data = this->blob_top_->cpu_data();
ref_top_data = this->ref_blob_top_->cpu_data();
for (int i = 0; i < this->blob_top_->count(); ++i) {
EXPECT_NEAR(top_data[i], ref_top_data[i], 1e-4);
}
caffe_conv(this->blob_bottom_2_, convolution_param, layer->blobs(),
this->MakeReferenceTop(this->blob_top_2_));
top_data = this->blob_top_2_->cpu_data();
ref_top_data = this->ref_blob_top_->cpu_data();
for (int i = 0; i < this->blob_top_->count(); ++i) {
EXPECT_NEAR(top_data[i], ref_top_data[i], 1e-4);
}
}

TYPED_TEST(ConvolutionLayerTest, Test1x1Convolution) {
typedef typename TypeParam::Dtype Dtype;
LayerParameter layer_param;
ConvolutionParameter* convolution_param =
layer_param.mutable_convolution_param();
convolution_param->add_kernel_size(1);
convolution_param->add_stride(1);
convolution_param->add_dilation(1);
convolution_param->set_num_output(4);
convolution_param->mutable_weight_filler()->set_type("gaussian");
convolution_param->mutable_bias_filler()->set_type("constant");
Expand Down Expand Up @@ -385,7 +474,6 @@ TYPED_TEST(ConvolutionLayerTest, TestSimpleConvolutionGroup) {
layer_param.mutable_convolution_param();
convolution_param->add_kernel_size(3);
convolution_param->add_stride(2);
convolution_param->add_dilation(1);
convolution_param->set_num_output(3);
convolution_param->set_group(3);
convolution_param->mutable_weight_filler()->set_type("gaussian");
Expand Down Expand Up @@ -425,7 +513,6 @@ TYPED_TEST(ConvolutionLayerTest, TestSobelConvolution) {
layer_param.mutable_convolution_param();
convolution_param->add_kernel_size(3);
convolution_param->add_stride(2);
convolution_param->add_dilation(1);
convolution_param->set_num_output(1);
convolution_param->set_bias_term(false);
shared_ptr<Layer<Dtype> > layer(
Expand Down Expand Up @@ -628,7 +715,6 @@ TYPED_TEST(ConvolutionLayerTest, TestGradient) {
this->blob_top_vec_.push_back(this->blob_top_2_);
convolution_param->add_kernel_size(3);
convolution_param->add_stride(2);
convolution_param->add_dilation(1);
convolution_param->set_num_output(2);
convolution_param->mutable_weight_filler()->set_type("gaussian");
convolution_param->mutable_bias_filler()->set_type("gaussian");
Expand All @@ -638,6 +724,30 @@ TYPED_TEST(ConvolutionLayerTest, TestGradient) {
this->blob_top_vec_);
}

TYPED_TEST(ConvolutionLayerTest, TestDilatedGradient) {
typedef typename TypeParam::Dtype Dtype;
LayerParameter layer_param;
ConvolutionParameter* convolution_param =
layer_param.mutable_convolution_param();
vector<int> bottom_shape;
bottom_shape.push_back(2);
bottom_shape.push_back(3);
bottom_shape.push_back(5);
bottom_shape.push_back(6);
for (int i = 0; i < this->blob_bottom_vec_.size(); ++i) {
this->blob_bottom_vec_[i]->Reshape(bottom_shape);
}
convolution_param->add_kernel_size(3);
convolution_param->add_dilation(2);
convolution_param->set_num_output(2);
convolution_param->mutable_weight_filler()->set_type("gaussian");
convolution_param->mutable_bias_filler()->set_type("gaussian");
ConvolutionLayer<Dtype> layer(layer_param);
GradientChecker<Dtype> checker(1e-2, 1e-3);
checker.CheckGradientExhaustive(&layer, this->blob_bottom_vec_,
this->blob_top_vec_);
}

TYPED_TEST(ConvolutionLayerTest, TestGradient3D) {
typedef typename TypeParam::Dtype Dtype;
LayerParameter layer_param;
Expand All @@ -657,7 +767,6 @@ TYPED_TEST(ConvolutionLayerTest, TestGradient3D) {
}
convolution_param->add_kernel_size(3);
convolution_param->add_stride(2);
convolution_param->add_dilation(1);
convolution_param->set_num_output(2);
convolution_param->mutable_weight_filler()->set_type("gaussian");
convolution_param->mutable_bias_filler()->set_type("gaussian");
Expand All @@ -676,7 +785,6 @@ TYPED_TEST(ConvolutionLayerTest, Test1x1Gradient) {
this->blob_top_vec_.push_back(this->blob_top_2_);
convolution_param->add_kernel_size(1);
convolution_param->add_stride(1);
convolution_param->add_dilation(1);
convolution_param->set_num_output(2);
convolution_param->mutable_weight_filler()->set_type("gaussian");
convolution_param->mutable_bias_filler()->set_type("gaussian");
Expand All @@ -693,7 +801,6 @@ TYPED_TEST(ConvolutionLayerTest, TestGradientGroup) {
layer_param.mutable_convolution_param();
convolution_param->add_kernel_size(3);
convolution_param->add_stride(2);
convolution_param->add_dilation(1);
convolution_param->set_num_output(3);
convolution_param->set_group(3);
convolution_param->mutable_weight_filler()->set_type("gaussian");
Expand Down
54 changes: 48 additions & 6 deletions src/caffe/test/test_im2col_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Im2colLayerTest : public MultiDeviceTest<TypeParam> {
typedef typename TypeParam::Dtype Dtype;
protected:
Im2colLayerTest()
: blob_bottom_(new Blob<Dtype>(2, 3, 10, 11)),
: blob_bottom_(new Blob<Dtype>(2, 3, 6, 5)),
blob_top_(new Blob<Dtype>()) {
// fill the values
Caffe::set_random_seed(1701);
Expand All @@ -41,6 +41,12 @@ TYPED_TEST(Im2colLayerTest, TestSetup) {
LayerParameter layer_param;
ConvolutionParameter* convolution_param =
layer_param.mutable_convolution_param();
vector<int> bottom_shape;
bottom_shape.push_back(2);
bottom_shape.push_back(3);
bottom_shape.push_back(10);
bottom_shape.push_back(11);
this->blob_bottom_->Reshape(bottom_shape);
convolution_param->add_kernel_size(3);
convolution_param->add_stride(2);
convolution_param->add_dilation(3);
Expand Down Expand Up @@ -76,28 +82,67 @@ TYPED_TEST(Im2colLayerTest, TestGradient) {
layer_param.mutable_convolution_param();
convolution_param->add_kernel_size(3);
convolution_param->add_stride(2);
convolution_param->add_dilation(3);
Im2colLayer<Dtype> layer(layer_param);
GradientChecker<Dtype> checker(1e-2, 1e-2);
checker.CheckGradientExhaustive(&layer, this->blob_bottom_vec_,
this->blob_top_vec_);
}

TYPED_TEST(Im2colLayerTest, TestGradientForceND) {
TYPED_TEST(Im2colLayerTest, TestDilatedGradient) {
typedef typename TypeParam::Dtype Dtype;
LayerParameter layer_param;
ConvolutionParameter* convolution_param =
layer_param.mutable_convolution_param();
vector<int> bottom_shape;
bottom_shape.push_back(2);
bottom_shape.push_back(3);
bottom_shape.push_back(10);
bottom_shape.push_back(9);
this->blob_bottom_->Reshape(bottom_shape);
convolution_param->add_kernel_size(3);
convolution_param->add_stride(2);
convolution_param->add_dilation(3);
Im2colLayer<Dtype> layer(layer_param);
GradientChecker<Dtype> checker(1e-2, 1e-2);
checker.CheckGradientExhaustive(&layer, this->blob_bottom_vec_,
this->blob_top_vec_);
}

TYPED_TEST(Im2colLayerTest, TestGradientForceND) {
typedef typename TypeParam::Dtype Dtype;
LayerParameter layer_param;
ConvolutionParameter* convolution_param =
layer_param.mutable_convolution_param();
convolution_param->add_kernel_size(3);
convolution_param->add_stride(2);
convolution_param->set_force_nd_im2col(true);
Im2colLayer<Dtype> layer(layer_param);
GradientChecker<Dtype> checker(1e-2, 1e-2);
checker.CheckGradientExhaustive(&layer, this->blob_bottom_vec_,
this->blob_top_vec_);
}

TYPED_TEST(Im2colLayerTest, TestDilatedGradientForceND) {
typedef typename TypeParam::Dtype Dtype;
LayerParameter layer_param;
ConvolutionParameter* convolution_param =
layer_param.mutable_convolution_param();
vector<int> bottom_shape;
bottom_shape.push_back(2);
bottom_shape.push_back(3);
bottom_shape.push_back(10);
bottom_shape.push_back(9);
this->blob_bottom_->Reshape(bottom_shape);
convolution_param->add_kernel_size(3);
convolution_param->add_stride(2);
convolution_param->add_dilation(3);
convolution_param->set_force_nd_im2col(true);
Im2colLayer<Dtype> layer(layer_param);
GradientChecker<Dtype> checker(1e-2, 1e-2);
checker.CheckGradientExhaustive(&layer, this->blob_bottom_vec_,
this->blob_top_vec_);
}

TYPED_TEST(Im2colLayerTest, TestRect) {
typedef typename TypeParam::Dtype Dtype;
LayerParameter layer_param;
Expand All @@ -116,7 +161,6 @@ TYPED_TEST(Im2colLayerTest, TestRect) {
}
}


TYPED_TEST(Im2colLayerTest, TestRectGradient) {
typedef typename TypeParam::Dtype Dtype;
LayerParameter layer_param;
Expand All @@ -125,8 +169,6 @@ TYPED_TEST(Im2colLayerTest, TestRectGradient) {
convolution_param->set_kernel_h(5);
convolution_param->set_kernel_w(3);
convolution_param->add_stride(2);
convolution_param->add_dilation(1);
convolution_param->add_dilation(3);
Im2colLayer<Dtype> layer(layer_param);
GradientChecker<Dtype> checker(1e-2, 1e-2);
checker.CheckGradientExhaustive(&layer, this->blob_bottom_vec_,
Expand Down
8 changes: 4 additions & 4 deletions src/caffe/util/im2col.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ void im2col_cpu(const Dtype* data_im, const int channels,
const int dilation_h, const int dilation_w,
Dtype* data_col) {
const int height_col = (height + 2 * pad_h -
(dilation_h * (kernel_h - 1) + 1)) / stride_h + 1;
(dilation_h * (kernel_h - 1) + 1)) / stride_h + 1;
const int width_col = (width + 2 * pad_w -
(dilation_w * (kernel_w - 1) + 1)) / stride_w + 1;
(dilation_w * (kernel_w - 1) + 1)) / stride_w + 1;
const int channels_col = channels * kernel_h * kernel_w;
for (int c_col = 0; c_col < channels_col; ++c_col) {
int w_offset = c_col % kernel_w;
Expand Down Expand Up @@ -147,9 +147,9 @@ void col2im_cpu(const Dtype* data_col, const int channels,
Dtype* data_im) {
caffe_set(height * width * channels, Dtype(0), data_im);
const int height_col = (height + 2 * pad_h -
(dilation_h * (kernel_h - 1) + 1)) / stride_h + 1;
(dilation_h * (kernel_h - 1) + 1)) / stride_h + 1;
const int width_col = (width + 2 * pad_w -
(dilation_w * (kernel_w - 1) + 1)) / stride_w + 1;
(dilation_w * (kernel_w - 1) + 1)) / stride_w + 1;
const int channels_col = channels * kernel_h * kernel_w;
for (int c_col = 0; c_col < channels_col; ++c_col) {
int w_offset = c_col % kernel_w;
Expand Down
8 changes: 4 additions & 4 deletions src/caffe/util/im2col.cu
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ void im2col_gpu(const Dtype* data_im, const int channels,
// We are going to launch channels * height_col * width_col kernels, each
// kernel responsible for copying a single-channel grid.
int height_col = (height + 2 * pad_h -
(dilation_h * (kernel_h - 1) + 1)) / stride_h + 1;
(dilation_h * (kernel_h - 1) + 1)) / stride_h + 1;
int width_col = (width + 2 * pad_w -
(dilation_w * (kernel_w - 1) + 1)) / stride_w + 1;
(dilation_w * (kernel_w - 1) + 1)) / stride_w + 1;
int num_kernels = channels * height_col * width_col;
// NOLINT_NEXT_LINE(whitespace/operators)
im2col_gpu_kernel<Dtype><<<CAFFE_GET_BLOCKS(num_kernels),
Expand Down Expand Up @@ -290,9 +290,9 @@ void col2im_gpu(const Dtype* data_col, const int channels,
const int pad_h, const int pad_w, const int stride_h,
const int stride_w, const int dilation_h, const int dilation_w,
Dtype* data_im) {
int height_col = (height + 2 * pad_h - (dilation_h * (kernel_h - 1) + 1)) /
int height_col = (height + 2 * pad_h - (dilation_h * (kernel_h - 1) + 1)) /
stride_h + 1;
int width_col = (width + 2 * pad_w - (dilation_w * (kernel_w - 1) + 1)) /
int width_col = (width + 2 * pad_w - (dilation_w * (kernel_w - 1) + 1)) /
stride_w + 1;
int num_kernels = channels * height * width;
// To avoid involving atomic operations, we will launch one kernel per
Expand Down

0 comments on commit 8462520

Please sign in to comment.