Completed
Push — master ( d10d5f...edd44f )
by Dafne van
03:09
created

generate_DeepConvLSTM_hyperparameter_set()   A

Complexity

Conditions 1

Size

Total Lines 55

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 1
c 3
b 0
f 0
dl 0
loc 55
ccs 0
cts 7
cp 0
crap 2
rs 9.7692

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1 1
from keras.models import Sequential
2
from keras.layers import Dense, Activation, Convolution1D, Lambda, \
3
    Convolution2D, Flatten, \
4
    Reshape, LSTM, Dropout, TimeDistributed, BatchNormalization
5
from keras.regularizers import l2
6
from keras.optimizers import Adam
7
import numpy as np
8
9
10
def generate_models(
11
        x_shape, number_of_classes, number_of_models=5, model_type=None,
12
        cnn_min_layers=1, cnn_max_layers=10,
13
        cnn_min_filters=10, cnn_max_filters=100,
14
        cnn_min_fc_nodes=10, cnn_max_fc_nodes=2000,
15
        deepconvlstm_min_conv_layers=1, deepconvlstm_max_conv_layers=10,
16
        deepconvlstm_min_conv_filters=10, deepconvlstm_max_conv_filters=100,
17
        deepconvlstm_min_lstm_layers=1, deepconvlstm_max_lstm_layers=5,
18
        deepconvlstm_min_lstm_dims=10, deepconvlstm_max_lstm_dims=100,
19
        low_lr=1, high_lr=4, low_reg=1, high_reg=4
20
):
21
    """
22
    Generate one or multiple Keras models with random hyperparameters.
23
24
    Parameters
25
    ----------
26
    x_shape : tuple
27
        Shape of the input dataset: (num_samples, num_timesteps, num_channels)
28
    number_of_classes : int
29
        Number of classes for classification task
30
    number_of_models : int
31
        Number of models to generate
32
    model_type : str, optional
33
        Type of model to build: 'CNN' or 'DeepConvLSTM'.
34
        Default option None generates both models.
35
    cnn_min_layers : int
36
        minimum of Conv layers in CNN model
37
    cnn_max_layers : int
38
        maximum of Conv layers in CNN model
39
    cnn_min_filters : int
40
        minimum number of filters per Conv layer in CNN model
41
    cnn_max_filters : int
42
        maximum number of filters per Conv layer in CNN model
43
    cnn_min_fc_nodes : int
44
        minimum number of hidden nodes per Dense layer in CNN model
45
    cnn_max_fc_nodes : int
46
        maximum number of hidden nodes per Dense layer in CNN model
47
    deepconvlstm_min_conv_layers : int
48
        minimum number of Conv layers in DeepConvLSTM model
49
    deepconvlstm_max_conv_layers : int
50
        maximum number of Conv layers in DeepConvLSTM model
51
    deepconvlstm_min_conv_filters : int
52
        minimum number of filters per Conv layer in DeepConvLSTM model
53
    deepconvlstm_max_conv_filters : int
54
        maximum number of filters per Conv layer in DeepConvLSTM model
55
    deepconvlstm_min_lstm_layers : int
56
        minimum number of Conv layers in DeepConvLSTM model
57
    deepconvlstm_max_lstm_layers : int
58
        maximum number of Conv layers in DeepConvLSTM model
59
    deepconvlstm_min_lstm_dims : int
60
        minimum number of hidden nodes per LSTM layer in DeepConvLSTM model
61
    deepconvlstm_max_lstm_dims : int
62
        maximum number of hidden nodes per LSTM layer in DeepConvLSTM model
63
    low_lr : float
64
        minimum of log range for learning rate: learning rate is sampled
65
        between `10**(-low_reg)` and `10**(-high_reg)`
66
    high_lr : float
67
        maximum  of log range for learning rate: learning rate is sampled
68
        between `10**(-low_reg)` and `10**(-high_reg)`
69
    low_reg : float
70
        minimum  of log range for regularization rate: regularization rate is
71
        sampled between `10**(-low_reg)` and `10**(-high_reg)`
72
    high_reg : float
73
        maximum  of log range for regularization rate: regularization rate is
74
        sampled between `10**(-low_reg)` and `10**(-high_reg)`
75
76
    Returns
77
    -------
78
    models : list
79
        List of compiled models
80
    """
81
    models = []
82
    for _ in range(0, number_of_models):
83
        if model_type is None:  # random model choice:
84
            current_model_type = 'CNN' if np.random.random(
85
            ) < 0.5 else 'DeepConvLSTM'
86
        else:  # user-defined model choice:
87
            current_model_type = model_type
88
        generate_model = None
