Skip to content
This repository has been archived by the owner on Nov 3, 2022. It is now read-only.

Added Inverse Square Root Linear Unit (ISRLU) activation layer #455

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ keras_contrib/callbacks/snapshot.py @titu1994


# layers
keras_contrib/layers/advanced_activations/isrlu.py @SriRangaTarun
keras_contrib/layers/advanced_activations/sinerelu.py @wilderrodrigues
keras_contrib/layers/advanced_activations/swish.py @gabrieldemarmiesse
keras_contrib/layers/convolutional/subpixelupscaling.py @titu1994
Expand Down
1 change: 1 addition & 0 deletions keras_contrib/layers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import absolute_import

from .advanced_activations.isrlu import ISRLU
from .advanced_activations.pelu import PELU
from .advanced_activations.srelu import SReLU
from .advanced_activations.swish import Swish
Expand Down
71 changes: 71 additions & 0 deletions keras_contrib/layers/advanced_activations/isrlu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# -*- coding: utf-8 -*-
from keras import backend as K
from keras.layers import Layer


class ISRLU(Layer):
"""Inverse Square Root Linear Unit
See: https://arxiv.org/pdf/1710.09967.pdf by AI Perf
Reference: https://en.wikipedia.org/wiki/Activation_function
Inverse Square Root Linear activation f(α, x):
x >= 0: x
x < 0: x / sqrt(1 + α * x^2)
# 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
alpha: Value of the alpha weights (float)
NOTE : This function can become unstable for
negative values of α (it may return
NaNs). In particular, this happens when
α < 0 and x < -1/sqrt(α) or x > 1/sqrt(α).
If this happens, try limiting the magnitude
of α below a certain threshold, such that
1 + α * x^2 is always positive.
Alternatively, you can normalize the inputs
into fixed ranges before passing them to ISRLU.
Adjust the value of α based on your specific
dataset and use-case.
# Example
model = Sequential()
model.add(Dense(5, input_shape=(15,))
model.add(ISRLU(alpha=-0.3))
"""
def __init__(self,
alpha=0.1,
**kwargs):

super(ISRLU, self).__init__(**kwargs)
self.alpha = alpha

def alpha_initializer(self, input_shape):
return self.alpha * K.ones(input_shape)

def build(self, input_shape):
new_input_shape = input_shape[1:]
self.alphas = self.add_weight(shape=new_input_shape,
name='{}_alphas'.format(self.name),
initializer=self.alpha_initializer,
trainable=False)
self.build = True

def call(self, x):
def inverse_square(x):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name inverse_square might not be appropriate as the function does not exactly return 1/x^2

return x / K.sqrt(1 + self.alphas * K.square(x))

def identity(x):
return x

return K.switch(K.less(x, K.zeros_like(x)), inverse_square(x), identity(x))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why introducing the identity function and not just pass x as argument


def compute_output_shape(self, input_shape):
return input_shape

def get_config(self):
config = {'alpha': self.alpha}
base_config = super(ISRLU, self).get_config()
base_config['trainable'] = False
return dict(list(base_config.items()) + list(config.items()))
15 changes: 15 additions & 0 deletions tests/keras_contrib/layers/advanced_activations/test_isrlu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
import pytest
from keras_contrib.utils.test_utils import layer_test
from keras_contrib.layers import ISRLU


@pytest.mark.parametrize('alpha', [0.2, 0.3, -0.01])
def test_isrlu(alpha):
layer_test(ISRLU,
kwargs={'alpha': alpha},
input_shape=(2, 3, 4))


if __name__ == '__main__':
pytest.main([__file__])