Skip to content

Commit dea9d40

Browse files
author
Jonathan DEKHTIAR
authored
Work on Special Activations Functions (#690)
* work on special activations * Special activation functions fixed * Changelog modified
1 parent 66f8d43 commit dea9d40

File tree

5 files changed

+148
-41
lines changed

5 files changed

+148
-41
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ To release a new version, please update the changelog as followed:
179179
- `tl.alphas` and `tl.alphas_like` added following the tf.ones/zeros and tf.zeros_like/ones_like (by @DEKHTIARJonathan in #580)
180180
- `tl.lazy_imports.LazyImport` to import heavy libraries only when necessary (by @DEKHTIARJonathan in #667)
181181
- `tl.act.leaky_relu6` and `tl.layers.PRelu6Layer` have been (by @DEKHTIARJonathan in #686)
182+
- `tl.act.leaky_twice_relu6` and `tl.layers.PTRelu6Layer` have been (by @DEKHTIARJonathan in #690)
182183
- CI Tool:
183184
- [Stale Probot](https://github.com/probot/stale) added to clean stale issues (by @DEKHTIARJonathan in #573)
184185
- [Changelog Probot](https://github.com/mikz/probot-changelog) Configuration added (by @DEKHTIARJonathan in #637)
@@ -242,6 +243,7 @@ To release a new version, please update the changelog as followed:
242243
- Convolution Layers have been refactored under the folder `tensorlayer/layers/convolution` (by @DEKHTIARJonathan in #692)
243244
- Dense Layers have been refactored under the folder `tensorlayer/layers/dense` (by @DEKHTIARJonathan in #692)
244245
- Numerous Layer utility functions have been refactored in the file `tensorlayer/layers/utils.py` (by @DEKHTIARJonathan in #692)
246+
- `tests\test_layers_special_activation.py` made more robust for `PReluLayer`, `PRelu6Layer`, and `PTRelu6Layer` (by @DEKHTIARJonathan in #690)
245247

246248
### Deprecated
247249
- `tl.layers.TimeDistributedLayer` argurment `args` is deprecated in favor of `layer_args` (by @DEKHTIARJonathan in #667)

tensorlayer/activation.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def leaky_relu6(x, alpha=0.2, name="leaky_relu6"):
127127
- `Convolutional Deep Belief Networks on CIFAR-10 [A. Krizhevsky, 2010] <http://www.cs.utoronto.ca/~kriz/conv-cifar10-aug2010.pdf>`__
128128
"""
129129

130-
if not (0 < alpha <= 1):
130+
if not isinstance(alpha, tf.Tensor) and not (0 < alpha <= 1):
131131
raise ValueError("`alpha` value must be in [0, 1]`")
132132

133133
with tf.name_scope(name, "leaky_relu6") as name_scope:
@@ -179,10 +179,10 @@ def leaky_twice_relu6(x, alpha_low=0.2, alpha_high=0.2, name="leaky_relu6"):
179179
180180
"""
181181

182-
if not (0 < alpha_high <= 1):
182+
if not isinstance(alpha_high, tf.Tensor) and not (0 < alpha_high <= 1):
183183
raise ValueError("`alpha_high` value must be in [0, 1]`")
184184

185-
if not (0 < alpha_low <= 1):
185+
if not isinstance(alpha_low, tf.Tensor) and not (0 < alpha_low <= 1):
186186
raise ValueError("`alpha_low` value must be in [0, 1]`")
187187

188188
with tf.name_scope(name, "leaky_twice_relu6") as name_scope:

tensorlayer/layers/core.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,10 @@ def _add_dropout_layers(self, drop_layers):
281281
raise ValueError()
282282

283283
@private_method
284-
def _apply_activation(self, logits):
285-
return self.act(logits) if self.act is not None else logits
284+
def _apply_activation(self, logits, **kwargs):
285+
if not kwargs:
286+
kwargs = {}
287+
return self.act(logits, **kwargs) if self.act is not None else logits
286288

287289
@private_method
288290
def _argument_dict_checkup(self, args):

tensorlayer/layers/special_activation.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ def __init__(
5050
a_init_args=None, name="PReluLayer"
5151
):
5252

53-
super(PReluLayer, self).__init__(prev_layer=prev_layer, a_init_args=a_init_args, name=name)
53+
super(PReluLayer,
54+
self).__init__(prev_layer=prev_layer, act=tf.nn.leaky_relu, a_init_args=a_init_args, name=name)
5455

5556
if channel_shared:
5657
w_shape = (1, )
@@ -65,9 +66,14 @@ def __init__(
6566
name='alpha', shape=w_shape, initializer=a_init, dtype=LayersConfig.tf_dtype, **self.a_init_args
6667
)
6768

68-
alpha_var = tf.nn.sigmoid(alpha_var, name="constraining_alpha_var_in_0_1")
69+
alpha_var_constrained = tf.nn.sigmoid(alpha_var, name="constraining_alpha_var_in_0_1")
6970

70-
self.outputs = tf.nn.leaky_relu(self.inputs, alpha=alpha_var, name="PReLU_activation")
71+
self.outputs = self._apply_activation(
72+
self.inputs, **{
73+
'alpha': alpha_var_constrained,
74+
'name': "PReLU_activation"
75+
}
76+
)
7177

7278
self._add_layers(self.outputs)
7379
self._add_params(alpha_var)
@@ -119,7 +125,7 @@ def __init__(
119125
a_init_args=None, name="PReLU6_layer"
120126
):
121127

122-
super(PRelu6Layer, self).__init__(prev_layer=prev_layer, a_init_args=a_init_args, name=name)
128+
super(PRelu6Layer, self).__init__(prev_layer=prev_layer, act=leaky_relu6, a_init_args=a_init_args, name=name)
123129

124130
if channel_shared:
125131
w_shape = (1, )
@@ -134,9 +140,14 @@ def __init__(
134140
name='alpha', shape=w_shape, initializer=a_init, dtype=LayersConfig.tf_dtype, **self.a_init_args
135141
)
136142

137-
alpha_var = tf.nn.sigmoid(alpha_var, name="constraining_alpha_var_in_0_1")
143+
alpha_var_constrained = tf.nn.sigmoid(alpha_var, name="constraining_alpha_var_in_0_1")
138144

139-
self.outputs = leaky_relu6(self.inputs, alpha=alpha_var, name="PReLU6_activation")
145+
self.outputs = self._apply_activation(
146+
self.inputs, **{
147+
'alpha': alpha_var_constrained,
148+
'name': "PReLU6_activation"
149+
}
150+
)
140151

141152
self._add_layers(self.outputs)
142153
self._add_params(alpha_var)
@@ -190,7 +201,8 @@ def __init__(
190201
a_init_args=None, name="PTReLU6_layer"
191202
):
192203

193-
super(PTRelu6Layer, self).__init__(prev_layer=prev_layer, a_init_args=a_init_args, name=name)
204+
super(PTRelu6Layer,
205+
self).__init__(prev_layer=prev_layer, act=leaky_twice_relu6, a_init_args=a_init_args, name=name)
194206

195207
if channel_shared:
196208
w_shape = (1, )
@@ -207,17 +219,21 @@ def __init__(
207219
name='alpha_low', shape=w_shape, initializer=a_init, dtype=LayersConfig.tf_dtype, **self.a_init_args
208220
)
209221

210-
alpha_low = tf.nn.sigmoid(alpha_low, name="constraining_alpha_low_in_0_1")
222+
alpha_low_constrained = tf.nn.sigmoid(alpha_low, name="constraining_alpha_low_in_0_1")
211223

212224
# Alpha for outputs higher than 6
213225
alpha_high = tf.get_variable(
214226
name='alpha_high', shape=w_shape, initializer=a_init, dtype=LayersConfig.tf_dtype, **self.a_init_args
215227
)
216228

217-
alpha_high = tf.nn.sigmoid(alpha_high, name="constraining_alpha_high_in_0_1")
229+
alpha_high_constrained = tf.nn.sigmoid(alpha_high, name="constraining_alpha_high_in_0_1")
218230

219-
self.outputs = leaky_twice_relu6(
220-
self.inputs, alpha_low=alpha_low, alpha_high=alpha_high, name="PTReLU6_activation"
231+
self.outputs = self.outputs = self._apply_activation(
232+
self.inputs, **{
233+
'alpha_low': alpha_low_constrained,
234+
'alpha_high': alpha_high_constrained,
235+
'name': "PTReLU6_activation"
236+
}
221237
)
222238

223239
self._add_layers(self.outputs)

tests/test_layers_special_activation.py

Lines changed: 112 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,49 +6,136 @@
66
import tensorlayer as tl
77

88

9-
class Layer_Special_Activation_Test(unittest.TestCase):
9+
class PReLU_Layer_Test(unittest.TestCase):
1010

1111
@classmethod
1212
def setUpClass(cls):
1313

1414
x = tf.placeholder(tf.float32, shape=[None, 30])
15-
net = tl.layers.InputLayer(x, name='input')
16-
net = tl.layers.DenseLayer(net, n_units=10, name='dense')
17-
net1 = tl.layers.PReluLayer(net, name='prelu')
1815

19-
net1.print_layers()
20-
net1.print_params(False)
16+
in_layer = tl.layers.InputLayer(x, name='input')
2117

22-
cls.net1_shape = net1.outputs.get_shape().as_list()
23-
cls.net1_layers = net1.all_layers
24-
cls.net1_params = net1.all_params
25-
cls.net1_n_params = net1.count_params()
18+
net = tl.layers.DenseLayer(in_layer, n_units=10, name='dense_1')
19+
cls.net1 = tl.layers.PReluLayer(net, name='prelu_1')
2620

27-
net2 = tl.layers.PReluLayer(net1, channel_shared=True, name='prelu2')
21+
cls.net1.print_layers()
22+
cls.net1.print_params(False)
2823

29-
net2.print_layers()
30-
net2.print_params(False)
24+
net2 = tl.layers.DenseLayer(cls.net1, n_units=30, name='dense_2')
25+
cls.net2 = tl.layers.PReluLayer(net2, channel_shared=True, name='prelu_2')
3126

32-
cls.net2_shape = net2.outputs.get_shape().as_list()
33-
cls.net2_layers = net2.all_layers
34-
cls.net2_params = net2.all_params
35-
cls.net2_n_params = net2.count_params()
27+
cls.net2.print_layers()
28+
cls.net2.print_params(False)
3629

3730
@classmethod
3831
def tearDownClass(cls):
3932
tf.reset_default_graph()
4033

4134
def test_net1(self):
42-
self.assertEqual(len(self.net1_layers), 3)
43-
self.assertEqual(len(self.net1_params), 3)
44-
self.assertEqual(self.net1_n_params, 320)
45-
self.assertEqual(self.net1_shape[-1], 10)
35+
self.assertEqual(len(self.net1.all_layers), 3)
36+
self.assertEqual(len(self.net1.all_params), 3)
37+
self.assertEqual(self.net1.count_params(), 320)
38+
self.assertEqual(self.net1.outputs.get_shape().as_list()[1:], [10])
39+
40+
prelu1_param_shape = self.net1.all_params[-1].get_shape().as_list()
41+
self.assertEqual(prelu1_param_shape, [10])
42+
43+
def test_net2(self):
44+
self.assertEqual(len(self.net2.all_layers), 5)
45+
self.assertEqual(len(self.net2.all_params), 6)
46+
self.assertEqual(self.net2.count_params(), 651)
47+
self.assertEqual(self.net2.outputs.get_shape().as_list()[1:], [30])
48+
49+
prelu2_param_shape = self.net2.all_params[-1].get_shape().as_list()
50+
self.assertEqual(prelu2_param_shape, [1])
51+
52+
53+
class PRelu6_Layer_Test(unittest.TestCase):
54+
55+
@classmethod
56+
def setUpClass(cls):
57+
58+
x = tf.placeholder(tf.float32, shape=[None, 30])
59+
60+
in_layer = tl.layers.InputLayer(x, name='input')
61+
62+
net = tl.layers.DenseLayer(in_layer, n_units=10, name='dense_1')
63+
cls.net1 = tl.layers.PRelu6Layer(net, name='prelu6_1')
64+
65+
cls.net1.print_layers()
66+
cls.net1.print_params(False)
67+
68+
net2 = tl.layers.DenseLayer(cls.net1, n_units=30, name='dense_2')
69+
cls.net2 = tl.layers.PRelu6Layer(net2, channel_shared=True, name='prelu6_2')
70+
71+
cls.net2.print_layers()
72+
cls.net2.print_params(False)
73+
74+
@classmethod
75+
def tearDownClass(cls):
76+
tf.reset_default_graph()
77+
78+
def test_net1(self):
79+
self.assertEqual(len(self.net1.all_layers), 3)
80+
self.assertEqual(len(self.net1.all_params), 3)
81+
self.assertEqual(self.net1.count_params(), 320)
82+
self.assertEqual(self.net1.outputs.get_shape().as_list()[1:], [10])
83+
84+
prelu1_param_shape = self.net1.all_params[-1].get_shape().as_list()
85+
self.assertEqual(prelu1_param_shape, [10])
4686

4787
def test_net2(self):
48-
self.assertEqual(len(self.net2_layers), 4)
49-
self.assertEqual(len(self.net2_params), 4)
50-
self.assertEqual(self.net2_n_params, 321)
51-
self.assertEqual(self.net2_shape[-1], 10)
88+
self.assertEqual(len(self.net2.all_layers), 5)
89+
self.assertEqual(len(self.net2.all_params), 6)
90+
self.assertEqual(self.net2.count_params(), 651)
91+
self.assertEqual(self.net2.outputs.get_shape().as_list()[1:], [30])
92+
93+
prelu2_param_shape = self.net2.all_params[-1].get_shape().as_list()
94+
self.assertEqual(prelu2_param_shape, [1])
95+
96+
97+
class PTRelu6_Layer_Test(unittest.TestCase):
98+
99+
@classmethod
100+
def setUpClass(cls):
101+
102+
x = tf.placeholder(tf.float32, shape=[None, 30])
103+
104+
in_layer = tl.layers.InputLayer(x, name='input')
105+
106+
net = tl.layers.DenseLayer(in_layer, n_units=10, name='dense_1')
107+
cls.net1 = tl.layers.PTRelu6Layer(net, name='ptrelu6_1')
108+
109+
cls.net1.print_layers()
110+
cls.net1.print_params(False)
111+
112+
net2 = tl.layers.DenseLayer(cls.net1, n_units=30, name='dense_2')
113+
cls.net2 = tl.layers.PTRelu6Layer(net2, channel_shared=True, name='ptrelu6_2')
114+
115+
cls.net2.print_layers()
116+
cls.net2.print_params(False)
117+
118+
@classmethod
119+
def tearDownClass(cls):
120+
tf.reset_default_graph()
121+
122+
def test_net1(self):
123+
self.assertEqual(len(self.net1.all_layers), 3)
124+
self.assertEqual(len(self.net1.all_params), 4)
125+
self.assertEqual(self.net1.count_params(), 330)
126+
self.assertEqual(self.net1.outputs.get_shape().as_list()[1:], [10])
127+
128+
prelu1_param_shape = self.net1.all_params[-1].get_shape().as_list()
129+
self.assertEqual(prelu1_param_shape, [10])
130+
131+
def test_net2(self):
132+
self.assertEqual(len(self.net2.all_layers), 5)
133+
self.assertEqual(len(self.net2.all_params), 8)
134+
self.assertEqual(self.net2.count_params(), 662)
135+
self.assertEqual(self.net2.outputs.get_shape().as_list()[1:], [30])
136+
137+
prelu2_param_shape = self.net2.all_params[-1].get_shape().as_list()
138+
self.assertEqual(prelu2_param_shape, [1])
52139

53140

54141
if __name__ == '__main__':

0 commit comments

Comments
 (0)