diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 2aff0cc0d6..abf573a352 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -124,6 +124,7 @@ Copyright: Copyright 2019, Ziyang Jiang Copyright 2019, Rohit Kartik Copyright 2019, Aditya Viki + Copyright 2019, Kartik Dutt License: BSD-3-clause All rights reserved. diff --git a/src/mlpack/methods/ann/layer/transposed_convolution_impl.hpp b/src/mlpack/methods/ann/layer/transposed_convolution_impl.hpp index ca70ee3a06..903c44e8bd 100644 --- a/src/mlpack/methods/ann/layer/transposed_convolution_impl.hpp +++ b/src/mlpack/methods/ann/layer/transposed_convolution_impl.hpp @@ -114,7 +114,6 @@ TransposedConvolution< aH + kernelHeight - 2 * padHeight) { Log::Fatal << "The output width / output height is not possible given " - << outputWidth << " " << padWidth << " " << aW << "the other parameters of the layer." << std::endl; } } @@ -449,12 +448,12 @@ void TransposedConvolution< * K=Kernel Size * P=Padding */ - size_t totalPadWidth = ((strideWidth - 1) * inputWidth + kernelWidth - - strideWidth); - size_t totalPadHeight = ((strideHeight - 1) * inputHeight + kernelHeight - - strideHeight); - padWidth = totalPadWidth / 2 + totalPadWidth & 1; - padHeight = totalPadHeight / 2 + totalPadHeight & 1; + size_t totalPadWidth = (strideWidth - 1) * inputWidth + kernelWidth - \ + strideWidth; + size_t totalPadHeight = (strideHeight - 1) * inputHeight + kernelHeight - \ + strideHeight; + padWidth = totalPadWidth / 2 + (totalPadWidth & 1); + padHeight = totalPadHeight / 2 + (totalPadHeight & 1); // If Padding is negative throw a fatal error. if (padWidth < 0 || padHeight < 0) { diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index f48585590c..588d248b18 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -2972,5 +2972,39 @@ BOOST_AUTO_TEST_CASE(TransposedConvolutionLayerPaddingTest) BOOST_REQUIRE_EQUAL(arma::accu(output), 0); BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows); BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols); + + TransposedConvolution<> module4(1, 1, 4, 4, 1, 1, 1, 1, 5, 5, 5, 5, "SAME"); + // Test the forward function. + input = arma::linspace(0, 24, 25); + module4.Parameters() = arma::mat(16 + 1, 1, arma::fill::zeros); + module4.Reset(); + module4.Forward(std::move(input), std::move(output)); + // Value calculated using torch.nn.functional.conv_transpose2d() + BOOST_REQUIRE_EQUAL(arma::accu(output), 0); + BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows); + BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols); + + + // Output shape should equal input. + TransposedConvolution<> module5(1, 1, 3, 3, 1, 1, 2, 2, 5, 5, 5, 5, "SAME"); + // Test the forward function. + input = arma::linspace(0, 24, 25); + module5.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); + module5.Reset(); + module5.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_EQUAL(arma::accu(output), 0); + BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows); + BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols); + + TransposedConvolution<> module6(1, 1, 3, 3, 2, 2, 0, 0, 2, 2, 2, 2, "SAME"); + // Test the forward function. + input = arma::linspace(0, 3, 4); + module6.Parameters() = arma::mat(25 + 1, 1, arma::fill::zeros); + module6.Reset(); + module6.Forward(std::move(input), std::move(output)); + // Value calculated using torch.nn.functional.conv_transpose2d() + BOOST_REQUIRE_EQUAL(arma::accu(output), 0); + BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows); + BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols); } BOOST_AUTO_TEST_SUITE_END();