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.

basic.py 20 kB

6 years ago
6 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. # Copyright 2020 Huawei Technologies Co., Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ============================================================================
  15. """basic"""
  16. import numpy as np
  17. import mindspore.common.dtype as mstype
  18. from mindspore.common.tensor import Tensor
  19. from mindspore.common.initializer import initializer
  20. from mindspore._checkparam import check_int_positive, check_bool
  21. from mindspore.ops import operations as P
  22. from mindspore.ops import functional as F
  23. from mindspore.ops.functional import identity
  24. from mindspore.common.parameter import Parameter
  25. from mindspore._extends import cell_attr_register
  26. from mindspore.common.api import ms_function
  27. from ..cell import Cell
  28. from .activation import get_activation
  29. from ..._checkparam import Validator as validator
  30. class Dropout(Cell):
  31. r"""
  32. Dropout layer for the input.
  33. Randomly set some elements of the input tensor to zero with probability :math:`1 - keep\_prob` during training
  34. using samples from a Bernoulli distribution.
  35. Note:
  36. Each channel will be zeroed out independently on every construct call.
  37. The outputs are scaled by a factor of :math:`\frac{1}{keep\_prob}` during training so
  38. that the output layer remains at a similar scale. During inference, this
  39. layer returns the same tensor as the input.
  40. This technique is proposed in paper `Dropout: A Simple Way to Prevent Neural Networks from Overfitting
  41. <http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf>`_ and proved to be effective to reduce
  42. over-fitting and prevents neurons from co-adaptation. See more details in `Improving neural networks by
  43. preventing co-adaptation of feature detectors
  44. <https://arxiv.org/pdf/1207.0580.pdf>`_.
  45. Args:
  46. keep_prob (float): The keep rate, greater than 0 and less equal than 1. E.g. rate=0.9,
  47. dropping out 10% of input units. Default: 0.5.
  48. seed0 (int): The first random seed. Default: 0.
  49. seed1 (int): The second random seed. Default: 0.
  50. dtype (:class:`mindspore.dtype`): Data type of input. Default: mindspore.float32.
  51. Raises:
  52. ValueError: If keep_prob is not in range (0, 1).
  53. Inputs:
  54. - **input** (Tensor) - An N-D Tensor.
  55. Outputs:
  56. Tensor, output tensor with the same shape as the input.
  57. Examples:
  58. >>> x = Tensor(np.ones([20, 16, 50]), mindspore.float32)
  59. >>> net = nn.Dropout(keep_prob=0.8)
  60. >>> net(x)
  61. """
  62. def __init__(self, keep_prob=0.5, seed0=0, seed1=0, dtype=mstype.float32):
  63. super(Dropout, self).__init__()
  64. if keep_prob <= 0 or keep_prob > 1:
  65. raise ValueError("dropout probability should be a number in range (0, 1], but got {}".format(keep_prob))
  66. validator.check_subclass("dtype", dtype, mstype.number_type, self.cls_name)
  67. self.keep_prob = Tensor(keep_prob)
  68. self.seed0 = seed0
  69. self.seed1 = seed1
  70. self.dtype = dtype
  71. self.get_shape = P.Shape()
  72. self.dropout_gen_mask = P.DropoutGenMask(Seed0=seed0, Seed1=seed1)
  73. self.dropout_do_mask = P.DropoutDoMask()
  74. self.cast = P.Cast()
  75. def construct(self, x):
  76. shape = self.get_shape(x)
  77. dtype = P.DType()(x)
  78. keep_prob = self.cast(self.keep_prob, dtype)
  79. output = self.dropout_gen_mask(shape, keep_prob)
  80. return self.dropout_do_mask(x, output, keep_prob)
  81. def extend_repr(self):
  82. str_info = 'keep_prob={}, Seed0={}, Seed1={}, dtype={}' \
  83. .format(self.keep_prob, self.seed0, self.seed1, self.dtype)
  84. return str_info
  85. class Flatten(Cell):
  86. r"""
  87. Flatten layer for the input.
  88. Flattens a tensor without changing dimension of batch size on the 0-th axis.
  89. Inputs:
  90. - **input** (Tensor) - Tensor of shape :math:`(N, \ldots)` to be flattened.
  91. Outputs:
  92. Tensor, the shape of the output tensor is :math:`(N, X)`, where :math:`X` is
  93. the product of the remaining dimensions.
  94. Examples:
  95. >>> net = nn.Flatten()
  96. >>> input = Tensor(np.array([[[1.2, 1.2], [2.1, 2.1]], [[2.2, 2.2], [3.2, 3.2]]]), mindspore.float32)
  97. >>> input.shape()
  98. (2, 2, 2)
  99. >>> net(input)
  100. [[1.2 1.2 2.1 2.1]
  101. [2.2 2.2 3.2 3.2]]
  102. """
  103. def __init__(self):
  104. super(Flatten, self).__init__()
  105. def construct(self, x):
  106. return F.reshape(x, (F.shape(x)[0], -1))
  107. class Dense(Cell):
  108. r"""
  109. The fully connected layer.
  110. Applies dense-connected layer for the input. This layer implements the operation as:
  111. .. math::
  112. \text{outputs} = \text{activation}(\text{inputs} * \text{kernel} + \text{bias}),
  113. where :math:`\text{activation}` is the activation function passed as the activation
  114. argument (if passed in), :math:`\text{activation}` is a weight matrix with the same
  115. data type as the inputs created by the layer, and :math:`\text{bias}` is a bias vector
  116. with the same data type as the inputs created by the layer (only if has_bias is True).
  117. Args:
  118. in_channels (int): The number of channels in the input space.
  119. out_channels (int): The number of channels in the output space.
  120. weight_init (Union[Tensor, str, Initializer, numbers.Number]): The trainable weight_init parameter. The dtype
  121. is same as input x. The values of str refer to the function `initializer`. Default: 'normal'.
  122. bias_init (Union[Tensor, str, Initializer, numbers.Number]): The trainable bias_init parameter. The dtype is
  123. same as input x. The values of str refer to the function `initializer`. Default: 'zeros'.
  124. has_bias (bool): Specifies whether the layer uses a bias vector. Default: True.
  125. activation (str): Regularizer function applied to the output of the layer, eg. 'relu'. Default: None.
  126. Raises:
  127. ValueError: If weight_init or bias_init shape is incorrect.
  128. Inputs:
  129. - **input** (Tensor) - Tensor of shape :math:`(N, in\_channels)`.
  130. Outputs:
  131. Tensor of shape :math:`(N, out\_channels)`.
  132. Examples:
  133. >>> net = nn.Dense(3, 4)
  134. >>> input = Tensor(np.random.randint(0, 255, [2, 3]), mindspore.float32)
  135. >>> net(input)
  136. [[ 2.5246444 2.2738023 0.5711005 -3.9399147 ]
  137. [ 1.0739875 4.0155234 0.94188046 -5.459526 ]]
  138. """
  139. @cell_attr_register(attrs=['has_bias', 'activation'])
  140. def __init__(self,
  141. in_channels,
  142. out_channels,
  143. weight_init='normal',
  144. bias_init='zeros',
  145. has_bias=True,
  146. activation=None):
  147. super(Dense, self).__init__()
  148. self.in_channels = check_int_positive(in_channels)
  149. self.out_channels = check_int_positive(out_channels)
  150. self.has_bias = check_bool(has_bias)
  151. if isinstance(weight_init, Tensor):
  152. if weight_init.dim() != 2 or weight_init.shape()[0] != out_channels or \
  153. weight_init.shape()[1] != in_channels:
  154. raise ValueError("weight_init shape error")
  155. self.weight = Parameter(initializer(weight_init, [out_channels, in_channels]), name="weight")
  156. if self.has_bias:
  157. if isinstance(bias_init, Tensor):
  158. if bias_init.dim() != 1 or bias_init.shape()[0] != out_channels:
  159. raise ValueError("bias_init shape error")
  160. self.bias = Parameter(initializer(bias_init, [out_channels]), name="bias")
  161. self.matmul = P.MatMul(transpose_b=True)
  162. self.bias_add = P.BiasAdd()
  163. self.activation = get_activation(activation)
  164. self.activation_flag = self.activation is not None
  165. def construct(self, x):
  166. output = self.matmul(x, self.weight)
  167. if self.has_bias:
  168. output = self.bias_add(output, self.bias)
  169. if self.activation_flag:
  170. return self.activation(output)
  171. return output
  172. def extend_repr(self):
  173. str_info = 'in_channels={}, out_channels={}, weight={}, has_bias={}' \
  174. .format(self.in_channels, self.out_channels, self.weight, self.has_bias)
  175. if self.has_bias:
  176. str_info = str_info + ', bias={}'.format(self.bias)
  177. if self.activation_flag:
  178. str_info = str_info + ', activation={}'.format(self.activation)
  179. return str_info
  180. class ClipByNorm(Cell):
  181. r"""
  182. Clips tensor values to a maximum :math:`L_2`-norm.
  183. The output of this layer remains the same if the :math:`L_2`-norm of the input tensor
  184. is not greater than the argument clip_norm. Otherwise the tensor will be normalized as:
  185. .. math::
  186. \text{output}(X) = \frac{\text{clip_norm} * X}{L_2(X)},
  187. where :math:`L_2(X)` is the :math:`L_2`-norm of :math:`X`.
  188. Inputs:
  189. - **input** (Tensor) - Tensor of shape N-D.
  190. - **clip_norm** (Tensor) - A scalar Tensor of shape :math:`()` or :math:`(1)` and of
  191. the same type as the input Tensor.
  192. Outputs:
  193. Tensor, clipped tensor with the same shape as the input.
  194. Examples:
  195. >>> net = nn.ClipByNorm()
  196. >>> input = Tensor(np.random.randint(0, 10, [4, 16]), mindspore.float32)
  197. >>> clip_norm = Tensor(np.array([100]).astype(np.float32))
  198. >>> net(input, clip_norm)
  199. """
  200. def __init__(self):
  201. super(ClipByNorm, self).__init__()
  202. self.reduce_sum = P.ReduceSum(keep_dims=True)
  203. self.select_ = P.Select()
  204. self.greater_ = P.Greater()
  205. self.axis = ()
  206. self.cast = P.Cast()
  207. self.zero = Tensor(np.array([0.0]).astype(np.float32))
  208. self.sqrt = P.Sqrt()
  209. self.max_op = P.Maximum()
  210. self.shape = P.Shape()
  211. self.reshape = P.Reshape()
  212. self.fill = P.Fill()
  213. self.expand_dims = P.ExpandDims()
  214. self.dtype = P.DType()
  215. @ms_function
  216. def construct(self, x, clip_norm):
  217. """add ms_function decorator for pynative mode"""
  218. mul_x = F.square(x)
  219. l2sum = self.cast(self.reduce_sum(mul_x, self.axis), mstype.float32)
  220. cond = self.greater_(l2sum, self.zero)
  221. ones_ = self.fill(self.dtype(cond), self.shape(cond), 1.0)
  222. l2sum_safe = self.select_(cond, l2sum, self.cast(ones_, self.dtype(l2sum)))
  223. l2norm = self.select_(cond, self.sqrt(l2sum_safe), l2sum)
  224. intermediate = x * clip_norm
  225. max_norm = self.max_op(l2norm, clip_norm)
  226. values_clip = self.cast(intermediate, mstype.float32) / self.expand_dims(max_norm, -1)
  227. values_clip = self.reshape(values_clip, self.shape(x))
  228. values_clip = identity(values_clip)
  229. return values_clip
  230. class Norm(Cell):
  231. """
  232. Computes the norm of vectors, currently including Euclidean norm, i.e., :math:`L_2`-norm.
  233. Args:
  234. axis (tuple): The axis over which to compute vector norms. Default: ().
  235. keep_dims (bool): If True, the axis indicated in `axis` are kept with size 1. Otherwise,
  236. the dimensions in `axis` are removed from the output shape. Default: False.
  237. Inputs:
  238. - **input** (Tensor) - Tensor which is not empty.
  239. Outputs:
  240. Tensor, output tensor with dimensions in 'axis' reduced to 1 will be returned if 'keep_dims' is True;
  241. otherwise a Tensor with dimensions in 'axis' removed is returned.
  242. Examples:
  243. >>> net = nn.Norm(axis=0)
  244. >>> input = Tensor(np.random.randint(0, 10, [4, 16]), mindspore.float32)
  245. >>> net(input)
  246. """
  247. def __init__(self, axis=(), keep_dims=False):
  248. super(Norm, self).__init__()
  249. self.axis = axis
  250. self.keep_dims = keep_dims
  251. self.reduce_sum = P.ReduceSum(True)
  252. self.sqrt = P.Sqrt()
  253. self.squeeze = P.Squeeze(self.axis)
  254. def construct(self, x):
  255. x = self.sqrt(self.reduce_sum(F.square(x), self.axis))
  256. if not self.keep_dims:
  257. x = self.squeeze(x)
  258. return x
  259. def extend_repr(self):
  260. str_info = 'axis={}, keep_dims={}'.format(self.axis, self.keep_dims)
  261. return str_info
  262. class OneHot(Cell):
  263. """
  264. Returns a one-hot tensor.
  265. The locations represented by indices in argument 'indices' take value on_value,
  266. while all other locations take value off_value.
  267. Note:
  268. If the input indices is rank :math:`N`, the output will have rank :math:`N+1`. The new
  269. axis is created at dimension `axis`.
  270. Args:
  271. axis (int): Features x depth if axis == -1, depth x features
  272. if axis == 0. Default: -1.
  273. depth (int): A scalar defining the depth of the one hot dimension. Default: 1.
  274. on_value (float): A scalar defining the value to fill in output[i][j]
  275. when indices[j] = i. Default: 1.0.
  276. off_value (float): A scalar defining the value to fill in output[i][j]
  277. when indices[j] != i. Default: 0.0.
  278. dtype (:class:`mindspore.dtype`): Data type of 'on_value' and 'off_value', not the
  279. data type of indices. Default: mindspore.float32.
  280. Inputs:
  281. - **indices** (Tensor) - A tensor of indices of data type mindspore.int32 and arbitrary shape.
  282. Outputs:
  283. Tensor, the one-hot tensor of data type 'dtype' with dimension at 'axis' expanded to 'depth' and filled with
  284. on_value and off_value.
  285. Examples:
  286. >>> net = nn.OneHot(depth=4, axis=1)
  287. >>> indices = Tensor([[1, 3], [0, 2]], dtype=mindspore.int32)
  288. >>> net(indices)
  289. [[[0. 0.]
  290. [1. 0.]
  291. [0. 0.]
  292. [0. 1.]]
  293. [[1. 0.]
  294. [0. 0.]
  295. [0. 1.]
  296. [0. 0.]]]
  297. """
  298. def __init__(self, axis=-1, depth=1, on_value=1.0, off_value=0.0, dtype=mstype.float32):
  299. super(OneHot, self).__init__()
  300. self.onehot = P.OneHot(axis)
  301. self.depth = depth
  302. self.on_value = Tensor(on_value, dtype)
  303. self.off_value = Tensor(off_value, dtype)
  304. def construct(self, indices):
  305. return self.onehot(indices, self.depth, self.on_value, self.off_value)
  306. class Pad(Cell):
  307. """
  308. Pads the input tensor according to the paddings and mode.
  309. Args:
  310. paddings (tuple): The shape of parameter `paddings` is (N, 2). N is the rank of input data. All elements of
  311. paddings are int type. For `D` th dimension of input, paddings[D, 0] indicates how many sizes to be
  312. extended ahead of the `D` th dimension of the input tensor, and paddings[D, 1] indicates how many sizes to
  313. be extended behind of the `D` th dimension of the input tensor.
  314. mode (string): Specifies padding mode. The optional values are "CONSTANT", "REFLECT", "SYMMETRIC".
  315. Default: "CONSTANT".
  316. Inputs:
  317. - ** input_x** (Tensor) - The input tensor.
  318. Outputs:
  319. Tensor, the tensor after padding.
  320. - If `mode` is "CONSTANT", it fill the edge with 0, regardless of the values of the `input_x`.
  321. If the `input_x` is [[1,2,3],[4,5,6],[7,8,9]] and `paddings` is [[1,1],[2,2]], then the
  322. Outputs is [[0,0,0,0,0,0,0],[0,0,1,2,3,0,0],[0,0,4,5,6,0,0],[0,0,7,8,9,0,0],[0,0,0,0,0,0,0]].
  323. - If 'mode` is "REFLECT", it uses a way of symmetrical copying throught the axis of symmetry to fill in,
  324. symmetry. If the `input_x` is [[1,2,3],[4,5,6],[7,8,9]] and `paddings` is [[1,1],[2,2]], then the
  325. Outputs is [[6,5,4,5,6,5,4],[3,2,1,2,3,2,1],[6,5,4,5,6,5,4],[9,8,7,8,9,8,7],[6,5,4,5,6,5,4]].
  326. - If 'mode' is "SYMMETRIC", the filling method is similar to the "REFLECT". It is also copied
  327. according to the symmetry axis, except that it includes the symmetry axis. If the `input_x`
  328. is [[1,2,3],[4,5,6],[7,8,9]] and `paddings` is [[1,1],[2,2]], then the Outputs is
  329. [[2,1,1,2,3,3,2],[2,1,1,2,3,3,2],[5,4,4,5,6,6,5],[8,7,7,8,9,9,8],[8,7,7,8,9,9,8]].
  330. Examples:
  331. >>> from mindspore import Tensor
  332. >>> from mindspore.ops import operations as P
  333. >>> import mindspore.nn as nn
  334. >>> import numpy as np
  335. >>> class Net(nn.Cell):
  336. >>> def __init__(self):
  337. >>> super(Net, self).__init__()
  338. >>> self.pad = nn.Pad(paddings=((1,1),(2,2)), mode="CONSTANT")
  339. >>> def construct(self, x):
  340. >>> return self.pad(x)
  341. >>> x = np.random.random(size=(2, 3)).astype(np.float32)
  342. >>> pad = Net()
  343. >>> ms_output = pad(Tensor(x))
  344. """
  345. def __init__(self, paddings, mode="CONSTANT"):
  346. super(Pad, self).__init__()
  347. self.mode = mode
  348. self.paddings = paddings
  349. validator.check_string('mode', self.mode, ["CONSTANT", "REFLECT", "SYMMETRIC"], self.cls_name)
  350. if not isinstance(paddings, tuple):
  351. raise TypeError('Paddings must be tuple type.')
  352. for item in paddings:
  353. if len(item) != 2:
  354. raise ValueError('The shape of paddings must be (n, 2).')
  355. if mode == "CONSTANT":
  356. self.pad = P.Pad(self.paddings)
  357. else:
  358. self.paddings = Tensor(np.array(self.paddings))
  359. self.pad = P.MirrorPad(mode=mode)
  360. def construct(self, x):
  361. if self.mode == "CONSTANT":
  362. x = self.pad(x)
  363. else:
  364. x = self.pad(x, self.paddings)
  365. return x
  366. class Unfold(Cell):
  367. """
  368. Extract patches from images.
  369. The input tensor must be a 4-D tensor and the data format is NCHW.
  370. Args:
  371. ksizes (Union[tuple[int], list[int]]): The size of sliding window, should be a tuple or list of int,
  372. and the format is [1, ksize_row, ksize_col, 1].
  373. strides (Union[tuple[int], list[int]]): Distance between the centers of the two consecutive patches,
  374. should be a tuple or list of int, and the format is [1, stride_row, stride_col, 1].
  375. rates (Union[tuple[int], list[int]]): In each extracted patch, the gap between the corresponding dim
  376. pixel positions, should be a tuple or list of int, and the format is [1, rate_row, rate_col, 1].
  377. padding (str): The type of padding algorithm, is a string whose value is "same" or "valid",
  378. not case sensitive. Default: "valid".
  379. - same: Means that the patch can take the part beyond the original image, and this part is filled with 0.
  380. - valid: Means that the patch area taken must be completely contained in the original image.
  381. Inputs:
  382. - **input_x** (Tensor) - A 4-D tensor whose shape is [in_batch, in_depth, in_row, in_col] and
  383. data type is int8, float16, uint8.
  384. Outputs:
  385. Tensor, a 4-D tensor whose data type is same as 'input_x',
  386. and the shape is [out_batch, out_depth, out_row, out_col], the out_batch is same as the in_batch.
  387. Examples:
  388. >>> net = Unfold(ksizes=[1, 2, 2, 1], strides=[1, 1, 1, 1], rates=[1, 1, 1, 1])
  389. >>> image = Tensor(np.ones([1, 1, 3, 3]), dtype=mstype.float16)
  390. >>> net(image)
  391. Tensor ([[[[1, 1] [1, 1]] [[1, 1], [1, 1]] [[1, 1] [1, 1]], [[1, 1], [1, 1]]]],
  392. shape=(1, 4, 2, 2), dtype=mstype.float16)
  393. """
  394. def __init__(self, ksizes, strides, rates, padding="valid"):
  395. super(Unfold, self).__init__()
  396. self.extract_image_patches = P.ExtractImagePatches(ksizes, strides, rates, padding)
  397. self.transpose = P.Transpose()
  398. self.format_NHWC = (0, 2, 3, 1)
  399. self.format_NCHW = (0, 3, 1, 2)
  400. def construct(self, input_x):
  401. x_transpose = self.transpose(input_x, self.format_NHWC)
  402. ret = self.extract_image_patches(x_transpose)
  403. ret_transpose = self.transpose(ret, self.format_NCHW)
  404. return ret_transpose