Completed
Push — master ( 295812...1d3564 )
by
unknown
12:22
created

get_learning_rate()   A

Complexity

Conditions 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 1
c 2
b 1
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
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
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', W_regularizer=l2(regularization_rate)))
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...
52
        model.add(Activation('relu'))
53
    # reshape 3 dimensional array back into a 2 dimensional array,
54
    # but now with more dept as we have the the filters for each channel
55
    model.add(Reshape(target_shape=(dim_length, filters[-1] * dim_channels)))
56
57
    for lstm_dim in lstm_dims:
58
        model.add(LSTM(output_dim=lstm_dim, return_sequences=True,
59
                       activation='tanh'))
60
61
    model.add(Dropout(0.5)) #dropout before the dense layer
62
    # 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...
63
    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...
64
    model.add(Activation("softmax"))
65
    # Final classification layer - per timestep
66
    model.add(Lambda(lambda x: x[:, -1, :], output_shape=[output_dim]))
67
68
    model.compile(loss='categorical_crossentropy',
69
                  optimizer=Adam(lr=learning_rate),
70
                  metrics=['accuracy'])
71
72
    return model
73
74
75 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...
76
    """
77
    Generate a convolutional neural network (CNN) model.
78
79
    The compiled Keras model is returned.
80
    """
81 1
    dim_length = x_shape[1] # number of samples in a time series
82 1
    dim_channels = x_shape[2] # number of channels
83 1
    outputdim = class_number # number of classes
84
85 1
    model = Sequential()
86
    # TODO: weight initialization (in layer constructor)
87
    # TODO: regularation etc
88 1
    model.add(
89
        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...
90
                      W_regularizer=l2(regularization_rate)))
91 1
    for filter_number in filters[1:]:
92 1
        model.add(Convolution1D(filter_number, 3, border_mode='same', W_regularizer=l2(regularization_rate)))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (109/79).

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

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

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

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