Source code for deepctr.layers.activation

# -*- coding:utf-8 -*-
"""

Author:
    Weichen Shen,weichenswc@163.com

"""

import tensorflow as tf

try:
    from tensorflow.python.ops.init_ops import Zeros
except ImportError:
    from tensorflow.python.ops.init_ops_v2 import Zeros
from tensorflow.python.keras.layers import Layer, Activation

try:
    from tensorflow.python.keras.layers import BatchNormalization
except ImportError:
    BatchNormalization = tf.keras.layers.BatchNormalization

try:
    unicode
except NameError:
    unicode = str


[docs]class Dice(Layer): """The Data Adaptive Activation Function in DIN,which can be viewed as a generalization of PReLu and can adaptively adjust the rectified point according to distribution of input data. Input shape - Arbitrary. Use the keyword argument `input_shape` (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model. Output shape - Same shape as the input. Arguments - **axis** : Integer, the axis that should be used to compute data distribution (typically the features axis). - **epsilon** : Small float added to variance to avoid dividing by zero. References - [Zhou G, Zhu X, Song C, et al. Deep interest network for click-through rate prediction[C]//Proceedings of the 24th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining. ACM, 2018: 1059-1068.](https://arxiv.org/pdf/1706.06978.pdf) """ def __init__(self, axis=-1, epsilon=1e-9, **kwargs): self.axis = axis self.epsilon = epsilon super(Dice, self).__init__(**kwargs)
[docs] def build(self, input_shape): self.bn = BatchNormalization( axis=self.axis, epsilon=self.epsilon, center=False, scale=False) self.alphas = self.add_weight(shape=(input_shape[-1],), initializer=Zeros( ), dtype=tf.float32, name='dice_alpha') # name='alpha_'+self.name super(Dice, self).build(input_shape) # Be sure to call this somewhere! self.uses_learning_phase = True
[docs] def call(self, inputs, training=None, **kwargs): inputs_normed = self.bn(inputs, training=training) # tf.layers.batch_normalization( # inputs, axis=self.axis, epsilon=self.epsilon, center=False, scale=False) x_p = tf.sigmoid(inputs_normed) return self.alphas * (1.0 - x_p) * inputs + x_p * inputs
[docs] def compute_output_shape(self, input_shape): return input_shape
[docs] def get_config(self, ): config = {'axis': self.axis, 'epsilon': self.epsilon} base_config = super(Dice, self).get_config() return dict(list(base_config.items()) + list(config.items()))
def activation_layer(activation): if activation in ("dice", "Dice"): act_layer = Dice() elif isinstance(activation, (str, unicode)): act_layer = Activation(activation) elif issubclass(activation, Layer): act_layer = activation() else: raise ValueError( "Invalid activation,found %s.You should use a str or a Activation Layer Class." % (activation)) return act_layer