89
        if current_model_type == 'CNN':
90
            generate_model = generate_CNN_model  # generate_model is a function
91
            hyperparameters = generate_CNN_hyperparameter_set(
92
                min_layers=cnn_min_layers, max_layers=cnn_max_layers,
93
                min_filters=cnn_min_filters, max_filters=cnn_max_filters,
94
                min_fc_nodes=cnn_min_fc_nodes, max_fc_nodes=cnn_max_fc_nodes,
95
                low_lr=low_lr, high_lr=high_lr, low_reg=low_reg,
96
                high_reg=high_reg)
97
        if current_model_type == 'DeepConvLSTM':
98
            generate_model = generate_DeepConvLSTM_model
99
            hyperparameters = generate_DeepConvLSTM_hyperparameter_set(
100
                min_conv_layers=deepconvlstm_min_conv_layers,
101
                max_conv_layers=deepconvlstm_max_conv_layers,
102
                min_conv_filters=deepconvlstm_min_conv_filters,
103
                max_conv_filters=deepconvlstm_max_conv_filters,
104
                min_lstm_layers=deepconvlstm_min_lstm_layers,
105
                max_lstm_layers=deepconvlstm_max_lstm_layers,
106
                min_lstm_dims=deepconvlstm_min_lstm_dims,
107
                max_lstm_dims=deepconvlstm_max_lstm_dims,
108
                low_lr=low_lr, high_lr=high_lr, low_reg=low_reg,
109
                high_reg=high_reg)
110
        models.append(
111
            (generate_model(x_shape, number_of_classes, **hyperparameters),
112
             hyperparameters, current_model_type))
113
    return models
114
115
116
def generate_DeepConvLSTM_model(
117
        x_shape, class_number, filters, lstm_dims, learning_rate=0.01,
118
        regularization_rate=0.01):
119
    """
120
    Generate a model with convolution and LSTM layers.
121
    See Ordonez et al., 2016, http://dx.doi.org/10.3390/s16010115
122
123
    Parameters
124
    ----------
125
    x_shape : tuple
126
        Shape of the input dataset: (num_samples, num_timesteps, num_channels)
127
    class_number : int
128
        Number of classes for classification task
129
    filters : list of ints
130
        number of filters for each convolutional layer
131
    lstm_dims : list of ints
132
        number of hidden nodes for each LSTM layer
133
    learning_rate : float
134
        learning rate
135
    regularization_rate : float
136
        regularization rate
137
138
    Returns
139
    -------
140
    model : Keras model
141
        The compiled Keras model
142
    """
143
    dim_length = x_shape[1]  # number of samples in a time series
144
    dim_channels = x_shape[2]  # number of channels
145
    output_dim = class_number  # number of classes
146
    weightinit = 'lecun_uniform'  # weight initialization
147
    model = Sequential()  # initialize model
148
    model.add(BatchNormalization(input_shape=(dim_length, dim_channels)))
149
    # reshape a 2 dimensional array per file/person/object into a
150
    # 3 dimensional array
151
    model.add(
152
        Reshape(target_shape=(1, dim_length, dim_channels)))
153
    for filt in filters:
154
        # filt: number of filters used in a layer
155
        # filters: vector of filt values
156
        model.add(
157
            Convolution2D(filt, nb_row=3, nb_col=1, border_mode='same',
158
                          W_regularizer=l2(regularization_rate),
159
                          init=weightinit))
160
        model.add(BatchNormalization())
161
        model.add(Activation('relu'))
162
    # reshape 3 dimensional array back into a 2 dimensional array,
163
    # but now with more dept as we have the the filters for each channel
164
    model.add(Reshape(target_shape=(dim_length, filters[-1] * dim_channels)))
165
166
    for lstm_dim in lstm_dims:
167
        model.add(LSTM(output_dim=lstm_dim, return_sequences=True,
168
                       activation='tanh'))
169
170
    model.add(Dropout(0.5))  # dropout before the dense layer
171
    # set up final dense layer such that every timestamp is given one
172
    # classification
173
    model.add(
174
        TimeDistributed(
175
            Dense(output_dim, W_regularizer=l2(regularization_rate))))
176
    model.add(Activation("softmax"))
177
    # Final classification layer - per timestep
178
    model.add(Lambda(lambda x: x[:, -1, :], output_shape=[output_dim]))
179
180
    model.compile(loss='categorical_crossentropy',
181
                  optimizer=Adam(lr=learning_rate),
182
                  metrics=['accuracy'])
183
184
    return model
185
186
187
def generate_CNN_model(x_shape, class_number, filters, fc_hidden_nodes,
188
                       learning_rate=0.01, regularization_rate=0.01):
