Completed
Push — master ( 87644b...5f5cab )
by
unknown
07:54 queued 01:22
created

generate_DeepConvLSTM_model()   B

Complexity

Conditions 4

Size

Total Lines 44

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 17.6056

Importance

Changes 5
Bugs 1 Features 2
Metric Value
cc 4
c 5
b 1
f 2
dl 0
loc 44
ccs 1
cts 19
cp 0.0526
crap 17.6056
rs 8.5806
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
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (162/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(x_shape, number_of_classes, number_of_models=5, model_type=None, **kwargs):
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (95/79).

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

Loading history...
9
    """ Generate one or multiple Keras models with random (default), or predefined, hyperparameters."""
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (103/79).

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

Loading history...
10 1
    models = []
11 1
    for _ in range(0, number_of_models):
12 1
        if model_type == None: # random model choice:
13 1
            current_model_type = 'CNN' if np.random.random(
14
            ) < 0.5 else 'DeepConvLSTM'
15
        else: # user-defined model choice:
16
            current_model_type = model_type
17
18 1
        if current_model_type == 'CNN':
19 1
            generate_model = generate_CNN_model #object is a function
20 1
            generate_hyperparameter_set = generate_CNN_hyperparameter_set
21 1
        if current_model_type == 'DeepConvLSTM':
22
            generate_model = generate_DeepConvLSTM_model #object is a function
23
            generate_hyperparameter_set = generate_DeepConvLSTM_hyperparameter_set
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...
24 1
        hyperparameters = generate_hyperparameter_set(**kwargs)
25 1
        models.append(
26
            (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...
27 1
    return models
28
29
30 1
def generate_DeepConvLSTM_model(x_shape, class_number, filters, lstm_dims, learning_rate=0.01,
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (94/79).

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

Loading history...
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...
31
                                regularization_rate=0.01):
32
    """
33
    Generate a model with convolution and LSTM layers.
34
    See Ordonez et al., 2016, http://dx.doi.org/10.3390/s16010115
35
36
    The compiled Keras model is returned.
37
    """
38
    dim_length = x_shape[1] # number of samples in a time series
39
    dim_channels = x_shape[2] # number of channels
40
    output_dim = class_number # number of classes
41
    weightinit = 'lecun_uniform' # weight initialization
42
    model = Sequential() # initialize model
43
    # reshape a 2 dimensional array per file/person/object into a
44
    # 3 dimensional array
45
    model.add(
46
        Reshape(target_shape=(1, dim_length, dim_channels), input_shape=(dim_length, dim_channels)))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (100/79).

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

Loading history...
47
    for filt in filters:
48
        # filt: number of filters used in a layer
49
        # filters: vector of filt values
50
        model.add(
51
            Convolution2D(filt, nb_row=3, nb_col=1, border_mode='same',
52
             W_regularizer=l2(regularization_rate),init = weightinit))
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
W_regularizer=l2(regularization_rate),init = weightinit))
^
Loading history...
Coding Style introduced by
No space allowed around keyword argument assignment
W_regularizer=l2(regularization_rate),init = weightinit))
^
Loading history...
53
        model.add(Activation('relu'))
54
    # reshape 3 dimensional array back into a 2 dimensional array,
55
    # but now with more dept as we have the the filters for each channel
56
    model.add(Reshape(target_shape=(dim_length, filters[-1] * dim_channels)))
57
58
    for lstm_dim in lstm_dims:
59
        model.add(LSTM(output_dim=lstm_dim, return_sequences=True,
60
                       activation='tanh'))
61
62
    model.add(Dropout(0.5)) #dropout before the dense layer
63
    # set up final dense layer such that every timestamp is given one classification
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (84/79).

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

Loading history...
64
    model.add(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 (88/79).

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

Loading history...
65
    model.add(Activation("softmax"))
66
    # Final classification layer - per timestep
67
    model.add(Lambda(lambda x: x[:, -1, :], output_shape=[output_dim]))
68
69
    model.compile(loss='categorical_crossentropy',
70
                  optimizer=Adam(lr=learning_rate),
71
                  metrics=['accuracy'])
72
73
    return model
74
75
76 1
def generate_CNN_model(x_shape, class_number, filters, fc_hidden_nodes, learning_rate=0.01, regularization_rate=0.01):
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (118/79).

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

Loading history...
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...
77
    """
78
    Generate a convolutional neural network (CNN) model.
79
80
    The compiled Keras model is returned.
81
    """
82 1
    dim_length = x_shape[1] # number of samples in a time series
83 1
    dim_channels = x_shape[2] # number of channels
84 1
    outputdim = class_number # number of classes
85 1
    weightinit = 'lecun_uniform' # weight initialization
86 1
    model = Sequential()
87 1
    model.add(
88
        Convolution1D(filters[0], 3, border_mode='same', input_shape=(dim_length, dim_channels),
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (96/79).

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

Loading history...
89
                      W_regularizer=l2(regularization_rate),init = weightinit))
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
W_regularizer=l2(regularization_rate),init = weightinit))
^
Loading history...
Coding Style introduced by
No space allowed around keyword argument assignment
W_regularizer=l2(regularization_rate),init = weightinit))
^
Loading history...
90 1
    for filter_number in filters[1:]:
