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.

activation.py 16 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  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. """activation"""
  16. import numpy as np
  17. from mindspore.ops import operations as P
  18. from mindspore.ops import functional as F
  19. from mindspore.ops import _selected_ops
  20. from mindspore.common.parameter import Parameter
  21. from mindspore.common.initializer import initializer
  22. from mindspore.common.tensor import Tensor
  23. from mindspore._extends import cell_attr_register
  24. from mindspore._checkparam import Validator as validator
  25. from ..cell import Cell
  26. __all__ = ['Softmax',
  27. 'LogSoftmax',
  28. 'ReLU',
  29. 'ReLU6',
  30. 'Tanh',
  31. 'GELU',
  32. 'Sigmoid',
  33. 'PReLU',
  34. 'get_activation',
  35. 'LeakyReLU',
  36. 'HSigmoid',
  37. 'HSwish',
  38. 'ELU',
  39. 'LogSigmoid',
  40. ]
  41. class Softmax(Cell):
  42. r"""
  43. Softmax activation function.
  44. Applies the Softmax function to an n-dimensional input Tensor.
  45. The input is a Tensor of logits transformed with exponential function and then
  46. normalized to lie in range [0, 1] and sum up to 1.
  47. Softmax is defined as:
  48. .. math::
  49. \text{softmax}(x_{i}) = \frac{\exp(x_i)}{\sum_{j=0}^{n-1}\exp(x_j)},
  50. where :math:`x_{i}` is the :math:`i`-th slice in the given dimension of the input Tensor.
  51. Args:
  52. axis (Union[int, tuple[int]]): The axis to apply Softmax operation, -1 means the last dimension. Default: -1.
  53. Inputs:
  54. - **x** (Tensor) - The input of Softmax.
  55. Outputs:
  56. Tensor, which has the same type and shape as `x` with values in the range[0,1].
  57. Examples:
  58. >>> input_x = Tensor(np.array([-1, -2, 0, 2, 1]), mindspore.float16)
  59. >>> softmax = nn.Softmax()
  60. >>> softmax(input_x)
  61. [0.03168 0.01166 0.0861 0.636 0.2341]
  62. """
  63. def __init__(self, axis=-1):
  64. super(Softmax, self).__init__()
  65. self.softmax = _selected_ops.Softmax(axis)
  66. def construct(self, x):
  67. return self.softmax(x)
  68. class LogSoftmax(Cell):
  69. r"""
  70. LogSoftmax activation function.
  71. Applies the LogSoftmax function to n-dimensional input tensor.
  72. The input is transformed by the Softmax function and then by the log function to lie in range[-inf,0).
  73. Logsoftmax is defined as:
  74. :math:`\text{logsoftmax}(x_i) = \log \left(\frac{\exp(x_i)}{\sum_{j=0}^{n-1} \exp(x_j)}\right)`,
  75. where :math:`x_{i}` is the :math:`i`-th slice in the given dimension of the input Tensor.
  76. Args:
  77. axis (int): The axis to apply LogSoftmax operation, -1 means the last dimension. Default: -1.
  78. Inputs:
  79. - **x** (Tensor) - The input of LogSoftmax.
  80. Outputs:
  81. Tensor, which has the same type and shape as the input as `x` with values in the range[-inf,0).
  82. Examples:
  83. >>> input_x = Tensor(np.array([[-1.0, 4.0, -8.0], [2.0, -5.0, 9.0]]), mindspore.float32)
  84. >>> log_softmax = nn.LogSoftmax()
  85. >>> log_softmax(input_x)
  86. [[-5.00672150e+00 -6.72150636e-03 -1.20067215e+01]
  87. [-7.00091219e+00 -1.40009127e+01 -9.12250078e-04]]
  88. """
  89. def __init__(self, axis=-1):
  90. super(LogSoftmax, self).__init__()
  91. self.log_softmax = _selected_ops.LogSoftmax(axis)
  92. def construct(self, x):
  93. return self.log_softmax(x)
  94. class ELU(Cell):
  95. r"""
  96. Exponential Linear Uint activation function.
  97. Applies the exponential linear unit function element-wise.
  98. The activation function is defined as:
  99. .. math::
  100. E_{i} =
  101. \begin{cases}
  102. x, &\text{if } x \geq 0; \cr
  103. \text{alpha} * (\exp(x_i) - 1), &\text{otherwise.}
  104. \end{cases}
  105. Args:
  106. alpha (float): The coefficient of negative factor whose type is float. Default: 1.0.
  107. Inputs:
  108. - **input_data** (Tensor) - The input of ELU.
  109. Outputs:
  110. Tensor, with the same type and shape as the `input_data`.
  111. Examples:
  112. >>> input_x = Tensor(np.array([-1, -2, 0, 2, 1]), mindspore.float32)
  113. >>> elu = nn.ELU()
  114. >>> elu(input_x)
  115. """
  116. def __init__(self, alpha=1.0):
  117. super(ELU, self).__init__()
  118. self.elu = P.Elu(alpha)
  119. def construct(self, x):
  120. return self.elu(x)
  121. class ReLU(Cell):
  122. r"""
  123. Rectified Linear Unit activation function.
  124. Applies the rectified linear unit function element-wise. It returns
  125. element-wise :math:`\max(0, x)`, specially, the neurons with the negative output
  126. will be suppressed and the active neurons will stay the same.
  127. Inputs:
  128. - **input_data** (Tensor) - The input of ReLU.
  129. Outputs:
  130. Tensor, with the same type and shape as the `input_data`.
  131. Examples:
  132. >>> input_x = Tensor(np.array([-1, 2, -3, 2, -1]), mindspore.float16)
  133. >>> relu = nn.ReLU()
  134. >>> relu(input_x)
  135. [0. 2. 0. 2. 0.]
  136. """
  137. def __init__(self):
  138. super(ReLU, self).__init__()
  139. self.relu = P.ReLU()
  140. def construct(self, x):
  141. return self.relu(x)
  142. class ReLU6(Cell):
  143. r"""
  144. Compute ReLU6 activation function.
  145. ReLU6 is similar to ReLU with a upper limit of 6, which if the inputs are greater than 6, the outputs
  146. will be suppressed to 6.
  147. It computes element-wise as :math:`\min(\max(0, x), 6)`. The input is a Tensor of any valid shape.
  148. Inputs:
  149. - **input_data** (Tensor) - The input of ReLU6.
  150. Outputs:
  151. Tensor, which has the same type as `input_data`.
  152. Examples:
  153. >>> input_x = Tensor(np.array([-1, -2, 0, 2, 1]), mindspore.float16)
  154. >>> relu6 = nn.ReLU6()
  155. >>> relu6(input_x)
  156. [0. 0. 0. 2. 1.]
  157. """
  158. def __init__(self):
  159. super(ReLU6, self).__init__()
  160. self.relu6 = P.ReLU6()
  161. def construct(self, x):
  162. return self.relu6(x)
  163. class LeakyReLU(Cell):
  164. r"""
  165. Leaky ReLU activation function.
  166. LeakyReLU is similar to ReLU, but LeakyReLU has a slope that makes it not equal to 0 at x < 0.
  167. The activation function is defined as:
  168. .. math::
  169. \text{leaky_relu}(x) = \begin{cases}x, &\text{if } x \geq 0; \cr
  170. \text{alpha} * x, &\text{otherwise.}\end{cases}
  171. See https://ai.stanford.edu/~amaas/papers/relu_hybrid_icml2013_final.pdf
  172. Args:
  173. alpha (Union[int, float]): Slope of the activation function at x < 0. Default: 0.2.
  174. Inputs:
  175. - **input_x** (Tensor) - The input of LeakyReLU.
  176. Outputs:
  177. Tensor, has the same type and shape as the `input_x`.
  178. Examples:
  179. >>> input_x = Tensor(np.array([[-1.0, 4.0, -8.0], [2.0, -5.0, 9.0]]), mindspore.float32)
  180. >>> leaky_relu = nn.LeakyReLU()
  181. >>> leaky_relu(input_x)
  182. [[-0.2 4. -1.6]
  183. [ 2 -1. 9.]]
  184. """
  185. def __init__(self, alpha=0.2):
  186. super(LeakyReLU, self).__init__()
  187. validator.check_value_type('alpha', alpha, [float, int], self.cls_name)
  188. self.greater_equal = P.GreaterEqual()
  189. self.mul = P.Mul()
  190. self.alpha = alpha
  191. def construct(self, x):
  192. alpha_array = P.Cast()(F.scalar_to_array(self.alpha), P.DType()(x))
  193. if self.alpha <= 1:
  194. out = P.Maximum()(alpha_array * x, x)
  195. else:
  196. out = P.Minimum()(alpha_array * x, x)
  197. return out
  198. class Tanh(Cell):
  199. r"""
  200. Tanh activation function.
  201. Applies the Tanh function element-wise, returns a new tensor with the hyperbolic tangent of the elements of input,
  202. The input is a Tensor with any valid shape.
  203. Tanh function is defined as:
  204. .. math::
  205. tanh(x_i) = \frac{\exp(x_i) - \exp(-x_i)}{\exp(x_i) + \exp(-x_i)} = \frac{\exp(2x_i) - 1}{\exp(2x_i) + 1},
  206. where :math:`x_i` is an element of the input Tensor.
  207. Inputs:
  208. - **input_data** (Tensor) - The input of Tanh.
  209. Outputs:
  210. Tensor, with the same type and shape as the `input_data`.
  211. Examples:
  212. >>> input_x = Tensor(np.array([1, 2, 3, 2, 1]), mindspore.float16)
  213. >>> tanh = nn.Tanh()
  214. >>> tanh(input_x)
  215. [0.7617 0.964 0.995 0.964 0.7617]
  216. """
  217. def __init__(self):
  218. super(Tanh, self).__init__()
  219. self.tanh = _selected_ops.Tanh()
  220. def construct(self, x):
  221. return self.tanh(x)
  222. class GELU(Cell):
  223. r"""
  224. Gaussian error linear unit activation function.
  225. Applies GELU function to each element of the input. The input is a Tensor with any valid shape.
  226. GELU is defined as:
  227. :math:`GELU(x_i) = x_i*P(X < x_i)`, where :math:`P` is the cumulative distribution function
  228. of standard Gaussian distribution and :math:`x_i` is the element of the input.
  229. Inputs:
  230. - **input_data** (Tensor) - The input of GELU.
  231. Outputs:
  232. Tensor, with the same type and shape as the `input_data`.
  233. Examples:
  234. >>> input_x = Tensor(np.array([[-1.0, 4.0, -8.0], [2.0, -5.0, 9.0]]), mindspore.float32)
  235. >>> gelu = nn.GELU()
  236. >>> gelu(input_x)
  237. [[-1.5880802e-01 3.9999299e+00 -3.1077917e-21]
  238. [ 1.9545976e+00 -2.2918017e-07 9.0000000e+00]]
  239. """
  240. def __init__(self):
  241. super(GELU, self).__init__()
  242. self.gelu = _selected_ops.Gelu()
  243. def construct(self, x):
  244. return self.gelu(x)
  245. class Sigmoid(Cell):
  246. r"""
  247. Sigmoid activation function.
  248. Applies sigmoid-type activation element-wise.
  249. Sigmoid function is defined as:
  250. :math:`\text{sigmoid}(x_i) = \frac{1}{1 + \exp(-x_i)}`, where :math:`x_i` is the element of the input.
  251. Inputs:
  252. - **input_data** (Tensor) - The input of Tanh.
  253. Outputs:
  254. Tensor, with the same type and shape as the `input_data`.
  255. Examples:
  256. >>> input_x = Tensor(np.array([-1, -2, 0, 2, 1]), mindspore.float16)
  257. >>> sigmoid = nn.Sigmoid()
  258. >>> sigmoid(input_x)
  259. [0.2688 0.11914 0.5 0.881 0.7305]
  260. """
  261. def __init__(self):
  262. super(Sigmoid, self).__init__()
  263. self.sigmoid = P.Sigmoid()
  264. def construct(self, x):
  265. return self.sigmoid(x)
  266. class PReLU(Cell):
  267. r"""
  268. PReLU activation function.
  269. Applies the PReLU function element-wise.
  270. PReLU is defined as: :math:`prelu(x_i)= \max(0, x_i) + w * \min(0, x_i)`, where :math:`x_i`
  271. is an element of an channel of the input.
  272. Here :math:`w` is a learnable parameter with a default initial value 0.25.
  273. Parameter :math:`w` has dimensionality of the argument channel. If called without argument
  274. channel, a single parameter :math:`w` will be shared across all channels.
  275. Args:
  276. channel (int): The dimension of input. Default: 1.
  277. w (float): The initial value of w. Default: 0.25.
  278. Inputs:
  279. - **input_data** (Tensor) - The input of PReLU.
  280. Outputs:
  281. Tensor, with the same type and shape as the `input_data`.
  282. Examples:
  283. >>> input_x = Tensor(np.array([[[[0.1, 0.6], [0.9, 0.9]]]]), mindspore.float32)
  284. >>> prelu = nn.PReLU()
  285. >>> prelu(input_x)
  286. [[[[0.1 0.6]
  287. [0.9 0.9]]]]
  288. """
  289. @cell_attr_register(attrs="")
  290. def __init__(self, channel=1, w=0.25):
  291. super(PReLU, self).__init__()
  292. if isinstance(w, (np.float32, float)):
  293. tmp = np.empty((channel,), dtype=np.float32)
  294. tmp.fill(w)
  295. w = Tensor(tmp)
  296. elif isinstance(w, list):
  297. w = Tensor(w)
  298. if not isinstance(w, Tensor):
  299. raise TypeError("w only support np.float32, float or Tensor type.")
  300. self.w = Parameter(initializer(w, [channel]), name='a')
  301. self.prelu = P.PReLU()
  302. self.relu = P.ReLU()
  303. self.assign = P.Assign()
  304. def construct(self, x):
  305. u = self.relu(self.w)
  306. v = self.prelu(x, u)
  307. if self.training:
  308. self.assign(self.w, u)
  309. return v
  310. class HSwish(Cell):
  311. r"""
  312. Hard swish activation function.
  313. Applies hswish-type activation element-wise. The input is a Tensor with any valid shape.
  314. Hard swish is defined as:
  315. .. math::
  316. \text{hswish}(x_{i}) = x_{i} * \frac{ReLU6(x_{i} + 3)}{6},
  317. where :math:`x_{i}` is the :math:`i`-th slice in the given dimension of the input Tensor.
  318. Inputs:
  319. - **input_data** (Tensor) - The input of HSwish.
  320. Outputs:
  321. Tensor, with the same type and shape as the `input_data`.
  322. Examples:
  323. >>> input_x = Tensor(np.array([-1, -2, 0, 2, 1]), mindspore.float16)
  324. >>> hswish = nn.HSwish()
  325. >>> hswish(input_x)
  326. """
  327. def __init__(self):
  328. super(HSwish, self).__init__()
  329. self.hswish = P.HSwish()
  330. def construct(self, x):
  331. return self.hswish(x)
  332. class HSigmoid(Cell):
  333. r"""
  334. Hard sigmoid activation function.
  335. Applies hard sigmoid activation element-wise. The input is a Tensor with any valid shape.
  336. Hard sigmoid is defined as:
  337. .. math::
  338. \text{hsigmoid}(x_{i}) = max(0, min(1, \frac{x_{i} + 3}{6})),
  339. where :math:`x_{i}` is the :math:`i`-th slice in the given dimension of the input Tensor.
  340. Inputs:
  341. - **input_data** (Tensor) - The input of HSigmoid.
  342. Outputs:
  343. Tensor, with the same type and shape as the `input_data`.
  344. Examples:
  345. >>> input_x = Tensor(np.array([-1, -2, 0, 2, 1]), mindspore.float16)
  346. >>> hsigmoid = nn.HSigmoid()
  347. >>> hsigmoid(input_x)
  348. """
  349. def __init__(self):
  350. super(HSigmoid, self).__init__()
  351. self.hsigmoid = P.HSigmoid()
  352. def construct(self, x):
  353. return self.hsigmoid(x)
  354. class LogSigmoid(Cell):
  355. r"""
  356. Logsigmoid activation function.
  357. Applies logsigmoid activation element-wise. The input is a Tensor with any valid shape.
  358. Logsigmoid is defined as:
  359. .. math::
  360. \text{logsigmoid}(x_{i}) = log(\frac{1}{1 + \exp(-x_i)}),
  361. where :math:`x_{i}` is the element of the input.
  362. Inputs:
  363. - **input_data** (Tensor) - The input of LogSigmoid.
  364. Outputs:
  365. Tensor, with the same type and shape as the `input_data`.
  366. Examples:
  367. >>> net = nn.LogSigmoid()
  368. >>> input_x = Tensor(np.array([1.0, 2.0, 3.0]), mindspore.float32)
  369. >>> logsigmoid = net(input_x)
  370. [-3.1326166e-01, -1.2692806e-01, -4.8587345e-02]
  371. """
  372. def __init__(self):
  373. super(LogSigmoid, self).__init__()
  374. self.mul = P.Mul()
  375. self.exp = P.Exp()
  376. self.add = P.TensorAdd()
  377. self.rec = P.Reciprocal()
  378. self.log = P.Log()
  379. def construct(self, input_x):
  380. neg_input = self.mul(input_x, -1)
  381. exp_neg_input = self.exp(neg_input)
  382. exp_neg_input_1 = self.add(exp_neg_input, 1)
  383. rec_exp_neg_input_1 = self.rec(exp_neg_input_1)
  384. ret = self.log(rec_exp_neg_input_1)
  385. return ret
  386. _activation = {
  387. 'softmax': Softmax,
  388. 'logsoftmax': LogSoftmax,
  389. 'relu': ReLU,
  390. 'relu6': ReLU6,
  391. 'tanh': Tanh,
  392. 'gelu': GELU,
  393. 'elu': ELU,
  394. 'sigmoid': Sigmoid,
  395. 'prelu': PReLU,
  396. 'leakyrelu': LeakyReLU,
  397. 'hswish': HSwish,
  398. 'hsigmoid': HSigmoid,
  399. 'logsigmoid': LogSigmoid,
  400. }
  401. def get_activation(name):
  402. """
  403. Gets the activation function.
  404. Args:
  405. name (str): The name of the activation function.
  406. Returns:
  407. Function, the activation function.
  408. Examples:
  409. >>> sigmoid = nn.get_activation('sigmoid')
  410. """
  411. if name is None:
  412. return None
  413. if name not in _activation:
  414. raise KeyError(f"Unknown activation type '{name}'")
  415. return _activation[name]()