pixelshuffle.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. from .module import Module
  2. from .. import functional as F
  3. from torch import Tensor
  4. __all__ = ['PixelShuffle', 'PixelUnshuffle']
  5. class PixelShuffle(Module):
  6. r"""Rearranges elements in a tensor of shape :math:`(*, C \times r^2, H, W)`
  7. to a tensor of shape :math:`(*, C, H \times r, W \times r)`, where r is an upscale factor.
  8. This is useful for implementing efficient sub-pixel convolution
  9. with a stride of :math:`1/r`.
  10. See the paper:
  11. `Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network`_
  12. by Shi et. al (2016) for more details.
  13. Args:
  14. upscale_factor (int): factor to increase spatial resolution by
  15. Shape:
  16. - Input: :math:`(*, C_{in}, H_{in}, W_{in})`, where * is zero or more batch dimensions
  17. - Output: :math:`(*, C_{out}, H_{out}, W_{out})`, where
  18. .. math::
  19. C_{out} = C_{in} \div \text{upscale\_factor}^2
  20. .. math::
  21. H_{out} = H_{in} \times \text{upscale\_factor}
  22. .. math::
  23. W_{out} = W_{in} \times \text{upscale\_factor}
  24. Examples::
  25. >>> pixel_shuffle = nn.PixelShuffle(3)
  26. >>> input = torch.randn(1, 9, 4, 4)
  27. >>> output = pixel_shuffle(input)
  28. >>> print(output.size())
  29. torch.Size([1, 1, 12, 12])
  30. .. _Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network:
  31. https://arxiv.org/abs/1609.05158
  32. """
  33. __constants__ = ['upscale_factor']
  34. upscale_factor: int
  35. def __init__(self, upscale_factor: int) -> None:
  36. super().__init__()
  37. self.upscale_factor = upscale_factor
  38. def forward(self, input: Tensor) -> Tensor:
  39. return F.pixel_shuffle(input, self.upscale_factor)
  40. def extra_repr(self) -> str:
  41. return 'upscale_factor={}'.format(self.upscale_factor)
  42. class PixelUnshuffle(Module):
  43. r"""Reverses the :class:`~torch.nn.PixelShuffle` operation by rearranging elements
  44. in a tensor of shape :math:`(*, C, H \times r, W \times r)` to a tensor of shape
  45. :math:`(*, C \times r^2, H, W)`, where r is a downscale factor.
  46. See the paper:
  47. `Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network`_
  48. by Shi et. al (2016) for more details.
  49. Args:
  50. downscale_factor (int): factor to decrease spatial resolution by
  51. Shape:
  52. - Input: :math:`(*, C_{in}, H_{in}, W_{in})`, where * is zero or more batch dimensions
  53. - Output: :math:`(*, C_{out}, H_{out}, W_{out})`, where
  54. .. math::
  55. C_{out} = C_{in} \times \text{downscale\_factor}^2
  56. .. math::
  57. H_{out} = H_{in} \div \text{downscale\_factor}
  58. .. math::
  59. W_{out} = W_{in} \div \text{downscale\_factor}
  60. Examples::
  61. >>> pixel_unshuffle = nn.PixelUnshuffle(3)
  62. >>> input = torch.randn(1, 1, 12, 12)
  63. >>> output = pixel_unshuffle(input)
  64. >>> print(output.size())
  65. torch.Size([1, 9, 4, 4])
  66. .. _Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network:
  67. https://arxiv.org/abs/1609.05158
  68. """
  69. __constants__ = ['downscale_factor']
  70. downscale_factor: int
  71. def __init__(self, downscale_factor: int) -> None:
  72. super().__init__()
  73. self.downscale_factor = downscale_factor
  74. def forward(self, input: Tensor) -> Tensor:
  75. return F.pixel_unshuffle(input, self.downscale_factor)
  76. def extra_repr(self) -> str:
  77. return 'downscale_factor={}'.format(self.downscale_factor)