@@ -13,6 +13,11 @@ class ConcreteDropout(Wrapper):
13
13
"""A wrapper automating the dropout rate choice
14
14
through the 'Concrete Dropout' technique.
15
15
16
+ Note that currently only Dense layers with weights
17
+ and Conv layers (Conv1D, Conv2D, Conv3D) are supported.
18
+ In the case of Dense Layers, dropout is applied to its complete input,
19
+ whereas in the Conv case just the input-channels are dropped.
20
+
16
21
# Example
17
22
18
23
```python
@@ -24,7 +29,7 @@ class ConcreteDropout(Wrapper):
24
29
model.add(ConcreteDropout(Dense(32), n_data=500))
25
30
# now model.output_shape == (None, 32)
26
31
27
- # Note that the current implementation supports Conv2D Layer as well.
32
+ # Note that the current implementation supports Conv layers as well.
28
33
```
29
34
30
35
# Arguments
@@ -83,19 +88,21 @@ def _concrete_dropout(self, inputs, layer_type):
83
88
84
89
# Arguments
85
90
inputs: Input.
86
- layer_type: str. Either 'dense' or 'conv2d '.
91
+ layer_type: str. Either 'dense' or 'conv '.
87
92
# Returns
88
93
A tensor with the same shape as inputs and dropout applied.
89
94
"""
90
- assert layer_type in {'dense' , 'conv2d ' }
95
+ assert layer_type in {'dense' , 'conv ' }
91
96
eps = K .cast_to_floatx (K .epsilon ())
92
97
93
98
noise_shape = K .shape (inputs )
94
- if layer_type == 'conv2d' :
99
+ if layer_type == 'conv' :
100
+ nodrops = np .ones (len (K .int_shape (inputs )) - 2 , int )
101
+ _ = lambda * x : x # don't ask... py2 can't unpack directly into a tuple
95
102
if K .image_data_format () == 'channels_first' :
96
- noise_shape = (noise_shape [0 ], noise_shape [1 ], 1 , 1 )
103
+ noise_shape = _ (noise_shape [0 ], noise_shape [1 ], * nodrops )
97
104
else :
98
- noise_shape = (noise_shape [0 ], 1 , 1 , noise_shape [3 ] )
105
+ noise_shape = _ (noise_shape [0 ], * ( _ ( * nodrops ) + ( noise_shape [- 1 ],)) )
99
106
unif_noise = K .random_uniform (shape = noise_shape ,
100
107
seed = self ._seed ,
101
108
dtype = inputs .dtype )
@@ -119,13 +126,15 @@ def build(self, input_shape=None):
119
126
input_shape = to_tuple (input_shape )
120
127
if len (input_shape ) == 2 : # Dense_layer
121
128
input_dim = np .prod (input_shape [- 1 ]) # we drop only last dim
122
- elif len (input_shape ) == 4 : # Conv2D_layer
123
- input_dim = (input_shape [1 ]
124
- if K .image_data_format () == 'channels_first'
125
- else input_shape [3 ]) # we drop only channels
129
+ elif 3 <= len (input_shape ) <= 5 : # Conv_layers
130
+ input_dim = (
131
+ input_shape [1 ]
132
+ if K .image_data_format () == 'channels_first'
133
+ else input_shape [- 1 ] # we drop only channels
134
+ )
126
135
else :
127
136
raise ValueError (
128
- 'concrete_dropout currenty supports only Dense/Conv2D layers' )
137
+ 'concrete_dropout currenty supports only Dense/Conv layers' )
129
138
130
139
self .input_spec = InputSpec (shape = input_shape )
131
140
if not self .layer .built :
@@ -161,7 +170,7 @@ def build(self, input_shape=None):
161
170
def call (self , inputs , training = None ):
162
171
def relaxed_dropped_inputs ():
163
172
return self .layer .call (self ._concrete_dropout (inputs , (
164
- 'dense' if len (K .int_shape (inputs )) == 2 else 'conv2d '
173
+ 'dense' if len (K .int_shape (inputs )) == 2 else 'conv '
165
174
)))
166
175
167
176
return K .in_train_phase (relaxed_dropped_inputs ,
0 commit comments