You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

super_resolution.py 7.3 kB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #! /usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import tensorlayer as tl
  4. from tensorlayer import logging
  5. from tensorlayer.layers.core import Module
  6. __all__ = [
  7. 'SubpixelConv1d',
  8. 'SubpixelConv2d',
  9. ]
  10. class SubpixelConv1d(Module):
  11. """It is a 1D sub-pixel up-sampling layer.
  12. Calls a TensorFlow function that directly implements this functionality.
  13. We assume input has dim (batch, width, r)
  14. Parameters
  15. ------------
  16. scale : int
  17. The up-scaling ratio, a wrong setting will lead to Dimension size error.
  18. act : activation function
  19. The activation function of this layer.
  20. in_channels : int
  21. The number of in channels.
  22. name : str
  23. A unique layer name.
  24. Examples
  25. ----------
  26. With TensorLayer
  27. >>> net = tl.layers.Input([8, 25, 32], name='input')
  28. >>> subpixelconv1d = tl.layers.SubpixelConv1d(scale=2, name='subpixelconv1d')(net)
  29. >>> print(subpixelconv1d)
  30. >>> output shape : (8, 50, 16)
  31. References
  32. -----------
  33. `Audio Super Resolution Implementation <https://github.com/kuleshov/audio-super-res/blob/master/src/models/layers/subpixel.py>`__.
  34. """
  35. def __init__(
  36. self,
  37. scale=2,
  38. act=None,
  39. in_channels=None,
  40. name=None # 'subpixel_conv1d'
  41. ):
  42. super().__init__(name, act=act)
  43. self.scale = scale
  44. self.in_channels = in_channels
  45. # self.out_channels = int(self.in_channels / self.scale)
  46. if self.in_channels is not None:
  47. self.build(None)
  48. self._built = True
  49. logging.info(
  50. "SubpixelConv1d %s: scale: %d act: %s" %
  51. (self.name, scale, self.act.__class__.__name__ if self.act is not None else 'No Activation')
  52. )
  53. def __repr__(self):
  54. actstr = self.act.__class__.__name__ if self.act is not None else 'No Activation'
  55. s = ('{classname}(in_channels={in_channels}, out_channels={out_channels}')
  56. s += (', ' + actstr)
  57. if self.name is not None:
  58. s += ', name=\'{name}\''
  59. s += ')'
  60. return s.format(classname=self.__class__.__name__, **self.__dict__)
  61. def build(self, inputs_shape):
  62. if inputs_shape is not None:
  63. self.in_channels = inputs_shape[-1]
  64. self.out_channels = int(self.in_channels / self.scale)
  65. self.transpose = tl.ops.Transpose(perm=[2, 1, 0])
  66. self.batch_to_space = tl.ops.BatchToSpace(block_size=[self.scale], crops=[[0, 0]])
  67. def forward(self, inputs):
  68. if self._forward_state == False:
  69. if self._built == False:
  70. self.build(tl.get_tensor_shape(inputs))
  71. self._built = True
  72. self._forward_state = True
  73. outputs = self._PS(inputs)
  74. if self.act is not None:
  75. outputs = self.act(outputs)
  76. return outputs
  77. def _PS(self, I):
  78. X = self.transpose(I) # (r, w, b)
  79. X = self.batch_to_space(X) # (1, r*w, b)
  80. X = self.transpose(X)
  81. return X
  82. class SubpixelConv2d(Module):
  83. """It is a 2D sub-pixel up-sampling layer, usually be used
  84. for Super-Resolution applications, see `SRGAN <https://github.com/tensorlayer/srgan/>`__ for example.
  85. Parameters
  86. ------------
  87. scale : int
  88. The up-scaling ratio, a wrong setting will lead to dimension size error.
  89. n_out_channel : int or None
  90. The number of output channels.
  91. - If None, automatically set n_out_channel == the number of input channels / (scale x scale).
  92. - The number of input channels == (scale x scale) x The number of output channels.
  93. act : activation function
  94. The activation function of this layer.
  95. in_channels : int
  96. The number of in channels.
  97. name : str
  98. A unique layer name.
  99. Examples
  100. ---------
  101. With TensorLayer
  102. >>> # examples here just want to tell you how to set the n_out_channel.
  103. >>> net = tl.layers.Input([2, 16, 16, 4], name='input1')
  104. >>> subpixelconv2d = tl.layers.SubpixelConv2d(scale=2, n_out_channels=1, name='subpixel_conv2d1')(net)
  105. >>> print(subpixelconv2d)
  106. >>> output shape : (2, 32, 32, 1)
  107. >>> net = tl.layers.Input([2, 16, 16, 4*10], name='input2')
  108. >>> subpixelconv2d = tl.layers.SubpixelConv2d(scale=2, n_out_channels=10, name='subpixel_conv2d2')(net)
  109. >>> print(subpixelconv2d)
  110. >>> output shape : (2, 32, 32, 10)
  111. >>> net = tl.layers.Input([2, 16, 16, 25*10], name='input3')
  112. >>> subpixelconv2d = tl.layers.SubpixelConv2d(scale=5, n_out_channels=10, name='subpixel_conv2d3')(net)
  113. >>> print(subpixelconv2d)
  114. >>> output shape : (2, 80, 80, 10)
  115. References
  116. ------------
  117. - `Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network <https://arxiv.org/pdf/1609.05158.pdf>`__
  118. """
  119. # github/Tetrachrome/subpixel https://github.com/Tetrachrome/subpixel/blob/master/subpixel.py
  120. def __init__(
  121. self,
  122. scale=2,
  123. n_out_channels=None,
  124. act=None,
  125. in_channels=None,
  126. name=None # 'subpixel_conv2d'
  127. ):
  128. super().__init__(name, act=act)
  129. self.scale = scale
  130. self.n_out_channels = n_out_channels
  131. self.in_channels = in_channels
  132. if self.in_channels is not None:
  133. self.build(None)
  134. self._built = True
  135. logging.info(
  136. "SubpixelConv2d %s: scale: %d act: %s" %
  137. (self.name, scale, self.act.__class__.__name__ if self.act is not None else 'No Activation')
  138. )
  139. def __repr__(self):
  140. actstr = self.act.__class__.__name__ if self.act is not None else 'No Activation'
  141. s = ('{classname}(in_channels={in_channels}, out_channels={n_out_channels}')
  142. s += (', ' + actstr)
  143. if self.name is not None:
  144. s += ', name=\'{name}\''
  145. s += ')'
  146. return s.format(classname=self.__class__.__name__, **self.__dict__)
  147. def build(self, inputs_shape):
  148. if inputs_shape is not None:
  149. self.in_channels = inputs_shape[-1]
  150. if self.in_channels / (self.scale**2) % 1 != 0:
  151. raise Exception(
  152. "SubpixelConv2d: The number of input channels == (scale x scale) x The number of output channels"
  153. )
  154. self.n_out_channels = int(self.in_channels / (self.scale**2))
  155. self.depth_to_space = tl.ops.DepthToSpace(block_size=self.scale)
  156. def forward(self, inputs):
  157. if self._forward_state == False:
  158. if self._built == False:
  159. self.build(tl.get_tensor_shape(inputs))
  160. self._built = True
  161. self._forward_state = True
  162. outputs = self._PS(X=inputs, r=self.scale, n_out_channels=self.n_out_channels)
  163. if self.act is not None:
  164. outputs = self.act(outputs)
  165. return outputs
  166. def _PS(self, X, r, n_out_channels):
  167. _err_log = "SubpixelConv2d: The number of input channels == (scale x scale) x The number of output channels"
  168. if n_out_channels >= 1:
  169. if int(X.get_shape()[-1]) != (r**2) * n_out_channels:
  170. raise Exception(_err_log)
  171. X = self.depth_to_space(input=X)
  172. else:
  173. raise RuntimeError(_err_log)
  174. return X

TensorLayer3.0 是一款兼容多种深度学习框架为计算后端的深度学习库。计划兼容TensorFlow, Pytorch, MindSpore, Paddle.