91 1
        model.add(Convolution1D(filter_number, 3, border_mode='same',
92
         W_regularizer=l2(regularization_rate),init = weightinit))
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
W_regularizer=l2(regularization_rate),init = weightinit))
^
Loading history...
Coding Style introduced by
No space allowed around keyword argument assignment
W_regularizer=l2(regularization_rate),init = weightinit))
^
Loading history...
93 1
        model.add(Activation('relu'))
94 1
    model.add(Flatten())
95 1
    model.add(Dense(output_dim=fc_hidden_nodes,
96
     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 (87/79).

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

Loading history...
Coding Style introduced by
Exactly one space required after comma
W_regularizer=l2(regularization_rate),init = weightinit)) # Fully connected layer
^
Loading history...
Coding Style introduced by
No space allowed around keyword argument assignment
W_regularizer=l2(regularization_rate),init = weightinit)) # Fully connected layer
^
Loading history...
97 1
    model.add(Activation('relu'))  # Relu activation
98 1
    model.add(Dense(output_dim=outputdim,init = weightinit))
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
model.add(Dense(output_dim=outputdim,init = weightinit))
^
Loading history...
Coding Style introduced by
No space allowed around keyword argument assignment
model.add(Dense(output_dim=outputdim,init = weightinit))
^
Loading history...
99 1
    model.add(Activation("softmax"))  # Final classification layer
100
101 1
    model.compile(loss='categorical_crossentropy',
102
                  optimizer=Adam(lr=learning_rate),
103
                  metrics=['accuracy'])
104
105 1
    return model
106
107
108 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...
109
                                    min_filters=10, max_filters=100,
110
                                    min_fc_nodes=10, max_fc_nodes=100):
111
    """ Generate a hyperparameter set that define a CNN model."""
112 1
    hyperparameters = generate_base_hyper_parameter_set()
113 1
    number_of_layers = np.random.randint(min_layers, max_layers)
114 1
    hyperparameters['filters'] = np.random.randint(
115
        min_filters, max_filters, number_of_layers)
116 1
    hyperparameters['fc_hidden_nodes'] = np.random.randint(
117
        min_fc_nodes, max_fc_nodes)
118 1
    return hyperparameters
119
120
121 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...
122
    min_conv_layers=1, max_conv_layers=10,
123
    min_conv_filters=10, max_conv_filters=100,
124
    min_lstm_layers=1, max_lstm_layers=5,
125
        min_lstm_dims=10, max_lstm_dims=100):
126
    """ Generate a hyperparameter set that defines a DeepConvLSTM model."""
127
    hyperparameters = generate_base_hyper_parameter_set()
128
    number_of_conv_layers = np.random.randint(min_conv_layers, max_conv_layers)
129
    hyperparameters['filters'] = np.random.randint(
130
        min_conv_filters, max_conv_filters, number_of_conv_layers)
131
    number_of_lstm_layers = np.random.randint(min_lstm_layers, max_lstm_layers)
132
    hyperparameters['lstm_dims'] = np.random.randint(
133
        min_lstm_dims, max_lstm_dims, number_of_lstm_layers)
134
    return hyperparameters
135
136
137 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...
138
    """ 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...
139 1
    hyperparameters = {}
140 1
    hyperparameters['learning_rate'] = get_learning_rate()
141 1
    hyperparameters['regularization_rate'] = get_regularization()
142 1
    return hyperparameters
143
144
145 1
def get_learning_rate(low=1, high=4):
146
    """ 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...
147 1
    result = 10 ** (-np.random.uniform(low, high))
148 1
    return result
149
150
151 1
def get_regularization(low = 1, high = 4):
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
def get_regularization(low = 1, high = 4):
^
Loading history...
Coding Style introduced by
No space allowed around keyword argument assignment
def get_regularization(low = 1, high = 4):
^
Loading history...
152
    """ 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...
153
    return 10**(-np.random.uniform(low, high))
154