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.

normalization.py 10 kB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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. 'BatchNorm',
  8. 'BatchNorm1d',
  9. 'BatchNorm2d',
  10. 'BatchNorm3d',
  11. ]
  12. # TODO Layers that needs to be updated
  13. # ['InstanceNorm',
  14. # 'InstanceNorm1d',
  15. # 'InstanceNorm2d',
  16. # 'InstanceNorm3d',
  17. # 'LayerNorm',
  18. # 'GroupNorm',
  19. # 'SwitchNorm',
  20. # ]
  21. class BatchNorm(Module):
  22. """
  23. The :class:`BatchNorm` is a batch normalization layer for both fully-connected and convolution outputs.
  24. See ``tf.nn.batch_normalization`` and ``tf.nn.moments``.
  25. Parameters
  26. ----------
  27. decay : float
  28. A decay factor for `ExponentialMovingAverage`.
  29. Suggest to use a large value for large dataset.
  30. epsilon : float
  31. Eplison.
  32. act : activation function
  33. The activation function of this layer.
  34. is_train : boolean
  35. Is being used for training or inference.
  36. beta_init : initializer or None
  37. The initializer for initializing beta, if None, skip beta.
  38. Usually you should not skip beta unless you know what happened.
  39. gamma_init : initializer or None
  40. The initializer for initializing gamma, if None, skip gamma.
  41. When the batch normalization layer is use instead of 'biases', or the next layer is linear, this can be
  42. disabled since the scaling can be done by the next layer. see `Inception-ResNet-v2 <https://github.com/tensorflow/models/blob/master/research/slim/nets/inception_resnet_v2.py>`__
  43. moving_mean_init : initializer or None
  44. The initializer for initializing moving mean, if None, skip moving mean.
  45. moving_var_init : initializer or None
  46. The initializer for initializing moving var, if None, skip moving var.
  47. num_features: int
  48. Number of features for input tensor. Useful to build layer if using BatchNorm1d, BatchNorm2d or BatchNorm3d,
  49. but should be left as None if using BatchNorm. Default None.
  50. data_format : str
  51. channels_last 'channel_last' (default) or channels_first.
  52. name : None or str
  53. A unique layer name.
  54. Examples
  55. ---------
  56. With TensorLayer
  57. >>> net = tl.layers.Input([10, 50, 50, 32], name='input')
  58. >>> net = tl.layers.BatchNorm()(net)
  59. Notes
  60. -----
  61. The :class:`BatchNorm` is universally suitable for 3D/4D/5D input in static model, but should not be used
  62. in dynamic model where layer is built upon class initialization. So the argument 'num_features' should only be used
  63. for subclasses :class:`BatchNorm1d`, :class:`BatchNorm2d` and :class:`BatchNorm3d`. All the three subclasses are
  64. suitable under all kinds of conditions.
  65. References
  66. ----------
  67. - `Source <https://github.com/ry/tensorflow-resnet/blob/master/resnet.py>`__
  68. - `stackoverflow <http://stackoverflow.com/questions/38312668/how-does-one-do-inference-with-batch-normalization-with-tensor-flow>`__
  69. """
  70. def __init__(
  71. self,
  72. decay=0.9,
  73. epsilon=0.00001,
  74. act=None,
  75. is_train=True,
  76. beta_init=tl.initializers.zeros(),
  77. gamma_init=tl.initializers.random_normal(mean=1.0, stddev=0.002),
  78. moving_mean_init=tl.initializers.zeros(),
  79. moving_var_init=tl.initializers.zeros(),
  80. num_features=None,
  81. data_format='channels_last',
  82. name=None,
  83. ):
  84. super(BatchNorm, self).__init__(name=name, act=act)
  85. self.decay = decay
  86. self.epsilon = epsilon
  87. self.data_format = data_format
  88. self.beta_init = beta_init
  89. self.gamma_init = gamma_init
  90. self.moving_mean_init = moving_mean_init
  91. self.moving_var_init = moving_var_init
  92. self.num_features = num_features
  93. self.is_train = is_train
  94. self.axes = None
  95. # if self.num_features is None:
  96. # raise AttributeError(
  97. # "The registered layer `{}` should be built in advance. "
  98. # "Do you forget to pass the keyword argument 'num_feature'? "
  99. # )
  100. if self.num_features:
  101. self.build(None)
  102. self._built = True
  103. if self.decay < 0.0 or 1.0 < self.decay:
  104. raise ValueError("decay should be between 0 to 1")
  105. logging.info(
  106. "BatchNorm %s: decay: %f epsilon: %f act: %s is_train: %s" % (
  107. self.name, decay, epsilon, self.act.__class__.__name__ if self.act is not None else 'No Activation',
  108. is_train
  109. )
  110. )
  111. def __repr__(self):
  112. actstr = self.act.__class__.__name__ if self.act is not None else 'No Activation'
  113. s = ('{classname}(num_features={num_features}, decay={decay}' ', epsilon={epsilon}')
  114. s += (', ' + actstr)
  115. if self.name is not None:
  116. s += ', name="{name}"'
  117. s += ')'
  118. return s.format(classname=self.__class__.__name__, **self.__dict__)
  119. def _get_param_shape(self, inputs_shape):
  120. if self.data_format == 'channels_last':
  121. axis = -1
  122. elif self.data_format == 'channels_first':
  123. axis = 1
  124. else:
  125. raise ValueError('data_format should be either %s or %s' % ('channels_last', 'channels_first'))
  126. channels = inputs_shape[axis]
  127. params_shape = [channels]
  128. return params_shape
  129. def _check_input_shape(self, inputs):
  130. if inputs.ndim <= 1:
  131. raise ValueError('expected input at least 2D, but got {}D input'.format(inputs.ndim))
  132. def build(self, inputs_shape):
  133. params_shape = [self.num_features] if self.num_features is not None else self._get_param_shape(inputs_shape)
  134. self.beta, self.gamma = None, None
  135. if self.beta_init:
  136. self.beta = self._get_weights(var_name="beta", shape=params_shape, init=self.beta_init)
  137. if self.gamma_init:
  138. self.gamma = self._get_weights(var_name="gamma", shape=params_shape, init=self.gamma_init)
  139. self.moving_mean = self._get_weights(
  140. var_name="moving_mean", shape=params_shape, init=self.moving_mean_init, trainable=False
  141. )
  142. self.moving_var = self._get_weights(
  143. var_name="moving_var", shape=params_shape, init=self.moving_var_init, trainable=False
  144. )
  145. self.batchnorm = tl.ops.BatchNorm(
  146. decay=self.decay, epsilon=self.epsilon, beta=self.beta, gamma=self.gamma, moving_mean=self.moving_mean,
  147. moving_var=self.moving_var, num_features=self.num_features, data_format=self.data_format,
  148. is_train=self.is_train
  149. )
  150. self.act_init_flag = False
  151. if self.act:
  152. self.act_init_flag = True
  153. def forward(self, inputs):
  154. self._check_input_shape(inputs)
  155. if self._forward_state == False:
  156. if self._built == False:
  157. self.build(tl.get_tensor_shape(inputs))
  158. self._built = True
  159. self._forward_state = True
  160. if not self.is_train:
  161. self.batchnorm = tl.ops.BatchNorm(
  162. decay=self.decay, epsilon=self.epsilon, beta=self.beta, gamma=self.gamma, moving_mean=self.moving_mean,
  163. moving_var=self.moving_var, num_features=self.num_features, data_format=self.data_format, is_train=False
  164. )
  165. outputs = self.batchnorm(inputs=inputs)
  166. if self.act_init_flag:
  167. outputs = self.act(outputs)
  168. return outputs
  169. class BatchNorm1d(BatchNorm):
  170. """The :class:`BatchNorm1d` applies Batch Normalization over 2D/3D input (a mini-batch of 1D
  171. inputs (optional) with additional channel dimension), of shape (N, C) or (N, L, C) or (N, C, L).
  172. See more details in :class:`BatchNorm`.
  173. Examples
  174. ---------
  175. With TensorLayer
  176. >>> # in static model, no need to specify num_features
  177. >>> net = tl.layers.Input([10, 50, 32], name='input')
  178. >>> net = tl.layers.BatchNorm1d()(net)
  179. >>> # in dynamic model, build by specifying num_features
  180. >>> conv = tl.layers.Conv1d(32, 5, 1, in_channels=3)
  181. >>> bn = tl.layers.BatchNorm1d(num_features=32)
  182. """
  183. def _check_input_shape(self, inputs):
  184. if inputs.ndim != 2 and inputs.ndim != 3:
  185. raise ValueError('expected input to be 2D or 3D, but got {}D input'.format(inputs.ndim))
  186. class BatchNorm2d(BatchNorm):
  187. """The :class:`BatchNorm2d` applies Batch Normalization over 4D input (a mini-batch of 2D
  188. inputs with additional channel dimension) of shape (N, H, W, C) or (N, C, H, W).
  189. See more details in :class:`BatchNorm`.
  190. Examples
  191. ---------
  192. With TensorLayer
  193. >>> # in static model, no need to specify num_features
  194. >>> net = tl.layers.Input([10, 50, 50, 32], name='input')
  195. >>> net = tl.layers.BatchNorm2d()(net)
  196. >>> # in dynamic model, build by specifying num_features
  197. >>> conv = tl.layers.Conv2d(32, (5, 5), (1, 1), in_channels=3)
  198. >>> bn = tl.layers.BatchNorm2d(num_features=32)
  199. """
  200. def _check_input_shape(self, inputs):
  201. if inputs.ndim != 4:
  202. raise ValueError('expected input to be 4D, but got {}D input'.format(inputs.ndim))
  203. class BatchNorm3d(BatchNorm):
  204. """The :class:`BatchNorm3d` applies Batch Normalization over 5D input (a mini-batch of 3D
  205. inputs with additional channel dimension) with shape (N, D, H, W, C) or (N, C, D, H, W).
  206. See more details in :class:`BatchNorm`.
  207. Examples
  208. ---------
  209. With TensorLayer
  210. >>> # in static model, no need to specify num_features
  211. >>> net = tl.layers.Input([10, 50, 50, 50, 32], name='input')
  212. >>> net = tl.layers.BatchNorm3d()(net)
  213. >>> # in dynamic model, build by specifying num_features
  214. >>> conv = tl.layers.Conv3d(32, (5, 5, 5), (1, 1), in_channels=3)
  215. >>> bn = tl.layers.BatchNorm3d(num_features=32)
  216. """
  217. def _check_input_shape(self, inputs):
  218. if inputs.ndim != 5:
  219. raise ValueError('expected input to be 5D, but got {}D input'.format(inputs.ndim))

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