189
    """
190
    Generate a convolutional neural network (CNN) model.
191
192
    The compiled Keras model is returned.
193
194
    Parameters
195
    ----------
196
    x_shape : tuple
197
        Shape of the input dataset: (num_samples, num_timesteps, num_channels)
198
    class_number : int
199
        Number of classes for classification task
200
    filters : list of ints
201
        number of filters for each convolutional layer
202
    fc_hidden_nodes : int
203
        number of hidden nodes for the hidden dense layer
204
    learning_rate : float
205
        learning rate
206
    regularization_rate : float
207
        regularization rate
208
209
    Returns
210
    -------
211
    model : Keras model
212
        The compiled Keras model
213
    """
214
    dim_length = x_shape[1]  # number of samples in a time series
215
    dim_channels = x_shape[2]  # number of channels
216
    outputdim = class_number  # number of classes
217
    weightinit = 'lecun_uniform'  # weight initialization
218
    model = Sequential()
219
    model.add(
220
        BatchNormalization(
221
            input_shape=(
222
                dim_length,
223
                dim_channels),
224
            mode=0,
225
            axis=2))
226
    for filter_number in filters:
227
        model.add(Convolution1D(filter_number, 3, border_mode='same',
228
                                W_regularizer=l2(regularization_rate),
229
                                init=weightinit))
230
        model.add(BatchNormalization())
231
        model.add(Activation('relu'))
232
    model.add(Flatten())
233
    model.add(Dense(output_dim=fc_hidden_nodes,
234
                    W_regularizer=l2(regularization_rate),
235
                    init=weightinit))  # Fully connected layer
236
    model.add(Activation('relu'))  # Relu activation
237
    model.add(Dense(output_dim=outputdim, init=weightinit))
238
    model.add(BatchNormalization())
239
    model.add(Activation("softmax"))  # Final classification layer
240
241
    model.compile(loss='categorical_crossentropy',
242
                  optimizer=Adam(lr=learning_rate),
243
                  metrics=['accuracy'])
244
245
    return model
246
247
248
def generate_CNN_hyperparameter_set(min_layers=1, max_layers=10,
249
                                    min_filters=10, max_filters=100,
250
                                    min_fc_nodes=10, max_fc_nodes=2000,
251
                                    low_lr=1, high_lr=4, low_reg=1,
252
                                    high_reg=4):
253
    """ Generate a hyperparameter set that define a CNN model.
254
255
    Parameters
256
    ----------
257
    min_layers : int
258
        minimum of Conv layers
259
    max_layers : int
260
        maximum of Conv layers
261
    min_filters : int
262
        minimum number of filters per Conv layer
263
    max_filters : int
264
        maximum number of filters per Conv layer
265
    min_fc_nodes : int
266
        minimum number of hidden nodes per Dense layer
267
    max_fc_nodes : int
268
        maximum number of hidden nodes per Dense layer
269
    low_lr : float
270
        minimum of log range for learning rate: learning rate is sampled
271
        between `10**(-low_reg)` and `10**(-high_reg)`
272
    high_lr : float
273
        maximum  of log range for learning rate: learning rate is sampled
274
        between `10**(-low_reg)` and `10**(-high_reg)`
275
    low_reg : float
276
        minimum  of log range for regularization rate: regularization rate is
277
        sampled between `10**(-low_reg)` and `10**(-high_reg)`
278
    high_reg : float
279
        maximum  of log range for regularization rate: regularization rate is
280
        sampled between `10**(-low_reg)` and `10**(-high_reg)`
281
282
    Returns
283
    ----------
284
    hyperparameters : dict
285
        parameters for a CNN model
286
    """
287
    hyperparameters = generate_base_hyper_parameter_set(
288
        low_lr, high_lr, low_reg, high_reg)
289
    number_of_layers = np.random.randint(min_layers, max_layers + 1)
290
    hyperparameters['filters'] = np.random.randint(
291
        min_filters, max_filters + 1, number_of_layers)
292
    hyperparameters['fc_hidden_nodes'] = np.random.randint(
293
        min_fc_nodes, max_fc_nodes + 1)
294
    return hyperparameters
295
296
297
def generate_DeepConvLSTM_hyperparameter_set(
298
        min_conv_layers=1, max_conv_layers=10,
299
        min_conv_filters=10, max_conv_filters=100,
300
        min_lstm_layers=1, max_lstm_layers=5,
301
        min_lstm_dims=10, max_lstm_dims=100,
302
        low_lr=1, high_lr=4, low_reg=1, high_reg=4):
