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 40 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058
  1. # Copyright 2020-2021 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 math
  17. import numpy as np
  18. import mindspore.common.dtype as mstype
  19. from mindspore.ops.composite.multitype_ops import _constexpr_utils as const_utils
  20. from mindspore.common.seed import _get_graph_seed
  21. from mindspore.common.tensor import Tensor
  22. from mindspore.common.initializer import initializer
  23. from mindspore.ops import operations as P
  24. from mindspore.ops import functional as F
  25. from mindspore.ops.functional import identity
  26. from mindspore.ops.operations import _inner_ops as inner
  27. from mindspore.ops.primitive import constexpr, Primitive
  28. from mindspore.common.parameter import Parameter
  29. from mindspore._extends import cell_attr_register
  30. from mindspore._checkparam import Rel, Validator
  31. from ..cell import Cell
  32. from .activation import get_activation
  33. __all__ = ['Dropout', 'Flatten', 'Dense', 'ClipByNorm', 'Norm', 'OneHot', 'Pad', 'Unfold',
  34. 'Tril', 'Triu', 'ResizeBilinear', 'MatrixDiag', 'MatrixDiagPart', 'MatrixSetDiag', 'L1Regularizer']
  35. class L1Regularizer(Cell):
  36. r"""
  37. Applies l1 regularization to weights.
  38. l1 regularization makes weights sparsity
  39. .. math::
  40. \text{loss}=\lambda * \text{reduce_sum}(\text{abs}(\omega))
  41. Note:
  42. scale(regularization factor) should be a number which greater than 0
  43. Args:
  44. scale (int, float): l1 regularization factor which greater than 0.
  45. Inputs:
  46. - **weights** (Tensor) - The input tensor
  47. Outputs:
  48. Tensor, which dtype is higher precision data type between mindspore.float32 and weights dtype,
  49. and Tensor shape is ()
  50. Raises:
  51. TypeError: If `scale` is neither an int nor float.
  52. ValueError: If `scale` is not greater than 0.
  53. ValueError: If `scale` is math.inf or math.nan.
  54. Supported Platforms:
  55. ``Ascend`` ``GPU`` ``CPU``
  56. Examples:
  57. >>> scale = 0.5
  58. >>> net = nn.L1Regularizer(scale)
  59. >>> weights = Tensor(np.array([[1.0, -2.0], [-3.0, 4.0]]).astype(np.float32))
  60. >>> output = net(weights)
  61. >>> print(output.asnumpy())
  62. 5.0
  63. """
  64. def __init__(self, scale):
  65. super(L1Regularizer, self).__init__()
  66. Validator.check_value_type("scale", scale, [int, float], self.cls_name)
  67. if scale <= 0:
  68. raise ValueError("scale should be a number which greater than 0")
  69. if math.isinf(scale) or math.isnan(scale):
  70. raise ValueError("scale can not be INF or NAN")
  71. self.abs = P.Abs()
  72. self.reduce_sum = P.ReduceSum()
  73. self.scale = Tensor(scale, dtype=mstype.float32)
  74. def construct(self, weights):
  75. const_utils.check_type_valid(F.dtype(weights), mstype.number_type, 'weights')
  76. l1_regularization = self.scale * self.reduce_sum(self.abs(weights))
  77. return l1_regularization
  78. class Dropout(Cell):
  79. r"""
  80. Dropout layer for the input.
  81. Randomly set some elements of the input tensor to zero with probability :math:`1 - keep\_prob` during training
  82. using samples from a Bernoulli distribution.
  83. The outputs are scaled by a factor of :math:`\frac{1}{keep\_prob}` during training so
  84. that the output layer remains at a similar scale. During inference, this
  85. layer returns the same tensor as the input.
  86. This technique is proposed in paper `Dropout: A Simple Way to Prevent Neural Networks from Overfitting
  87. <http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf>`_ and proved to be effective to reduce
  88. over-fitting and prevents neurons from co-adaptation. See more details in `Improving neural networks by
  89. preventing co-adaptation of feature detectors
  90. <https://arxiv.org/pdf/1207.0580.pdf>`_.
  91. Note:
  92. Each channel will be zeroed out independently on every construct call.
  93. Args:
  94. keep_prob (float): The keep rate, greater than 0 and less equal than 1. E.g. rate=0.9,
  95. dropping out 10% of input units. Default: 0.5.
  96. dtype (:class:`mindspore.dtype`): Data type of input. Default: mindspore.float32.
  97. Inputs:
  98. - **input** (Tensor) - The input of Dropout with data type of float16 or float32.
  99. Outputs:
  100. Tensor, output tensor with the same shape as the input.
  101. Raises:
  102. TypeError: If `keep_prob` is not a float.
  103. TypeError: If dtype of `input` is not neither float16 nor float32.
  104. ValueError: If `keep_prob` is not in range (0, 1].
  105. ValueError: If length of shape of `input` is less than 1.
  106. Supported Platforms:
  107. ``Ascend`` ``GPU`` ``CPU``
  108. Examples:
  109. >>> x = Tensor(np.ones([2, 2, 3]), mindspore.float32)
  110. >>> net = nn.Dropout(keep_prob=0.8)
  111. >>> net.set_train()
  112. Dropout<keep_prob=0.8>
  113. >>> output = net(x)
  114. >>> print(output.shape)
  115. (2, 2, 3)
  116. """
  117. def __init__(self, keep_prob=0.5, dtype=mstype.float32):
  118. super(Dropout, self).__init__()
  119. if keep_prob <= 0 or keep_prob > 1:
  120. raise ValueError("dropout probability should be a number in range (0, 1], but got {}".format(keep_prob))
  121. Validator.check_subclass("dtype", dtype, mstype.number_type, self.cls_name)
  122. Validator.check_value_type('keep_prob', keep_prob, [float], self.cls_name)
  123. self.keep_prob = keep_prob
  124. seed0, seed1 = _get_graph_seed(0, "dropout")
  125. self.seed0 = seed0
  126. self.seed1 = seed1
  127. self.dropout = P.Dropout(keep_prob, seed0, seed1)
  128. def construct(self, x):
  129. if not self.training:
  130. return x
  131. if self.keep_prob == 1:
  132. return x
  133. out, _ = self.dropout(x)
  134. return out
  135. def extend_repr(self):
  136. return 'keep_prob={}'.format(self.keep_prob)
  137. class Flatten(Cell):
  138. r"""
  139. Flatten layer for the input.
  140. Flattens a tensor without changing dimension of batch size on the 0-th axis.
  141. Inputs:
  142. - **input** (Tensor) - Tensor of shape :math:`(N, \ldots)` to be flattened.
  143. Outputs:
  144. Tensor, the shape of the output tensor is :math:`(N, X)`, where :math:`X` is
  145. the product of the remaining dimensions.
  146. Raises:
  147. TypeError: If `input` is not a subclass of Tensor.
  148. Supported Platforms:
  149. ``Ascend`` ``GPU`` ``CPU``
  150. Examples:
  151. >>> input = Tensor(np.array([[[1.2, 1.2], [2.1, 2.1]], [[2.2, 2.2], [3.2, 3.2]]]), mindspore.float32)
  152. >>> net = nn.Flatten()
  153. >>> output = net(input)
  154. >>> print(output)
  155. [[1.2 1.2 2.1 2.1]
  156. [2.2 2.2 3.2 3.2]]
  157. """
  158. def __init__(self):
  159. super(Flatten, self).__init__()
  160. def construct(self, x):
  161. return F.reshape(x, (F.shape(x)[0], -1))
  162. @constexpr
  163. def check_dense_input_shape(x):
  164. if len(x) < 2:
  165. raise ValueError('For Dense, the dimension of input should not be less than 2, while the input dimension is '
  166. + f'{len(x)}.')
  167. class Dense(Cell):
  168. r"""
  169. The dense connected layer.
  170. Applies dense connected layer for the input. This layer implements the operation as:
  171. .. math::
  172. \text{outputs} = \text{activation}(\text{inputs} * \text{kernel} + \text{bias}),
  173. where :math:`\text{activation}` is the activation function passed as the activation
  174. argument (if passed in), :math:`\text{kernel}` is a weight matrix with the same
  175. data type as the inputs created by the layer, and :math:`\text{bias}` is a bias vector
  176. with the same data type as the inputs created by the layer (only if has_bias is True).
  177. Args:
  178. in_channels (int): The number of channels in the input space.
  179. out_channels (int): The number of channels in the output space.
  180. weight_init (Union[Tensor, str, Initializer, numbers.Number]): The trainable weight_init parameter. The dtype
  181. is same as input x. The values of str refer to the function `initializer`. Default: 'normal'.
  182. bias_init (Union[Tensor, str, Initializer, numbers.Number]): The trainable bias_init parameter. The dtype is
  183. same as input x. The values of str refer to the function `initializer`. Default: 'zeros'.
  184. has_bias (bool): Specifies whether the layer uses a bias vector. Default: True.
  185. activation (Union[str, Cell, Primitive]): activate function applied to the output of the fully connected layer,
  186. eg. 'ReLU'.Default: None.
  187. Inputs:
  188. - **input** (Tensor) - Tensor of shape :math:`(*, in\_channels)`.
  189. Outputs:
  190. Tensor of shape :math:`(*, out\_channels)`.
  191. Raises:
  192. TypeError: If `in_channels` or `out_channels` is not an int.
  193. TypeError: If `has_bias` is not a bool.
  194. TypeError: If `activation` is not one of str, Cell, Primitive, None.
  195. ValueError: If length of shape of `weight_init` is not equal to 2 or shape[0] of `weight_init`
  196. is not equal to `out_channels` or shape[1] of `weight_init` is not equal to `in_channels`.
  197. ValueError: If length of shape of `bias_init` is not equal to 1
  198. or shape[0] of `bias_init` is not equal to `out_channels`.
  199. Supported Platforms:
  200. ``Ascend`` ``GPU`` ``CPU``
  201. Examples:
  202. >>> input = Tensor(np.array([[180, 234, 154], [244, 48, 247]]), mindspore.float32)
  203. >>> net = nn.Dense(3, 4)
  204. >>> output = net(input)
  205. >>> print(output.shape)
  206. (2, 4)
  207. """
  208. @cell_attr_register(attrs=['has_bias', 'activation'])
  209. def __init__(self,
  210. in_channels,
  211. out_channels,
  212. weight_init='normal',
  213. bias_init='zeros',
  214. has_bias=True,
  215. activation=None):
  216. super(Dense, self).__init__()
  217. self.in_channels = Validator.check_positive_int(in_channels)
  218. self.out_channels = Validator.check_positive_int(out_channels)
  219. self.has_bias = Validator.check_bool(has_bias)
  220. self.reshape = P.Reshape()
  221. self.shape_op = P.Shape()
  222. if isinstance(weight_init, Tensor):
  223. if weight_init.ndim != 2 or weight_init.shape[0] != out_channels or \
  224. weight_init.shape[1] != in_channels:
  225. raise ValueError("Weight init shape error.")
  226. self.weight = Parameter(initializer(weight_init, [out_channels, in_channels]), name="weight")
  227. self.bias = None
  228. if self.has_bias:
  229. if isinstance(bias_init, Tensor):
  230. if bias_init.ndim != 1 or bias_init.shape[0] != out_channels:
  231. raise ValueError("Bias init shape error.")
  232. self.bias = Parameter(initializer(bias_init, [out_channels]), name="bias")
  233. self.bias_add = P.BiasAdd()
  234. self.matmul = P.MatMul(transpose_b=True)
  235. self.activation = get_activation(activation) if isinstance(activation, str) else activation
  236. if activation is not None and not isinstance(self.activation, (Cell, Primitive)):
  237. raise TypeError("The activation must be str or Cell or Primitive,"" but got {}.".format(activation))
  238. self.activation_flag = self.activation is not None
  239. def construct(self, x):
  240. x_shape = self.shape_op(x)
  241. check_dense_input_shape(x_shape)
  242. if len(x_shape) != 2:
  243. x = self.reshape(x, (-1, x_shape[-1]))
  244. x = self.matmul(x, self.weight)
  245. if self.has_bias:
  246. x = self.bias_add(x, self.bias)
  247. if self.activation_flag:
  248. x = self.activation(x)
  249. if len(x_shape) != 2:
  250. out_shape = x_shape[:-1] + (-1,)
  251. x = self.reshape(x, out_shape)
  252. return x
  253. def extend_repr(self):
  254. s = 'input_channels={}, output_channels={}'.format(self.in_channels, self.out_channels)
  255. if self.has_bias:
  256. s += ', has_bias={}'.format(self.has_bias)
  257. if self.activation_flag:
  258. s += ', activation={}'.format(self.activation)
  259. return s
  260. @constexpr
  261. def _is_equal_one(x):
  262. if x is None:
  263. return False
  264. return bool(x.asnumpy().mean() == 1.0)
  265. @constexpr
  266. def _dtype_check(x_dtype):
  267. if x_dtype not in [mstype.float32, mstype.float16]:
  268. raise TypeError("The input type must be float32 or float16.")
  269. @constexpr
  270. def _is_float_dtype(dtype):
  271. if dtype in [mstype.float32, mstype.float16]:
  272. return True
  273. return False
  274. @constexpr
  275. def _need_reduce_all(axis):
  276. if axis == ():
  277. return True
  278. return False
  279. class ClipByNorm(Cell):
  280. r"""
  281. Clips tensor values to a maximum :math:`L_2`-norm.
  282. The output of this layer remains the same if the :math:`L_2`-norm of the input tensor
  283. is not greater than the argument clip_norm. Otherwise the tensor will be normalized as:
  284. .. math::
  285. \text{output}(X) = \frac{\text{clip_norm} * X}{L_2(X)},
  286. where :math:`L_2(X)` is the :math:`L_2`-norm of :math:`X`.
  287. Args:
  288. axis (Union[None, int, tuple(int)]): Compute the L2-norm along the Specific dimension.
  289. Default: None, all dimensions to calculate.
  290. Inputs:
  291. - **input** (Tensor) - Tensor of shape N-D. The type must be float32 or float16.
  292. - **clip_norm** (Tensor) - A scalar Tensor of shape :math:`()` or :math:`(1)`.
  293. Or a tensor shape can be broadcast to input shape.
  294. Outputs:
  295. Tensor, clipped tensor with the same shape as the input, whose type is float32.
  296. Raises:
  297. TypeError: If `axis` is not one of None, int, tuple.
  298. TypeError: If dtype of `input` is neither float32 nor float16.
  299. Supported Platforms:
  300. ``Ascend`` ``GPU`` ``CPU``
  301. Examples:
  302. >>> net = nn.ClipByNorm()
  303. >>> input = Tensor(np.random.randint(0, 10, [4, 16]), mindspore.float32)
  304. >>> clip_norm = Tensor(np.array([100]).astype(np.float32))
  305. >>> output = net(input, clip_norm)
  306. >>> print(output.shape)
  307. (4, 16)
  308. """
  309. def __init__(self, axis=None):
  310. super(ClipByNorm, self).__init__()
  311. if axis is None:
  312. axis = ()
  313. if isinstance(axis, tuple):
  314. for idx, item in enumerate(axis):
  315. Validator.check_value_type("axis[%d]" % idx, item, [int], self.cls_name)
  316. self.axis = Validator.check_value_type('axis', axis, [int, tuple], self.cls_name)
  317. self.reduce_sum = P.ReduceSum(keep_dims=True)
  318. self.select_ = P.Select()
  319. self.greater_ = P.Greater()
  320. self.cast = P.Cast()
  321. self.sqrt = P.Sqrt()
  322. self.max_op = P.Maximum()
  323. self.shape = P.Shape()
  324. self.reshape = P.Reshape()
  325. self.fill = P.Fill()
  326. self.expand_dims = P.ExpandDims()
  327. self.dtype = P.DType()
  328. def construct(self, x, clip_norm):
  329. mul_x = F.square(x)
  330. l2sum = self.cast(self.reduce_sum(mul_x, self.axis), mstype.float32)
  331. cond = self.greater_(l2sum, 0)
  332. ones_ = self.fill(self.dtype(cond), self.shape(cond), 1.0)
  333. l2sum_safe = self.select_(cond, l2sum, self.cast(ones_, self.dtype(l2sum)))
  334. l2norm = self.select_(cond, self.sqrt(l2sum_safe), l2sum)
  335. _dtype_check(self.dtype(x))
  336. if _is_equal_one(clip_norm):
  337. intermediate = x
  338. else:
  339. intermediate = x * clip_norm
  340. max_norm = self.max_op(l2norm, clip_norm)
  341. if _need_reduce_all(self.axis):
  342. max_norm = self.expand_dims(max_norm, -1)
  343. values_clip = self.cast(intermediate, mstype.float32) / max_norm
  344. values_clip = self.reshape(values_clip, self.shape(x))
  345. values_clip = identity(values_clip)
  346. return values_clip
  347. class Norm(Cell):
  348. r"""
  349. Computes the norm of vectors, currently including Euclidean norm, i.e., :math:`L_2`-norm.
  350. .. math::
  351. norm(x) = \sqrt{\sum_{i=1}^{n} (x_i^2)}
  352. Args:
  353. axis (Union[tuple, int]): The axis over which to compute vector norms. Default: ().
  354. keep_dims (bool): If true, the axis indicated in `axis` are kept with size 1. Otherwise,
  355. the dimensions in `axis` are removed from the output shape. Default: False.
  356. Inputs:
  357. - **input** (Tensor) - Tensor which is not empty.
  358. Outputs:
  359. Tensor, output tensor with dimensions in 'axis' reduced to 1 will be returned if 'keep_dims' is True;
  360. otherwise a Tensor with dimensions in 'axis' removed is returned.
  361. Raises:
  362. TypeError: If `axis` is neither an int nor tuple.
  363. TypeError: If `keep_dims` is not a bool.
  364. Supported Platforms:
  365. ``Ascend`` ``GPU`` ``CPU``
  366. Examples:
  367. >>> net = nn.Norm(axis=0)
  368. >>> input = Tensor(np.array([[4, 4, 9, 1], [2, 1, 3, 6]]), mindspore.float32)
  369. >>> output = net(input)
  370. >>> print(output)
  371. [4.472136 4.1231055 9.486833 6.0827627]
  372. """
  373. def __init__(self, axis=(), keep_dims=False):
  374. super(Norm, self).__init__()
  375. Validator.check_value_type("keep_dims", keep_dims, [bool], self.cls_name)
  376. self.axis = axis
  377. self.keep_dims = keep_dims
  378. self.reduce_sum = P.ReduceSum(True)
  379. self.sqrt = P.Sqrt()
  380. self.squeeze = P.Squeeze(self.axis)
  381. def construct(self, x):
  382. x = self.sqrt(self.reduce_sum(F.square(x), self.axis))
  383. if not self.keep_dims:
  384. x = self.squeeze(x)
  385. return x
  386. def extend_repr(self):
  387. return 'axis={}, keep_dims={}'.format(self.axis, self.keep_dims)
  388. class OneHot(Cell):
  389. """
  390. Returns a one-hot tensor.
  391. The locations represented by indices in argument `indices` take value on_value,
  392. while all other locations take value off_value.
  393. Note:
  394. If the input indices is rank :math:`N`, the output will have rank :math:`N+1`. The new
  395. axis is created at dimension `axis`.
  396. If `indices` is a scalar, the output shape will be a vector of length `depth`.
  397. If `indices` is a vector of length `features`, the output shape will be:
  398. .. code-block::
  399. features * depth if axis == -1
  400. depth * features if axis == 0
  401. If `indices` is a matrix with shape `[batch, features]`, the output shape will be:
  402. .. code-block::
  403. batch * features * depth if axis == -1
  404. batch * depth * features if axis == 1
  405. depth * batch * features if axis == 0
  406. Args:
  407. axis (int): Features x depth if axis is -1, depth x features
  408. if axis is 0. Default: -1.
  409. depth (int): A scalar defining the depth of the one hot dimension. Default: 1.
  410. on_value (float): A scalar defining the value to fill in output[i][j]
  411. when indices[j] = i. Default: 1.0.
  412. off_value (float): A scalar defining the value to fill in output[i][j]
  413. when indices[j] != i. Default: 0.0.
  414. dtype (:class:`mindspore.dtype`): Data type of 'on_value' and 'off_value', not the
  415. data type of indices. Default: mindspore.float32.
  416. Inputs:
  417. - **indices** (Tensor) - A tensor of indices with data type of int32 or int64 and arbitrary shape.
  418. Outputs:
  419. Tensor, the one-hot tensor of data type `dtype` with dimension at `axis` expanded to `depth` and filled with
  420. on_value and off_value.
  421. Raises:
  422. TypeError: If `axis` or `depth` is not an int.
  423. TypeError: If dtype of `indices` is neither int32 nor int64.
  424. ValueError: If `axis` is not in range [-1, len(indices_shape)].
  425. ValueError: If `depth` is less than 0.
  426. Supported Platforms:
  427. ``Ascend`` ``GPU`` ``CPU``
  428. Examples:
  429. >>> net = nn.OneHot(depth=4, axis=1)
  430. >>> indices = Tensor([[1, 3], [0, 2]], dtype=mindspore.int32)
  431. >>> output = net(indices)
  432. >>> print(output)
  433. [[[0. 0.]
  434. [1. 0.]
  435. [0. 0.]
  436. [0. 1.]]
  437. [[1. 0.]
  438. [0. 0.]
  439. [0. 1.]
  440. [0. 0.]]]
  441. """
  442. def __init__(self, axis=-1, depth=1, on_value=1.0, off_value=0.0, dtype=mstype.float32):
  443. super(OneHot, self).__init__()
  444. self.onehot = P.OneHot(axis)
  445. self.depth = depth
  446. self.dtype = dtype
  447. self.on_value = on_value
  448. self.off_value = off_value
  449. def construct(self, indices):
  450. return self.onehot(indices, self.depth, F.cast(self.on_value, self.dtype), F.cast(self.off_value, self.dtype))
  451. class Pad(Cell):
  452. r"""
  453. Pads the input tensor according to the paddings and mode.
  454. Args:
  455. paddings (tuple): The shape of parameter `paddings` is (N, 2). N is the rank of input data. All elements of
  456. paddings are int type. For `D` th dimension of input, paddings[D, 0] indicates how many sizes to be
  457. extended ahead of the `D` th dimension of the input tensor, and paddings[D, 1] indicates how many sizes to
  458. be extended behind of the `D` th dimension of the input tensor. The padded size of each dimension D of the
  459. output is: :math:`paddings[D, 0] + input\_x.dim\_size(D) + paddings[D, 1]`
  460. mode (str): Specifies padding mode. The optional values are "CONSTANT", "REFLECT", "SYMMETRIC".
  461. Default: "CONSTANT".
  462. Inputs:
  463. - **input_x** (Tensor) - The input tensor.
  464. Outputs:
  465. Tensor, the tensor after padding.
  466. - If `mode` is "CONSTANT", it fills the edge with 0, regardless of the values of the `input_x`.
  467. If the `input_x` is [[1,2,3], [4,5,6], [7,8,9]] and `paddings` is [[1,1], [2,2]], then the
  468. 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]].
  469. - If `mode` is "REFLECT", it uses a way of symmetrical copying through the axis of symmetry to fill in.
  470. If the `input_x` is [[1,2,3], [4,5,6], [7,8,9]] and `paddings` is [[1,1], [2,2]], then the
  471. 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]].
  472. - If `mode` is "SYMMETRIC", the filling method is similar to the "REFLECT". It is also copied
  473. according to the symmetry axis, except that it includes the symmetry axis. If the `input_x`
  474. is [[1,2,3], [4,5,6], [7,8,9]] and `paddings` is [[1,1], [2,2]], then the Outputs is
  475. [[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]].
  476. Raises:
  477. TypeError: If `paddings` is not a tuple.
  478. ValueError: If length of `paddings` is more than 4 or its shape is not (n, 2).
  479. ValueError: If `mode` is not one of 'CONSTANT', 'REFLECT', 'SYMMETRIC'.
  480. Supported Platforms:
  481. ``Ascend`` ``GPU`` ``CPU``
  482. Examples:
  483. >>> from mindspore import Tensor
  484. >>> from mindspore.ops import operations as P
  485. >>> import mindspore.nn as nn
  486. >>> import numpy as np
  487. >>> class Net(nn.Cell):
  488. ... def __init__(self):
  489. ... super(Net, self).__init__()
  490. ... self.pad = nn.Pad(paddings=((1, 1), (2, 2)), mode="CONSTANT")
  491. ... def construct(self, x):
  492. ... return self.pad(x)
  493. >>> x = np.array([[0.3, 0.5, 0.2], [0.5, 0.7, 0.3]], dtype=np.float32)
  494. >>> pad = Net()
  495. >>> output = pad(Tensor(x))
  496. >>> print(output)
  497. [[0. 0. 0. 0. 0. 0. 0. ]
  498. [0. 0. 0.3 0.5 0.2 0. 0. ]
  499. [0. 0. 0.5 0.7 0.3 0. 0. ]
  500. [0. 0. 0. 0. 0. 0. 0. ]]
  501. """
  502. def __init__(self, paddings, mode="CONSTANT"):
  503. super(Pad, self).__init__()
  504. self.mode = mode
  505. self.paddings = paddings
  506. Validator.check_string(self.mode, ["CONSTANT", "REFLECT", "SYMMETRIC"], 'mode', self.cls_name)
  507. if not isinstance(paddings, tuple):
  508. raise TypeError('Paddings must be tuple type.')
  509. for item in paddings:
  510. if len(item) != 2:
  511. raise ValueError('The shape of paddings must be (n, 2).')
  512. if len(paddings) > 4:
  513. raise ValueError('Only padding up to 4 dims is supported')
  514. if mode == "CONSTANT":
  515. self.pad = P.Pad(self.paddings)
  516. else:
  517. self.paddings = Tensor(np.array(self.paddings))
  518. self.pad = P.MirrorPad(mode=mode)
  519. def construct(self, x):
  520. if self.mode == "CONSTANT":
  521. x = self.pad(x)
  522. else:
  523. x = self.pad(x, self.paddings)
  524. return x
  525. @constexpr
  526. def bilinear(shape, size, scale, align_corners):
  527. """Check input and calculate shape"""
  528. if not isinstance(align_corners, bool):
  529. raise TypeError("align_corners should be type boolean")
  530. if size is None and scale is None:
  531. raise ValueError("size and scale both none")
  532. if size is not None and scale is not None:
  533. raise ValueError("size and scale both not none")
  534. if size is not None:
  535. if not isinstance(size, (tuple, list)):
  536. raise ValueError("size must be tuple or list")
  537. Validator.check_int(len(size), 2, Rel.EQ, "size", "bilinear")
  538. Validator.check_int(size[0], 1, Rel.GE, "size[0]", "bilinear")
  539. Validator.check_int(size[1], 1, Rel.GE, "size[1]", "bilinear")
  540. return size
  541. Validator.check_int(scale, 1, Rel.GE, "scale factor", "bilinear")
  542. ret = (scale * shape[2], scale * shape[3])
  543. return ret
  544. class ResizeBilinear(Cell):
  545. r"""
  546. Samples the input tensor to the given size or scale_factor by using bilinear interpolate.
  547. Inputs:
  548. - **x** (Tensor) - Tensor to be resized. Input tensor must be a 4-D tensor with shape:
  549. math:`(batch, channels, height, width)`, with data type of float16 or float32.
  550. - **size** (Union[tuple[int], list[int]]): A tuple or list of 2 int elements '(new_height, new_width)',
  551. the new size of the tensor. One and only one of size and scale_factor can be set to None. Default: None.
  552. - **scale_factor** (int): The scale factor of new size of the tensor. The value should be positive integer.
  553. One and only one of size and scale_factor can be set to None. Default: None.
  554. - **align_corners** (bool): If true, rescale input by '(new_height - 1) / (height - 1)', which exactly aligns
  555. the 4 corners of images and resized images. If false, rescale by 'new_height / height'. Default: False.
  556. Outputs:
  557. Resized tensor.
  558. If size is set, the result is 4-D tensor with shape:math:`(batch, channels, new_height, new_width)`
  559. in float32.
  560. If scale is set, the result is 4-D tensor with shape:math:`(batch, channels, scale_factor * height,
  561. scale_factor * width)` in float32
  562. Raises:
  563. TypeError: If `size` is not one of tuple, list, None.
  564. TypeError: If `scale_factor` is neither int nor None.
  565. TypeError: If `align_corners` is not a bool.
  566. TypeError: If dtype of `x` is neither float16 nor float32.
  567. ValueError: If `size` and `scale_factor` are both None or not None.
  568. ValueError: If length of shape of `x` is not equal to 4.
  569. ValueError: If `scale_factor` is an int which is less than 1.
  570. ValueError: If `size` is a list or tuple whose length is not equal to 2.
  571. Supported Platforms:
  572. ``Ascend`` ``CPU``
  573. Examples:
  574. >>> tensor = Tensor([[[[1, 2, 3, 4], [5, 6, 7, 8]]]], mindspore.float32)
  575. >>> resize_bilinear = nn.ResizeBilinear()
  576. >>> result = resize_bilinear(tensor, size=(5,5))
  577. >>> print(result.shape)
  578. (1, 1, 5, 5)
  579. """
  580. def __init__(self):
  581. super(ResizeBilinear, self).__init__()
  582. def construct(self, x, size=None, scale_factor=None, align_corners=False):
  583. shape = bilinear(x.shape, size, scale_factor, align_corners)
  584. resize_bilinear = P.ResizeBilinear(shape, align_corners)
  585. return resize_bilinear(x)
  586. class Unfold(Cell):
  587. r"""
  588. Extracts patches from images.
  589. The input tensor must be a 4-D tensor and the data format is NCHW.
  590. Args:
  591. ksizes (Union[tuple[int], list[int]]): The size of sliding window, must be a tuple or a list of integers,
  592. and the format is [1, ksize_row, ksize_col, 1].
  593. strides (Union[tuple[int], list[int]]): Distance between the centers of the two consecutive patches,
  594. must be a tuple or list of int, and the format is [1, stride_row, stride_col, 1].
  595. rates (Union[tuple[int], list[int]]): In each extracted patch, the gap between the corresponding dimension
  596. pixel positions, must be a tuple or a list of integers, and the format is [1, rate_row, rate_col, 1].
  597. padding (str): The type of padding algorithm, is a string whose value is "same" or "valid", not case sensitive.
  598. Default: "valid".
  599. - same: Means that the patch can take the part beyond the original image, and this part is filled with 0.
  600. - valid: Means that the taken patch area must be completely covered in the original image.
  601. Inputs:
  602. - **input_x** (Tensor) - A 4-D tensor whose shape is [in_batch, in_depth, in_row, in_col] and
  603. data type is number.
  604. Outputs:
  605. Tensor, a 4-D tensor whose data type is same as `input_x`,
  606. and the shape is [out_batch, out_depth, out_row, out_col] where `out_batch` is the same as the `in_batch`.
  607. :math:`out\_depth = ksize\_row * ksize\_col * in\_depth`
  608. :math:`out\_row = (in\_row - (ksize\_row + (ksize\_row - 1) * (rate\_row - 1))) // stride\_row + 1`
  609. :math:`out\_col = (in\_col - (ksize\_col + (ksize\_col - 1) * (rate\_col - 1))) // stride\_col + 1`
  610. Raises:
  611. TypeError: If `ksizes`, `strides` or `rates` is neither a tuple nor list.
  612. ValueError: If shape of `ksizes`, `strides` or `rates` is not (1, x_row, x_col, 1).
  613. ValueError: If the second and third element of `ksizes`, `strides` or `rates` is less than 1.
  614. Supported Platforms:
  615. ``Ascend``
  616. Examples:
  617. >>> net = Unfold(ksizes=[1, 2, 2, 1], strides=[1, 2, 2, 1], rates=[1, 2, 2, 1])
  618. >>> image = Tensor(np.ones([2, 3, 6, 6]), dtype=mstype.float16)
  619. >>> output = net(image)
  620. >>> print(output.shape)
  621. (2, 12, 2, 2)
  622. """
  623. def __init__(self, ksizes, strides, rates, padding="valid"):
  624. super(Unfold, self).__init__()
  625. def _check_tuple_or_list(arg_name, arg_val, prim_name):
  626. Validator.check_value_type(f"{arg_name}s", ksizes, [tuple, list], self.cls_name)
  627. if len(arg_val) != 4 or arg_val[0] != 1 or arg_val[3] != 1:
  628. raise ValueError(f"For \'{prim_name}\' the format of {arg_name}s should be [1, {arg_name}_row, "
  629. f"{arg_name}_col, 1], but got {arg_val}.")
  630. if not isinstance(arg_val[1], int) or not isinstance(arg_val[2], int) or arg_val[1] < 1 or arg_val[2] < 1:
  631. raise ValueError(f"For '{prim_name}' the {arg_name}_row and {arg_name}_col in {arg_name}s should be an "
  632. f"positive integer number, but got {arg_name}_row is {arg_val[1]}, {arg_name}_col "
  633. f"is {arg_val[2]}")
  634. _check_tuple_or_list("ksize", ksizes, self.cls_name)
  635. _check_tuple_or_list("stride", strides, self.cls_name)
  636. _check_tuple_or_list("rate", rates, self.cls_name)
  637. ksizes = ksizes[0], ksizes[3], ksizes[1], ksizes[2]
  638. strides = strides[0], strides[3], strides[1], strides[2]
  639. rates = rates[0], rates[3], rates[1], rates[2]
  640. self.extract_image_patches = inner.ExtractImagePatches(ksizes, strides, rates, padding)
  641. def construct(self, input_x):
  642. result = self.extract_image_patches(input_x)
  643. return result
  644. @constexpr
  645. def tril(x_shape, x_dtype, k):
  646. Validator.check_int(len(x_shape), 1, Rel.GE, "x rank", "tril")
  647. Validator.check_is_int(k, "k value", "tril")
  648. mask = np.tril(np.ones(x_shape), k)
  649. return Tensor(mask, x_dtype)
  650. class Tril(Cell):
  651. """
  652. Returns a tensor with elements above the kth diagonal zeroed.
  653. Inputs:
  654. - **x** (Tensor) - The input tensor.
  655. - **k** (Int) - The index of diagonal. Default: 0
  656. Outputs:
  657. Tensor, has the same type as input `x`.
  658. Raises:
  659. TypeError: If `k` is not an int.
  660. ValueError: If length of shape of `x` is less than 1.
  661. Supported Platforms:
  662. ``Ascend`` ``GPU`` ``CPU``
  663. Examples:
  664. >>> x = Tensor(np.array([[1, 2], [3, 4]]))
  665. >>> tril = nn.Tril()
  666. >>> result = tril(x)
  667. >>> print(result)
  668. [[1 0]
  669. [3 4]]
  670. """
  671. def __init__(self):
  672. super(Tril, self).__init__()
  673. self.dtype = P.DType()
  674. self.mul = P.Mul()
  675. self.cast = P.Cast()
  676. def construct(self, x, k=0):
  677. assist = tril(x.shape, self.dtype(x), k)
  678. result = self.mul(self.cast(x, mstype.float32), self.cast(assist, mstype.float32))
  679. return self.cast(result, self.dtype(x))
  680. @constexpr
  681. def triu(x_shape, x_dtype, k):
  682. Validator.check_int(len(x_shape), 1, Rel.GE, "x rank", "triu")
  683. Validator.check_is_int(k, "k value", "triu")
  684. mask = np.triu(np.ones(x_shape), k)
  685. return Tensor(mask, x_dtype)
  686. class Triu(Cell):
  687. """
  688. Returns a tensor with elements below the kth diagonal zeroed.
  689. Inputs:
  690. - **x** (Tensor) - The input tensor.
  691. - **k** (Int) - The index of diagonal. Default: 0
  692. Outputs:
  693. Tensor, has the same type as input `x`.
  694. Raises:
  695. TypeError: If `k` is not an int.
  696. ValueError: If length of shape of `x` is less than 1.
  697. Supported Platforms:
  698. ``Ascend`` ``GPU`` ``CPU``
  699. Examples:
  700. >>> x = Tensor(np.array([[1, 2], [3, 4]]))
  701. >>> triu = nn.Triu()
  702. >>> result = triu(x)
  703. >>> print(result)
  704. [[1 2]
  705. [0 4]]
  706. """
  707. def __init__(self):
  708. super(Triu, self).__init__()
  709. self.dtype = P.DType()
  710. self.mul = P.Mul()
  711. self.cast = P.Cast()
  712. def construct(self, x, k=0):
  713. assist = triu(x.shape, self.dtype(x), k)
  714. result = self.mul(self.cast(x, mstype.float32), self.cast(assist, mstype.float32))
  715. return self.cast(result, self.dtype(x))
  716. @constexpr
  717. def _get_matrix_diag_assist(x_shape, x_dtype):
  718. Validator.check_int(len(x_shape), 1, Rel.GE, "x rank", "_get_matrix_diag_assist")
  719. base_eye = np.eye(x_shape[-1], x_shape[-1]).reshape(-1)
  720. assist = np.tile(base_eye, x_shape[:-1]).reshape(x_shape + (x_shape[-1],))
  721. return Tensor(assist, x_dtype)
  722. @constexpr
  723. def _get_matrix_diag_part_assist(x_shape, x_dtype):
  724. Validator.check_int(len(x_shape), 2, Rel.GE, "x rank", "_get_matrix_diag_part_assist")
  725. base_eye = np.eye(x_shape[-2], x_shape[-1]).reshape(-1)
  726. assist = np.tile(base_eye, x_shape[:-2]).reshape(x_shape)
  727. return Tensor(assist, x_dtype)
  728. class MatrixDiag(Cell):
  729. r"""
  730. Returns a batched diagonal tensor with a given batched diagonal values.
  731. Assume `x` has :math:`k` dimensions :math:`[I, J, K, ..., N]`, then the output is a tensor of rank
  732. :math:`k+1` with dimensions :math:`[I, J, K, ..., N, N]` where:
  733. :math:`output[i, j, k, ..., m, n] = 1\{m=n\} * x[i, j, k, ..., n]`
  734. Inputs:
  735. - **x** (Tensor) - The diagonal values. It can be one of the following data types:
  736. float32, float16, int32, int8, and uint8.
  737. Outputs:
  738. Tensor, has the same type as input `x`. The shape must be x.shape + (x.shape[-1], ).
  739. Raises:
  740. TypeError: If dtype of `x` is not one of float32, float16, int32, int8 or uint8.
  741. Supported Platforms:
  742. ``Ascend``
  743. Examples:
  744. >>> x = Tensor(np.array([1, -1]), mindspore.float32)
  745. >>> matrix_diag = nn.MatrixDiag()
  746. >>> output = matrix_diag(x)
  747. >>> print(output)
  748. [[ 1. 0.]
  749. [ 0. -1.]]
  750. """
  751. def __init__(self):
  752. super(MatrixDiag, self).__init__()
  753. self.matrix_diag = inner.MatrixDiag()
  754. self.dtype = P.DType()
  755. def construct(self, input_x):
  756. x_shape = F.shape(input_x)
  757. x_dtype = self.dtype(input_x)
  758. assist = _get_matrix_diag_assist(x_shape, x_dtype)
  759. out_matrix_diag = self.matrix_diag(input_x, assist)
  760. return out_matrix_diag
  761. class MatrixDiagPart(Cell):
  762. r"""
  763. Returns the batched diagonal part of a batched tensor.
  764. Assume `x` has :math:`k` dimensions :math:`[I, J, K, ..., M, N]`, then the output is a tensor of rank
  765. :math:`k-1` with dimensions :math:`[I, J, K, ..., min(M, N)]` where:
  766. :math:`output[i, j, k, ..., n] = x[i, j, k, ..., n, n]`
  767. Inputs:
  768. - **x** (Tensor) - The batched tensor. It can be one of the following data types:
  769. float32, float16, int32, int8, and uint8.
  770. Outputs:
  771. Tensor, has the same type as input `x`. The shape must be x.shape[:-2] + [min(x.shape[-2:])].
  772. Raises:
  773. TypeError: If dtype of `x` is not one of float32, float16, int32, int8 or uint8.
  774. Supported Platforms:
  775. ``Ascend``
  776. Examples:
  777. >>> x = Tensor([[[-1, 0], [0, 1]], [[-1, 0], [0, 1]], [[-1, 0], [0, 1]]], mindspore.float32)
  778. >>> matrix_diag_part = nn.MatrixDiagPart()
  779. >>> output = matrix_diag_part(x)
  780. >>> print(output)
  781. [[-1. 1.]
  782. [-1. 1.]
  783. [-1. 1.]]
  784. """
  785. def __init__(self):
  786. super(MatrixDiagPart, self).__init__()
  787. self.matrix_diag_part = inner.MatrixDiagPart()
  788. self.dtype = P.DType()
  789. def construct(self, input_x):
  790. x_shape = F.shape(input_x)
  791. x_dtype = self.dtype(input_x)
  792. assist = _get_matrix_diag_part_assist(x_shape, x_dtype)
  793. out_matrix_diag_part = self.matrix_diag_part(input_x, assist)
  794. return out_matrix_diag_part
  795. class MatrixSetDiag(Cell):
  796. r"""
  797. Modifies the batched diagonal part of a batched tensor.
  798. Assume `x` has :math:`k+1` dimensions :math:`[I, J, K, ..., M, N]` and `diagonal` has :math:`k`
  799. dimensions :math:`[I, J, K, ..., min(M, N)]`. Then the output is a tensor of rank :math:`k+1` with dimensions
  800. :math:`[I, J, K, ..., M, N]` where:
  801. .. math::
  802. output[i, j, k, ..., m, n] = diagnoal[i, j, k, ..., n]\ for\ m == n
  803. .. math::
  804. output[i, j, k, ..., m, n] = x[i, j, k, ..., m, n]\ for\ m != n
  805. Inputs:
  806. - **x** (Tensor) - The batched tensor. Rank k+1, where k >= 1. It can be one of the following data types:
  807. float32, float16, int32, int8, and uint8.
  808. - **diagonal** (Tensor) - The diagonal values. Must have the same type as input `x`. Rank k, where k >= 1.
  809. Outputs:
  810. Tensor, has the same type and shape as input `x`.
  811. Raises:
  812. TypeError: If dtype of `x` or `diagonal` is not one of float32, float16, int32, int8 or uint8.
  813. ValueError: If length of shape of `x` is less than 2.
  814. ValueError: If x_shape[-2] < x_shape[-1] and x_shape[:-1] != diagonal_shape.
  815. ValueError: If x_shape[-2] >= x_shape[-1] and x_shape[:-2] + x_shape[-1:] != diagonal_shape.
  816. Supported Platforms:
  817. ``Ascend``
  818. Examples:
  819. >>> x = Tensor([[[-1, 0], [0, 1]], [[-1, 0], [0, 1]], [[-1, 0], [0, 1]]], mindspore.float32)
  820. >>> diagonal = Tensor([[-1., 2.], [-1., 1.], [-1., 1.]], mindspore.float32)
  821. >>> matrix_set_diag = nn.MatrixSetDiag()
  822. >>> output = matrix_set_diag(x, diagonal)
  823. >>> print(output)
  824. [[[-1. 0.]
  825. [ 0. 2.]]
  826. [[-1. 0.]
  827. [ 0. 1.]]
  828. [[-1. 0.]
  829. [ 0. 1.]]]
  830. """
  831. def __init__(self):
  832. super(MatrixSetDiag, self).__init__()
  833. self.matrix_set_diag = inner.MatrixSetDiag()
  834. self.dtype = P.DType()
  835. def construct(self, input_x, diagonal):
  836. x_shape = F.shape(input_x)
  837. x_dtype = self.dtype(input_x)
  838. assist = _get_matrix_diag_part_assist(x_shape, x_dtype)
  839. out_matrix_set_diag = self.matrix_set_diag(input_x, diagonal, assist)
  840. return out_matrix_set_diag