Repository: facebookresearch/NeuralCompression (language: python)

Issue:
`SynthesisTransformation2D` layer
```Python
from torch import Tensor
from torch.nn import ConvTranspose2d, Module, Sequential

from ._generalized_divisive_normalization import GeneralizedDivisiveNormalization


class SynthesisTransformation(Module):
    def __init__(self, m: int, n: int):
        super(SynthesisTransformation, self).__init__()

        self._modules = Sequential(
            ConvTranspose2d(m, n, (5,), (2,), (2,), (1,)),
            GeneralizedDivisiveNormalization(n, inverse=True),
            ConvTranspose2d(n, n, (5,), (2,), (2,), (1,)),
            GeneralizedDivisiveNormalization(n, inverse=True),
            ConvTranspose2d(n, n, (5,), (2,), (2,), (1,)),
            GeneralizedDivisiveNormalization(n, inverse=True),
            ConvTranspose2d(n, 3, (5,), (2,), (2,), (1,)),
        )

    def forward(self, x: Tensor) -> Tensor:
        return self._modules(x)
```

Prerequisites

- [x] #85 


Discussion / hints:

Fix patch:
diff --git a/docs/source/layers.rst b/docs/source/layers.rst
index 3e234874..e4219b80 100644
--- a/docs/source/layers.rst
+++ b/docs/source/layers.rst
@@ -51,3 +51,10 @@ SimplifiedInverseGDN
 .. autoclass:: SimplifiedInverseGDN
   :members: __getitem__
   :special-members:
+
+SynthesisTransformation2D
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. autoclass:: SynthesisTransformation2D
+  :members: __getitem__
+  :special-members:
diff --git a/neuralcompression/layers/__init__.py b/neuralcompression/layers/__init__.py
index 066f094f..a957e1d7 100644
--- a/neuralcompression/layers/__init__.py
+++ b/neuralcompression/layers/__init__.py
@@ -10,4 +10,5 @@
 from ._hyper_analysis_transformation_2d import HyperAnalysisTransformation2D
 from ._hyper_synthesis_transformation_2d import HyperSynthesisTransformation2D
 from ._non_negative_parameterization import NonNegativeParameterization
+from ._synthesis_transformation_2d import SynthesisTransformation2D
 from .gdn import SimplifiedGDN, SimplifiedInverseGDN
diff --git a/neuralcompression/layers/_synthesis_transformation_2d.py b/neuralcompression/layers/_synthesis_transformation_2d.py
new file mode 100644
index 00000000..a95d2e1a
--- /dev/null
+++ b/neuralcompression/layers/_synthesis_transformation_2d.py
@@ -0,0 +1,22 @@
+from torch import Tensor
+from torch.nn import ConvTranspose2d, Module, Sequential
+
+from ._generalized_divisive_normalization import GeneralizedDivisiveNormalization
+
+
+class SynthesisTransformation2D(Module):
+    def __init__(self, m: int, n: int):
+        super(SynthesisTransformation2D, self).__init__()
+
+        self.model = Sequential(
+            ConvTranspose2d(m, n, (5, 5), (2, 2), (2, 2), (1, 1)),
+            GeneralizedDivisiveNormalization(n, inverse=True),
+            ConvTranspose2d(n, n, (5, 5), (2, 2), (2, 2), (1, 1)),
+            GeneralizedDivisiveNormalization(n, inverse=True),
+            ConvTranspose2d(n, n, (5, 5), (2, 2), (2, 2), (1, 1)),
+            GeneralizedDivisiveNormalization(n, inverse=True),
+            ConvTranspose2d(n, 3, (5, 5), (2, 2), (2, 2), (1, 1)),
+        )
+
+    def forward(self, x: Tensor) -> Tensor:
+        return self.model(x)


Test patch:
diff --git a/tests/layers/test_synthesis_transformation_2d.py b/tests/layers/test_synthesis_transformation_2d.py
new file mode 100644
index 00000000..e26c5e5c
--- /dev/null
+++ b/tests/layers/test_synthesis_transformation_2d.py
@@ -0,0 +1,18 @@
+"""
+Copyright (c) Facebook, Inc. and its affiliates.
+This source code is licensed under the MIT license found in the
+LICENSE file in the root directory of this source tree.
+"""
+
+import torch
+from torch import Size
+
+from neuralcompression.layers import SynthesisTransformation2D
+
+
+class TestSynthesisTransformation2D:
+    transformation = SynthesisTransformation2D(28, 28)
+
+    x = torch.rand((28, 28, 5, 5))
+
+    assert transformation(x).shape == Size([28, 3, 80, 80])