1# Copyright 2015 The TensorFlow Authors. All Rights Reserved. 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"""Built-in activation functions.""" 16from __future__ import absolute_import 17from __future__ import division 18from __future__ import print_function 19 20import six 21 22from tensorflow.python.keras import backend as K 23from tensorflow.python.keras.utils.generic_utils import deserialize_keras_object 24from tensorflow.python.keras.utils.generic_utils import serialize_keras_object 25from tensorflow.python.ops import math_ops 26from tensorflow.python.ops import nn 27from tensorflow.python.util.tf_export import keras_export 28 29# b/123041942 30# In TF 2.x, if the `tf.nn.softmax` is used as an activation function in Keras 31# layers, it gets serialized as 'softmax_v2' instead of 'softmax' as the 32# internal method name is returned in serialization. This results in errors in 33# model exporting and loading as Keras can't find any activation function with 34# the name of `softmax_v2`. 35 36# This dict maps the activation function name from its v2 version to its 37# canonical name. 38_TF_ACTIVATIONS_V2 = { 39 'softmax_v2': 'softmax', 40} 41 42 43@keras_export('keras.activations.softmax') 44def softmax(x, axis=-1): 45 """Softmax converts a real vector to a vector of categorical probabilities. 46 47 The elements of the output vector are in range (0, 1) and sum to 1. 48 49 Each vector is handled independently. The `axis` argument sets which axis 50 of the input the function is applied along. 51 52 Softmax is often used as the activation for the last 53 layer of a classification network because the result could be interpreted as 54 a probability distribution. 55 56 The softmax of each vector x is calculated by `exp(x)/tf.reduce_sum(exp(x))`. 57 The input values in are the log-odds of the resulting probability. 58 59 Arguments: 60 x : Input tensor. 61 axis: Integer, axis along which the softmax normalization is applied. 62 63 Returns: 64 Tensor, output of softmax transformation (all values are non-negative 65 and sum to 1). 66 67 Raises: 68 ValueError: In case `dim(x) == 1`. 69 """ 70 ndim = K.ndim(x) 71 if ndim == 2: 72 return nn.softmax(x) 73 elif ndim > 2: 74 e = math_ops.exp(x - math_ops.reduce_max(x, axis=axis, keepdims=True)) 75 s = math_ops.reduce_sum(e, axis=axis, keepdims=True) 76 return e / s 77 else: 78 raise ValueError('Cannot apply softmax to a tensor that is 1D. ' 79 'Received input: %s' % (x,)) 80 81 82@keras_export('keras.activations.elu') 83def elu(x, alpha=1.0): 84 """Exponential linear unit. 85 86 Arguments: 87 x: Input tensor. 88 alpha: A scalar, slope of negative section. 89 90 Returns: 91 The exponential linear activation: `x` if `x > 0` and 92 `alpha * (exp(x)-1)` if `x < 0`. 93 94 Reference: 95 - [Fast and Accurate Deep Network Learning by Exponential 96 Linear Units (ELUs)](https://arxiv.org/abs/1511.07289) 97 """ 98 return K.elu(x, alpha) 99 100 101@keras_export('keras.activations.selu') 102def selu(x): 103 """Scaled Exponential Linear Unit (SELU). 104 105 The Scaled Exponential Linear Unit (SELU) activation function is: 106 `scale * x` if `x > 0` and `scale * alpha * (exp(x) - 1)` if `x < 0` 107 where `alpha` and `scale` are pre-defined constants 108 (`alpha = 1.67326324` 109 and `scale = 1.05070098`). 110 The SELU activation function multiplies `scale` > 1 with the 111 `[elu](https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/keras/activations/elu)` 112 (Exponential Linear Unit (ELU)) to ensure a slope larger than one 113 for positive net inputs. 114 115 The values of `alpha` and `scale` are 116 chosen so that the mean and variance of the inputs are preserved 117 between two consecutive layers as long as the weights are initialized 118 correctly (see [`lecun_normal` initialization] 119 (https://www.tensorflow.org/api_docs/python/tf/keras/initializers/lecun_normal)) 120 and the number of inputs is "large enough" 121 (see references for more information). 122 123 ![]https://cdn-images-1.medium.com/max/1600/1*m0e8lZU_Zrkh4ESfQkY2Pw.png 124 (Courtesy: Blog on Towards DataScience at 125 https://towardsdatascience.com/selu-make-fnns-great-again-snn-8d61526802a9) 126 127 Example Usage: 128 129 >>> n_classes = 10 #10-class problem 130 >>> from tensorflow.python.keras.layers import Dense 131 >>> model = tf.keras.Sequential() 132 >>> model.add(Dense(64, kernel_initializer='lecun_normal', 133 ... activation='selu', input_shape=(28, 28, 1))) 134 >>> model.add(Dense(32, kernel_initializer='lecun_normal', 135 ... activation='selu')) 136 >>> model.add(Dense(16, kernel_initializer='lecun_normal', 137 ... activation='selu')) 138 >>> model.add(Dense(n_classes, activation='softmax')) 139 140 Arguments: 141 x: A tensor or variable to compute the activation function for. 142 143 Returns: 144 The scaled exponential unit activation: `scale * elu(x, alpha)`. 145 146 # Note 147 - To be used together with the initialization "[lecun_normal] 148 (https://www.tensorflow.org/api_docs/python/tf/keras/initializers/lecun_normal)". 149 - To be used together with the dropout variant "[AlphaDropout] 150 (https://www.tensorflow.org/api_docs/python/tf/keras/layers/AlphaDropout)". 151 152 References: 153 [Self-Normalizing Neural Networks (Klambauer et al, 2017)] 154 (https://arxiv.org/abs/1706.02515) 155 """ 156 return nn.selu(x) 157 158 159@keras_export('keras.activations.softplus') 160def softplus(x): 161 """Softplus activation function. 162 163 Arguments: 164 x: Input tensor. 165 166 Returns: 167 The softplus activation: `log(exp(x) + 1)`. 168 """ 169 return nn.softplus(x) 170 171 172@keras_export('keras.activations.softsign') 173def softsign(x): 174 """Softsign activation function. 175 176 Arguments: 177 x: Input tensor. 178 179 Returns: 180 The softsign activation: `x / (abs(x) + 1)`. 181 """ 182 return nn.softsign(x) 183 184 185@keras_export('keras.activations.swish') 186def swish(x): 187 """Swish activation function. 188 189 Arguments: 190 x: Input tensor. 191 192 Returns: 193 The swish activation applied to `x`. 194 """ 195 return nn.swish(x) 196 197 198@keras_export('keras.activations.relu') 199def relu(x, alpha=0., max_value=None, threshold=0): 200 """Applies the rectified linear unit activation function. 201 202 With default values, this returns the standard ReLU activation: 203 `max(x, 0)`, the element-wise maximum of 0 and the input tensor. 204 205 Modifying default parameters allows you to use non-zero thresholds, 206 change the max value of the activation, 207 and to use a non-zero multiple of the input for values below the threshold. 208 209 For example: 210 211 >>> foo = tf.constant([-10, -5, 0.0, 5, 10], dtype = tf.float32) 212 >>> tf.keras.activations.relu(foo).numpy() 213 array([ 0., 0., 0., 5., 10.], dtype=float32) 214 >>> tf.keras.activations.relu(foo, alpha=0.5).numpy() 215 array([-5. , -2.5, 0. , 5. , 10. ], dtype=float32) 216 >>> tf.keras.activations.relu(foo, max_value=5).numpy() 217 array([0., 0., 0., 5., 5.], dtype=float32) 218 >>> tf.keras.activations.relu(foo, threshold=5).numpy() 219 array([-0., -0., 0., 0., 10.], dtype=float32) 220 221 Arguments: 222 x: Input `tensor` or `variable`. 223 alpha: A `float` that governs the slope for values lower than the 224 threshold. 225 max_value: A `float` that sets the saturation threshold (the largest value 226 the function will return). 227 threshold: A `float` giving the threshold value of the activation function 228 below which values will be damped or set to zero. 229 230 Returns: 231 A `Tensor` representing the input tensor, 232 transformed by the relu activation function. 233 Tensor will be of the same shape and dtype of input `x`. 234 """ 235 return K.relu(x, alpha=alpha, max_value=max_value, threshold=threshold) 236 237 238@keras_export('keras.activations.tanh') 239def tanh(x): 240 """Hyperbolic tangent activation function. 241 242 For example: 243 244 >>> a = tf.constant([-3.0,-1.0, 0.0,1.0,3.0], dtype = tf.float32) 245 >>> b = tf.keras.activations.tanh(a) 246 >>> b.numpy() 247 array([-0.9950547, -0.7615942, 0. , 0.7615942, 0.9950547], 248 dtype=float32) 249 250 Arguments: 251 x: Input tensor. 252 253 Returns: 254 Tensor of same shape and dtype of input `x`, with tanh activation: 255 `tanh(x) = sinh(x)/cosh(x) = ((exp(x) - exp(-x))/(exp(x) + exp(-x)))`. 256 """ 257 return nn.tanh(x) 258 259 260@keras_export('keras.activations.sigmoid') 261def sigmoid(x): 262 """Sigmoid activation function. 263 264 Applies the sigmoid activation function. The sigmoid function is defined as 265 1 divided by (1 + exp(-x)). It's curve is like an "S" and is like a smoothed 266 version of the Heaviside (Unit Step Function) function. For small values 267 (<-5) the sigmoid returns a value close to zero and for larger values (>5) 268 the result of the function gets close to 1. 269 270 Sigmoid is equivalent to a 2-element Softmax, where the second element is 271 assumed to be zero. 272 273 For example: 274 275 >>> a = tf.constant([-20, -1.0, 0.0, 1.0, 20], dtype = tf.float32) 276 >>> b = tf.keras.activations.sigmoid(a) 277 >>> b.numpy() >= 0.0 278 array([ True, True, True, True, True]) 279 280 Arguments: 281 x: Input tensor. 282 283 Returns: 284 Tensor with the sigmoid activation: `(1.0 / (1.0 + exp(-x)))`. 285 Tensor will be of same shape and dtype of input `x`. 286 """ 287 return nn.sigmoid(x) 288 289 290@keras_export('keras.activations.exponential') 291def exponential(x): 292 """Exponential activation function. 293 294 For example: 295 296 >>> a = tf.constant([-3.0,-1.0, 0.0,1.0,3.0], dtype = tf.float32) 297 >>> b = tf.keras.activations.exponential(a) 298 >>> b.numpy() 299 array([ 0.04978707, 0.36787945, 1. , 2.7182817 , 20.085537 ], 300 dtype=float32) 301 302 Arguments: 303 x: Input tensor. 304 305 Returns: 306 Tensor with exponential activation: `exp(x)`. Tensor will be of same 307 shape and dtype of input `x`. 308 """ 309 return math_ops.exp(x) 310 311 312@keras_export('keras.activations.hard_sigmoid') 313def hard_sigmoid(x): 314 """Hard sigmoid activation function. 315 316 Faster to compute than sigmoid activation. 317 318 For example: 319 320 >>> a = tf.constant([-3.0,-1.0, 0.0,1.0,3.0], dtype = tf.float32) 321 >>> b = tf.keras.activations.hard_sigmoid(a) 322 >>> b.numpy() 323 array([0. , 0.3, 0.5, 0.7, 1. ], dtype=float32) 324 325 Arguments: 326 x: Input tensor. 327 328 Returns: 329 The hard sigmoid activation: 330 331 - `0` if `x < -2.5` 332 - `1` if `x > 2.5` 333 - `0.2 * x + 0.5` if `-2.5 <= x <= 2.5`. 334 """ 335 return K.hard_sigmoid(x) 336 337 338@keras_export('keras.activations.linear') 339def linear(x): 340 """Linear activation function. 341 342 For example: 343 344 >>> a = tf.constant([-3.0,-1.0, 0.0,1.0,3.0], dtype = tf.float32) 345 >>> b = tf.keras.activations.linear(a) 346 >>> b.numpy() 347 array([-3., -1., 0., 1., 3.], dtype=float32) 348 349 Arguments: 350 x: Input tensor. 351 352 Returns: 353 the input unmodified. 354 """ 355 return x 356 357 358@keras_export('keras.activations.serialize') 359def serialize(activation): 360 """Returns name attribute (`__name__`) of function. 361 362 Arguments: 363 activation : Function 364 365 Returns: 366 String denoting the name attribute of the input function 367 368 For example: 369 370 >>> tf.keras.activations.serialize(tf.keras.activations.tanh) 371 'tanh' 372 >>> tf.keras.activations.serialize(tf.keras.activations.sigmoid) 373 'sigmoid' 374 >>> tf.keras.activations.serialize('abcd') 375 Traceback (most recent call last): 376 ... 377 ValueError: ('Cannot serialize', 'abcd') 378 379 Raises: 380 ValueError: The input function is not a valid one. 381 """ 382 if (hasattr(activation, '__name__') and 383 activation.__name__ in _TF_ACTIVATIONS_V2): 384 return _TF_ACTIVATIONS_V2[activation.__name__] 385 return serialize_keras_object(activation) 386 387 388@keras_export('keras.activations.deserialize') 389def deserialize(name, custom_objects=None): 390 """Returns activation function denoted by input string. 391 392 Arguments: 393 x : String 394 395 Returns: 396 TensorFlow Activation function denoted by input string. 397 398 For example: 399 400 >>> tf.keras.activations.deserialize('linear') 401 <function linear at 0x1239596a8> 402 >>> tf.keras.activations.deserialize('sigmoid') 403 <function sigmoid at 0x123959510> 404 >>> tf.keras.activations.deserialize('abcd') 405 Traceback (most recent call last): 406 ... 407 ValueError: Unknown activation function:abcd 408 409 Args: 410 name: The name of the activation function. 411 custom_objects: A {name:value} dictionary for activations not build into 412 keras. 413 414 Raises: 415 ValueError: `Unknown activation function` if the input string does not 416 denote any defined Tensorflow activation function. 417 """ 418 return deserialize_keras_object( 419 name, 420 module_objects=globals(), 421 custom_objects=custom_objects, 422 printable_module_name='activation function') 423 424 425@keras_export('keras.activations.get') 426def get(identifier): 427 """Returns function. 428 429 Arguments: 430 identifier: Function or string 431 432 Returns: 433 Activation function denoted by input: 434 - `Linear activation function` if input is `None`. 435 - Function corresponding to the input string or input function. 436 437 For example: 438 439 >>> tf.keras.activations.get('softmax') 440 <function softmax at 0x1222a3d90> 441 >>> tf.keras.activations.get(tf.keras.activations.softmax) 442 <function softmax at 0x1222a3d90> 443 >>> tf.keras.activations.get(None) 444 <function linear at 0x1239596a8> 445 >>> tf.keras.activations.get(abs) 446 <built-in function abs> 447 >>> tf.keras.activations.get('abcd') 448 Traceback (most recent call last): 449 ... 450 ValueError: Unknown activation function:abcd 451 452 Raises: 453 ValueError: Input is an unknown function or string, i.e., the input does 454 not denote any defined function. 455 """ 456 if identifier is None: 457 return linear 458 if isinstance(identifier, six.string_types): 459 identifier = str(identifier) 460 return deserialize(identifier) 461 elif callable(identifier): 462 return identifier 463 elif isinstance(identifier, dict): 464 return deserialize_keras_object( 465 identifier, printable_module_name='activation') 466 else: 467 raise TypeError( 468 'Could not interpret activation function identifier: {}'.format( 469 repr(identifier))) 470