Completed
Push — master ( 7ce67b...ed5c34 )
by Dafne van
06:47
created

generate_DeepConvLSTM_hyperparameter_set()   A

Complexity

Conditions 1

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 1
c 3
b 1
f 0
dl 0
loc 16
ccs 7
cts 7
cp 1
crap 1
rs 9.4285
1 1
from keras.models import Sequential
2 1
from keras.layers import Dense, Activation, Convolution1D, Flatten, MaxPooling1D, Lambda, Convolution2D, Flatten, Reshape, LSTM, Dropout, TimeDistributed, Permute, BatchNormalization
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (182/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
3 1
from keras.regularizers import l2
4 1
from keras.optimizers import Adam
5 1
import numpy as np
6
7
8 1
def generate_models(
9
    x_shape, number_of_classes, number_of_models=5, model_type=None,
10
    cnn_min_layers=1, cnn_max_layers=10,
11
    cnn_min_filters=10, cnn_max_filters=100,
12
    cnn_min_fc_nodes=10, cnn_max_fc_nodes=100,
13
    deepconvlstm_min_conv_layers=1, deepconvlstm_max_conv_layers=10,
14
    deepconvlstm_min_conv_filters=10, deepconvlstm_max_conv_filters=100,
15
    deepconvlstm_min_lstm_layers=1, deepconvlstm_max_lstm_layers=5,
16
    deepconvlstm_min_lstm_dims=10, deepconvlstm_max_lstm_dims=100,
17
    low_lr=1, high_lr=4, low_reg=1, high_reg=4
18
):
19
    """
20
    Generate one or multiple Keras models with random hyperparameters.
21
22
    Parameters
23
    ----------
24
    x_shape
25
        Shape of the input data set. Should be 3 dimensions.
26
    number_of_classes
27
        Number of classes for classification task
28
    number_of_models
29
        Number of models to generate
30
    model_type : str (optional)
31
        Type of model to build: 'CNN' or 'DeepConvLSTM'. Default option None generates both models.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (99/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
32
    cnn_min_layers : int
33
        minimum of Conv layers in CNN model
34
    cnn_max_layers : int
35
        maximum of Conv layers in CNN model
36
    cnn_min_filters : int
37
        minimum number of filters per Conv layer in CNN model
38
    cnn_max_filters : int
39
        maximum number of filters per Conv layer in CNN model
40
    cnn_min_fc_nodes : int
41
        minimum number of hidden nodes per Dense layer in CNN model
42
    cnn_max_fc_nodes : int
43
        maximum number of hidden nodes per Dense layer in CNN model
44
    deepconvlstm_min_conv_layers : int
45
        minimum number of Conv layers in DeepConvLSTM model
46
    deepconvlstm_max_conv_layers : int
47
        maximum number of Conv layers in DeepConvLSTM model
48
    deepconvlstm_min_conv_filters : int
49
        minimum number of filters per Conv layer in DeepConvLSTM model
50
    deepconvlstm_max_conv_filters : int
51
        maximum number of filters per Conv layer in DeepConvLSTM model
52
    deepconvlstm_min_lstm_layers : int
53
        minimum number of Conv layers in DeepConvLSTM model
54
    deepconvlstm_max_lstm_layers : int
55
        maximum number of Conv layers in DeepConvLSTM model
56
    deepconvlstm_min_lstm_dims : int
57
        minimum number of hidden nodes per LSTM layer in DeepConvLSTM model
58
    deepconvlstm_max_lstm_dims : int
59
        maximum number of hidden nodes per LSTM layer in DeepConvLSTM model
60
    low_lr : float
61
        minimum of log range for learning rate: learning rate is sampled between `10**(-low_reg)` and `10**(-high_reg)`
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (119/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
62
    high_lr : float
63
        maximum  of log range for learning rate: learning rate is sampled between `10**(-low_reg)` and `10**(-high_reg)`
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (120/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
64
    low_reg : float
65
        minimum  of log range for regularization rate: regularization rate is sampled between `10**(-low_reg)` and `10**(-high_reg)`
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (132/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
66
    high_reg : float
67
        maximum  of log range for regularization rate: regularization rate is sampled between `10**(-low_reg)` and `10**(-high_reg)`
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (132/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
68
69
    Returns
70
    -------
71
    List of compiled models
72
    """
73 1
    models = []
74 1
    for _ in range(0, number_of_models):
75 1
        if model_type is None:  # random model choice:
76 1
            current_model_type = 'CNN' if np.random.random(
77
            ) < 0.5 else 'DeepConvLSTM'
78
        else:  # user-defined model choice:
79
            current_model_type = model_type
80 1
        generate_model = None
81 1
        if current_model_type == 'CNN':
82 1
            generate_model = generate_CNN_model  # object is a function
83 1
            hyperparameters = generate_CNN_hyperparameter_set(
84
                min_layers=cnn_min_layers, max_layers=cnn_max_layers,
85
                min_filters=cnn_min_filters, max_filters=cnn_max_filters,
86
                min_fc_nodes=cnn_min_fc_nodes, max_fc_nodes=cnn_max_fc_nodes,
87
                low_lr=low_lr, high_lr=high_lr, low_reg=low_reg, high_reg=high_reg)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (83/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
88 1
        if current_model_type == 'DeepConvLSTM':
89
            generate_model = generate_DeepConvLSTM_model  # object is a function
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (80/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
90
            hyperparameters = generate_DeepConvLSTM_hyperparameter_set(
91
                min_conv_layers=deepconvlstm_min_conv_layers, max_conv_layers=deepconvlstm_max_conv_layers,
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (107/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
92
                min_conv_filters=deepconvlstm_min_conv_filters, max_conv_filters=deepconvlstm_max_conv_filters,
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (111/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
93
                min_lstm_layers=deepconvlstm_min_lstm_layers, max_lstm_layers=deepconvlstm_max_lstm_layers,
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (107/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
94
                min_lstm_dims=deepconvlstm_min_lstm_dims, max_lstm_dims=deepconvlstm_max_lstm_dims,
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (99/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
95
                low_lr=low_lr, high_lr=high_lr, low_reg=low_reg, high_reg=high_reg)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (83/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
96 1
        models.append(
97
            (generate_model(x_shape, number_of_classes, **hyperparameters), hyperparameters, current_model_type))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (113/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
98 1
    return models
99
100
101 1
def generate_DeepConvLSTM_model(
0 ignored issues
show
Coding Style Naming introduced by
The name generate_DeepConvLSTM_model does not conform to the function naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
102
    x_shape, class_number, filters, lstm_dims, learning_rate=0.01,
103
        regularization_rate=0.01):
104
    """
105
    Generate a model with convolution and LSTM layers.
106
    See Ordonez et al., 2016, http://dx.doi.org/10.3390/s16010115
107
108
    The compiled Keras model is returned.
109
    """
110 1
    dim_length = x_shape[1]  # number of samples in a time series
111 1
    dim_channels = x_shape[2]  # number of channels
112 1
    output_dim = class_number  # number of classes
113 1
    weightinit = 'lecun_uniform'  # weight initialization
114 1
    model = Sequential()  # initialize model
115 1
    model.add(BatchNormalization(input_shape=(dim_length, dim_channels)))
116
    # reshape a 2 dimensional array per file/person/object into a
117
    # 3 dimensional array
118 1
    model.add(
119
        Reshape(target_shape=(1, dim_length, dim_channels)))
120 1
    for filt in filters:
121
        # filt: number of filters used in a layer
122
        # filters: vector of filt values
123 1
        model.add(
124
            Convolution2D(filt, nb_row=3, nb_col=1, border_mode='same',
125
                          W_regularizer=l2(regularization_rate), init=weightinit))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (82/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
126 1
        model.add(Activation('relu'))
127
    # reshape 3 dimensional array back into a 2 dimensional array,
128
    # but now with more dept as we have the the filters for each channel
129 1
    model.add(Reshape(target_shape=(dim_length, filters[-1] * dim_channels)))
130
131 1
    for lstm_dim in lstm_dims:
132 1
        model.add(LSTM(output_dim=lstm_dim, return_sequences=True,
133
                       activation='tanh'))
134
135 1
    model.add(Dropout(0.5))  # dropout before the dense layer
136
    # set up final dense layer such that every timestamp is given one
137
    # classification
138 1
    model.add(
139
        TimeDistributed(Dense(output_dim, W_regularizer=l2(regularization_rate))))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (82/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
140 1
    model.add(Activation("softmax"))
141
    # Final classification layer - per timestep
142 1
    model.add(Lambda(lambda x: x[:, -1, :], output_shape=[output_dim]))
143
144 1
    model.compile(loss='categorical_crossentropy',
145
                  optimizer=Adam(lr=learning_rate),
146
                  metrics=['accuracy'])
147
148 1
    return model
149
150
151 1
def generate_CNN_model(x_shape, class_number, filters, fc_hidden_nodes,
0 ignored issues
show
Coding Style Naming introduced by
The name generate_CNN_model does not conform to the function naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
152
                       learning_rate=0.01, regularization_rate=0.01):
153
    """
154
    Generate a convolutional neural network (CNN) model.
155
156
    The compiled Keras model is returned.
157
    """
158 1
    dim_length = x_shape[1]  # number of samples in a time series
159 1
    dim_channels = x_shape[2]  # number of channels
160 1
    outputdim = class_number  # number of classes
161 1
    weightinit = 'lecun_uniform'  # weight initialization
162 1
    model = Sequential()
163 1
    model.add(BatchNormalization(input_shape=(dim_length, dim_channels)))
164 1
    for filter_number in filters:
165 1
        model.add(Convolution1D(filter_number, 3, border_mode='same',
166
                                W_regularizer=l2(regularization_rate), init=weightinit))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (88/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
167 1
        model.add(Activation('relu'))
168 1
    model.add(Flatten())
169 1
    model.add(Dense(output_dim=fc_hidden_nodes,
170
                    W_regularizer=l2(regularization_rate), init=weightinit))  # Fully connected layer
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (101/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
171 1
    model.add(Activation('relu'))  # Relu activation
172 1
    model.add(Dense(output_dim=outputdim, init=weightinit))
173 1
    model.add(Activation("softmax"))  # Final classification layer
174
175 1
    model.compile(loss='categorical_crossentropy',
176
                  optimizer=Adam(lr=learning_rate),
177
                  metrics=['accuracy'])
178
179 1
    return model
180
181
182 1
def generate_CNN_hyperparameter_set(min_layers=1, max_layers=10,
0 ignored issues
show
Coding Style Naming introduced by
The name generate_CNN_hyperparameter_set does not conform to the function naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
183
                                    min_filters=10, max_filters=100,
184
                                    min_fc_nodes=10, max_fc_nodes=100,
185
                                    low_lr=1, high_lr=4, low_reg=1, high_reg=4):
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (80/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
186
    """ Generate a hyperparameter set that define a CNN model."""
187 1
    hyperparameters = generate_base_hyper_parameter_set(
188
        low_lr, high_lr, low_reg, high_reg)
189 1
    number_of_layers = np.random.randint(min_layers, max_layers+1)
190 1
    hyperparameters['filters'] = np.random.randint(
191
        min_filters, max_filters+1, number_of_layers)
192 1
    hyperparameters['fc_hidden_nodes'] = np.random.randint(
193
        min_fc_nodes, max_fc_nodes+1)
194 1
    return hyperparameters
195
196
197 1
def generate_DeepConvLSTM_hyperparameter_set(
0 ignored issues
show
Coding Style Naming introduced by
The name generate_DeepConvLSTM_hyperparameter_set does not conform to the function naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
198
    min_conv_layers=1, max_conv_layers=10,
199
    min_conv_filters=10, max_conv_filters=100,
200
    min_lstm_layers=1, max_lstm_layers=5,
201
    min_lstm_dims=10, max_lstm_dims=100,
202
        low_lr=1, high_lr=4, low_reg=1, high_reg=4):
203
    """ Generate a hyperparameter set that defines a DeepConvLSTM model."""
204 1
    hyperparameters = generate_base_hyper_parameter_set(
205
        low_lr, high_lr, low_reg, high_reg)
206 1
    number_of_conv_layers = np.random.randint(min_conv_layers, max_conv_layers+1)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (81/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
207 1
    hyperparameters['filters'] = np.random.randint(
208
        min_conv_filters, max_conv_filters+1, number_of_conv_layers)
209 1
    number_of_lstm_layers = np.random.randint(min_lstm_layers, max_lstm_layers+1)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (81/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
210 1
    hyperparameters['lstm_dims'] = np.random.randint(
211
        min_lstm_dims, max_lstm_dims+1, number_of_lstm_layers)
212 1
    return hyperparameters
213
214
215 1
def generate_base_hyper_parameter_set(
0 ignored issues
show
Coding Style Naming introduced by
The name generate_base_hyper_parameter_set does not conform to the function naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
216
    low_lr=1,
217
    high_lr=4,
218
    low_reg=1,
219
        high_reg=4):
220
    """ Generate a base set of hyperparameters that are necessary for any model, but sufficient for none."""
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (108/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
221 1
    hyperparameters = {}
222 1
    hyperparameters['learning_rate'] = get_learning_rate(low_lr, high_lr)
223 1
    hyperparameters['regularization_rate'] = get_regularization(
224
        low_reg, high_reg)
225 1
    return hyperparameters
226
227
228 1
def get_learning_rate(low=1, high=4):
229
    """ Return random learning rate 10^-n where n is sampled uniformly between low and high bounds."""
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (102/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
230 1
    result = 10 ** (-np.random.uniform(low, high))
231 1
    return result
232
233
234 1
def get_regularization(low=1, high=4):
235
    """ Return random regularization rate 10^-n where n is sampled uniformly between low and high bounds."""
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (108/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
236
    return 10 ** (-np.random.uniform(low, high))
237