Repository: pytorch/pytorch

Issue:
Feature Request: Add dilate to ConvTranspose functions
Any possibility of adding dilatation to transpose convolutions?


Discussion:
this should be possible. We could do this.
Thanks.  Looking through `functional.py` it appears that you may just need to add a `dilation` parameter (currently just set to 1).  I'm sure there is some issues to address wrt the transpose though, and of course testing.
@ezyang an easy task for you. give it a try. Ask me if you need pointers.

Resolving patch:
diff --git a/torch/nn/functional.py b/torch/nn/functional.py
--- a/torch/nn/functional.py
+++ b/torch/nn/functional.py
@@ -25,6 +25,7 @@ def conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1,
           a tuple (sh x sw). Default: 1
         padding: implicit zero padding on the input. Can be a single number or
           a tuple. Default: 0
+        dilation: the spacing between kernel elements. Default: 1
         groups: split input into groups, in_channels should be divisible by
           the number of groups
 
@@ -51,6 +52,11 @@ def conv1d(input, weight, bias=None, stride=1, padding=0, dilation=1,
         weight: filters of shape (out_channels, in_channels, kW)
         bias: optional bias of shape (out_channels)
         stride: the stride of the convolving kernel, default 1
+        padding: implicit zero padding on the input. Can be a single number or
+          a tuple. Default: 0
+        dilation: the spacing between kernel elements. Default: 1
+        groups: split input into groups, in_channels should be divisible by
+          the number of groups
 
     Examples:
         >>> filters = autograd.Variable(torch.randn(33, 16, 3))
@@ -77,6 +83,9 @@ def conv3d(input, weight, bias=None, stride=1, padding=0, dilation=1,
           a tuple (st x sh x sw). Default: 1
         padding: implicit zero padding on the input. Can be a single number or
           a tuple. Default: 0
+        dilation: the spacing between kernel elements. Default: 1
+        groups: split input into groups, in_channels should be divisible by
+          the number of groups
 
     Examples:
         >>> filters = autograd.Variable(torch.randn(33, 16, 3, 3, 3))
@@ -89,14 +98,15 @@ def conv3d(input, weight, bias=None, stride=1, padding=0, dilation=1,
 
 
 def conv_transpose1d(input, weight, bias=None, stride=1, padding=0,
-                     output_padding=0, groups=1):
-    f = ConvNd(_single(stride), _single(padding), _single(1), True,
-               _single(output_padding), groups, torch.backends.cudnn.benchmark, torch.backends.cudnn.enabled)
+                     output_padding=0, groups=1, dilation=1):
+    f = ConvNd(_single(stride), _single(padding), _single(dilation), True,
+               _single(output_padding),
+               groups, torch.backends.cudnn.benchmark, torch.backends.cudnn.enabled)
     return f(input, weight, bias)
 
 
 def conv_transpose2d(input, weight, bias=None, stride=1, padding=0,
-                     output_padding=0, groups=1):
+                     output_padding=0, groups=1, dilation=1):
     """Applies a 2D transposed convolution operator over an input image
     composed of several input planes, sometimes also called "deconvolution".
 
@@ -114,14 +124,15 @@ def conv_transpose2d(input, weight, bias=None, stride=1, padding=0,
           the number of groups
         output_padding: A zero-padding of 0 <= padding < stride that should be
           added to the output. Can be a single number or a tuple. Default: 0
+        dilation: the spacing between kernel elements. Default: 1
     """
-    f = ConvNd(_pair(stride), _pair(padding), _pair(1), True,
+    f = ConvNd(_pair(stride), _pair(padding), _pair(dilation), True,
                _pair(output_padding), groups, torch.backends.cudnn.benchmark, torch.backends.cudnn.enabled)
     return f(input, weight, bias)
 
 
 def conv_transpose3d(input, weight, bias=None, stride=1, padding=0,
-                     output_padding=0, groups=1):
+                     output_padding=0, groups=1, dilation=1):
     """Applies a 3D transposed convolution operator over an input image
     composed of several input planes, sometimes also called "deconvolution"
 
@@ -135,8 +146,13 @@ def conv_transpose3d(input, weight, bias=None, stride=1, padding=0,
           tuple (sh x sw). Default: 1
         padding: implicit zero padding on the input, a single number or a
           tuple (padh x padw). Default: 0
+        output_padding: A zero-padding of 0 <= padding < stride that should be
+          added to the output. Can be a single number or a tuple. Default: 0
+        groups: split input into groups, in_channels should be divisible by
+          the number of groups
+        dilation: the spacing between kernel elements. Default: 1
     """
-    f = ConvNd(_triple(stride), _triple(padding), _triple(1), True,
+    f = ConvNd(_triple(stride), _triple(padding), _triple(dilation), True,
                _triple(output_padding), groups, torch.backends.cudnn.benchmark, torch.backends.cudnn.enabled)
     return f(input, weight, bias)
 
diff --git a/torch/nn/modules/conv.py b/torch/nn/modules/conv.py
--- a/torch/nn/modules/conv.py
+++ b/torch/nn/modules/conv.py
@@ -407,11 +407,11 @@ class ConvTranspose1d(_ConvTransposeMixin, _ConvNd):
     """
 
     def __init__(self, in_channels, out_channels, kernel_size, stride=1,
-                 padding=0, output_padding=0, groups=1, bias=True):
+                 padding=0, output_padding=0, groups=1, bias=True, dilation=1):
         kernel_size = _single(kernel_size)
         stride = _single(stride)
         padding = _single(padding)
-        dilation = _single(1)
+        dilation = _single(dilation)
         output_padding = _single(output_padding)
         super(ConvTranspose1d, self).__init__(
             in_channels, out_channels, kernel_size, stride, padding, dilation,
@@ -467,6 +467,7 @@ class ConvTranspose2d(_ConvTransposeMixin, _ConvNd):
         output_padding (int or tuple, optional): Zero-padding added to one side of the output
         groups (int, optional): Number of blocked connections from input channels to output channels
         bias (bool, optional): If True, adds a learnable bias to the output
+        dilation (int or tuple, optional): Spacing between kernel elements
 
     Shape:
         - Input: :math:`(N, C_{in}, H_{in}, W_{in})`
@@ -506,11 +507,11 @@ class ConvTranspose2d(_ConvTransposeMixin, _ConvNd):
     """
 
     def __init__(self, in_channels, out_channels, kernel_size, stride=1,
-                 padding=0, output_padding=0, groups=1, bias=True):
+                 padding=0, output_padding=0, groups=1, bias=True, dilation=1):
         kernel_size = _pair(kernel_size)
         stride = _pair(stride)
         padding = _pair(padding)
-        dilation = _pair(1)
+        dilation = _pair(dilation)
         output_padding = _pair(output_padding)
         super(ConvTranspose2d, self).__init__(
             in_channels, out_channels, kernel_size, stride, padding, dilation,
@@ -566,6 +567,7 @@ class ConvTranspose3d(_ConvTransposeMixin, _ConvNd):
         output_padding (int or tuple, optional): Zero-padding added to one side of the output
         groups (int, optional): Number of blocked connections from input channels to output channels
         bias (bool, optional): If True, adds a learnable bias to the output
+        dilation (int or tuple, optional): Spacing between kernel elements
 
     Shape:
         - Input: :math:`(N, C_{in}, D_{in}, H_{in}, W_{in})`
@@ -596,11 +598,11 @@ class ConvTranspose3d(_ConvTransposeMixin, _ConvNd):
     """
 
     def __init__(self, in_channels, out_channels, kernel_size, stride=1,
-                 padding=0, output_padding=0, groups=1, bias=True):
+                 padding=0, output_padding=0, groups=1, bias=True, dilation=1):
         kernel_size = _triple(kernel_size)
         stride = _triple(stride)
         padding = _triple(padding)
-        dilation = _triple(1)
+        dilation = _triple(dilation)
         output_padding = _triple(output_padding)
         super(ConvTranspose3d, self).__init__(
             in_channels, out_channels, kernel_size, stride, padding, dilation,


Test patch:
diff --git a/test/test_nn.py b/test/test_nn.py
--- a/test/test_nn.py
+++ b/test/test_nn.py
@@ -2393,6 +2393,13 @@ def add_test(test):
         cudnn=True,
         desc='no_bias'
     ),
+    dict(
+        module_name='ConvTranspose1d',
+        constructor_args=(3, 4, 3, 2, 1, 1, 1, True, 2),
+        input_size=(1, 3, 6),
+        cudnn=True,
+        desc='dilated'
+    ),
     dict(
         module_name='MaxPool1d',
         constructor_args=(4,),
@@ -2455,6 +2462,13 @@ def add_test(test):
         cudnn=True,
         input_size=(1, 3, 7, 6)
     ),
+    dict(
+        module_name='ConvTranspose2d',
+        constructor_args=(3, 4, 3, (2, 3), 1, (1, 1), 1, False, (2, 2)),
+        input_size=(1, 3, 6, 7),
+        cudnn=True,
+        desc='dilated'
+    ),
     dict(
         module_name='ConvTranspose2d',
         constructor_args=(3, 4, 3, (2, 3), 1, (1, 1), 1, False),
@@ -2572,6 +2586,13 @@ def add_test(test):
         cudnn=True,
         input_size=(1, 2, 4, 5, 4)
     ),
+    dict(
+        module_name='ConvTranspose3d',
+        constructor_args=(2, 3, (2, 3, 2), 1, 0, 0, 1, True, (2, 2, 2)),
+        cudnn=True,
+        input_size=(1, 2, 4, 5, 4),
+        desc='dilated'
+    ),
     dict(
         module_name='MaxPool3d',
         constructor_args=((2, 2, 2),),