303
    """ Generate a hyperparameter set that defines a DeepConvLSTM model.
304
305
    Parameters
306
    ----------
307
    min_conv_layers : int
308
        minimum number of Conv layers in DeepConvLSTM model
309
    max_conv_layers : int
310
        maximum number of Conv layers in DeepConvLSTM model
311
    min_conv_filters : int
312
        minimum number of filters per Conv layer in DeepConvLSTM model
313
    max_conv_filters : int
314
        maximum number of filters per Conv layer in DeepConvLSTM model
315
    min_lstm_layers : int
316
        minimum number of Conv layers in DeepConvLSTM model
317
    max_lstm_layers : int
318
        maximum number of Conv layers in DeepConvLSTM model
319
    min_lstm_dims : int
320
        minimum number of hidden nodes per LSTM layer in DeepConvLSTM model
321
    max_lstm_dims : int
322
        maximum number of hidden nodes per LSTM layer in DeepConvLSTM model
323
    low_lr : float
324
        minimum of log range for learning rate: learning rate is sampled
325
        between `10**(-low_reg)` and `10**(-high_reg)`
326
    high_lr : float
327
        maximum  of log range for learning rate: learning rate is sampled
328
        between `10**(-low_reg)` and `10**(-high_reg)`
329
    low_reg : float
330
        minimum  of log range for regularization rate: regularization rate is
331
        sampled between `10**(-low_reg)` and `10**(-high_reg)`
332
    high_reg : float
333
        maximum  of log range for regularization rate: regularization rate is
334
        sampled between `10**(-low_reg)` and `10**(-high_reg)`
335
336
    Returns
337
    ----------
338
    hyperparameters: dict
339
        hyperparameters for a DeepConvLSTM model
340
    """
341
    hyperparameters = generate_base_hyper_parameter_set(
342
        low_lr, high_lr, low_reg, high_reg)
343
    number_of_conv_layers = np.random.randint(
344
        min_conv_layers, max_conv_layers + 1)
345
    hyperparameters['filters'] = np.random.randint(
346
        min_conv_filters, max_conv_filters + 1, number_of_conv_layers)
347
    number_of_lstm_layers = np.random.randint(
348
        min_lstm_layers, max_lstm_layers + 1)
349
    hyperparameters['lstm_dims'] = np.random.randint(
350
        min_lstm_dims, max_lstm_dims + 1, number_of_lstm_layers)
351
    return hyperparameters
352
353
354
def generate_base_hyper_parameter_set(
355
        low_lr=1,
356
        high_lr=4,
357
        low_reg=1,
358
        high_reg=4):
359
    """ Generate a base set of hyperparameters that are necessary for any
360
    model, but sufficient for none.
361
362
    Parameters
363
    ----------
364
    low_lr : float
365
        minimum of log range for learning rate: learning rate is sampled
366
        between `10**(-low_reg)` and `10**(-high_reg)`
367
    high_lr : float
368
        maximum  of log range for learning rate: learning rate is sampled
369
        between `10**(-low_reg)` and `10**(-high_reg)`
370
    low_reg : float
371
        minimum  of log range for regularization rate: regularization rate is
372
        sampled between `10**(-low_reg)` and `10**(-high_reg)`
373
    high_reg : float
374
        maximum  of log range for regularization rate: regularization rate is
375
        sampled between `10**(-low_reg)` and `10**(-high_reg)`
376
377
    Returns
378
    -------
379
    hyperparameters : dict
380
        basis hyperpameters
381
    """
382
    hyperparameters = {}
383
    hyperparameters['learning_rate'] = get_learning_rate(low_lr, high_lr)
384
    hyperparameters['regularization_rate'] = get_regularization(
385
        low_reg, high_reg)
386
    return hyperparameters
387
388
389
def get_learning_rate(low=1, high=4):
390
    """ Return random learning rate 10^-n where n is sampled uniformly between
391
    low and high bounds.
392
393
    Parameters
394
    ----------
395
    low : float
396
        low bound
397
    high : float
398
        high bound
399
400
    Returns
401
    -------
402
    learning_rate : float
403
        learning rate
404
    """
405
    result = 10 ** (-np.random.uniform(low, high))
406
    return result
407
408
409
def get_regularization(low=1, high=4):
410
    """ Return random regularization rate 10^-n where n is sampled uniformly
411
    between low and high bounds.
412
413
    Parameters
414
    ----------
415
    low : float
416
        low bound
417
    high : float
418
        high bound
419
420
    Returns
421
    -------
422
    regularization_rate : float
423
        regularization rate
424
    """
425
    return 10 ** (-np.random.uniform(low, high))
426