Skip to content

Commit

Permalink
add a first solution for fine-tuning models #2
Browse files Browse the repository at this point in the history
  • Loading branch information
pzinemanas committed May 27, 2020
1 parent e0ba7ba commit b8a5842
Show file tree
Hide file tree
Showing 14 changed files with 319 additions and 5 deletions.
53 changes: 52 additions & 1 deletion dcase_models/model/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

from keras.optimizers import Adam
from keras.callbacks import ModelCheckpoint,CSVLogger
from keras.models import model_from_json
from keras.models import model_from_json, Model
import keras.backend as K
from keras.layers import Dense, Input


from ..utils.files import save_json
from ..utils.metrics import evaluate_metrics
Expand Down Expand Up @@ -214,3 +216,52 @@ def get_numer_of_parameters(self):
trainable_count = int(np.sum([K.count_params(p) for p in set(models.trainable_weights)]))
return trainable_count

def fine_tuning(self, layer_where_to_cut, new_number_of_classes=10, new_activation='softmax',
freeze_source_model=True, new_model=None):
"""
Create a new model for fine-tuning. Cut the model in the layer_where_to_cut layer
and add a new fully-connected layer.
Parameters
----------
layer_where_to_cut : str or int
Name (str) of index (int) of the layer where cut the model. This layer
is included in the new model.
new_number_of_classes : int
Number of units in the new fully-connected layer (number of classes)
new_activation : str
Activitation of the new fully-connected layer
freeze_source_model : bool
If True, the source model is set to not be trainable
new_model : Keras Model
If is not None, this model is add after the cut model. This is useful if you
want add more than a fully-connected layer.
"""
# cut last layer
if type(layer_where_to_cut) == str:
last_layer = self.model.get_layer(layer_where_to_cut)
elif type(layer_where_to_cut) == int:
last_layer = self.model.layers[layer_where_to_cut]
else:
raise AttributeError("layer_where_to_cut has to be str or int type")
model_without_last_layer = Model(self.model.input, last_layer.output, name='source_model')

# add a new fully connected layer
input_shape = self.model.layers[0].output_shape[1:]
x = Input(shape=input_shape, dtype='float32', name='input')
y = model_without_last_layer(x)

if new_model is None:
y = Dense(new_number_of_classes, activation=new_activation, name='new_dense_layer')(y)
else:
y = new_model(y)

# change self.model with fine_tuned model
self.model = Model(x, y)

# freeze the source model if freeze_source_model is True
self.model.get_layer('source_model').trainable = not freeze_source_model
2 changes: 1 addition & 1 deletion dcase_models/model/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def __init__(self, model=None, folder=None, metrics=['accuracy'], n_classes=10,

# CONV 2
y = Conv2D(48, filter_size_cnn, padding='valid', activation='relu', name='conv2')(y)
y = MaxPooling2D(pool_size=(2,2), strides=None, padding='valid', name='maxpool2')(y)
y = MaxPooling2D(pool_size=(4,2), strides=None, padding='valid', name='maxpool2')(y)
y = BatchNormalization(name='batchnorm2')(y)

# CONV 3
Expand Down
Binary file added tests/SB_CNN/ESC50/fold1/best_weights.hdf5
Binary file not shown.
1 change: 1 addition & 0 deletions tests/SB_CNN/ESC50/fold1/model.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"{\"class_name\": \"Model\", \"config\": {\"name\": \"model_1\", \"layers\": [{\"name\": \"input\", \"class_name\": \"InputLayer\", \"config\": {\"batch_input_shape\": [null, 64, 128], \"dtype\": \"float32\", \"sparse\": false, \"name\": \"input\"}, \"inbound_nodes\": []}, {\"name\": \"source_model\", \"class_name\": \"Model\", \"config\": {\"name\": \"source_model\", \"layers\": [{\"name\": \"input\", \"class_name\": \"InputLayer\", \"config\": {\"batch_input_shape\": [null, 64, 128], \"dtype\": \"float32\", \"sparse\": false, \"name\": \"input\"}, \"inbound_nodes\": []}, {\"name\": \"lambda\", \"class_name\": \"Lambda\", \"config\": {\"name\": \"lambda\", \"trainable\": true, \"function\": [\"4wEAAAAAAAAAAQAAAAQAAABTAAAAcwwAAAB0AKABfABkAaECUwApAk7p/////ykC2gFL2gtleHBh\\nbmRfZGltcykB2gF4qQByBQAAAPofLi4vZGNhc2VfbW9kZWxzL21vZGVsL21vZGVscy5wedoIPGxh\\nbWJkYT44AAAA8wAAAAA=\\n\", null, null], \"function_type\": \"lambda\", \"output_shape\": null, \"output_shape_type\": \"raw\", \"arguments\": {}}, \"inbound_nodes\": [[[\"input\", 0, 0, {}]]]}, {\"name\": \"conv1\", \"class_name\": \"Conv2D\", \"config\": {\"name\": \"conv1\", \"trainable\": true, \"filters\": 24, \"kernel_size\": [5, 5], \"strides\": [1, 1], \"padding\": \"valid\", \"data_format\": \"channels_last\", \"dilation_rate\": [1, 1], \"activation\": \"relu\", \"use_bias\": true, \"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"scale\": 1.0, \"mode\": \"fan_avg\", \"distribution\": \"uniform\", \"seed\": null}}, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"kernel_regularizer\": null, \"bias_regularizer\": null, \"activity_regularizer\": null, \"kernel_constraint\": null, \"bias_constraint\": null}, \"inbound_nodes\": [[[\"lambda\", 0, 0, {}]]]}, {\"name\": \"maxpool1\", \"class_name\": \"MaxPooling2D\", \"config\": {\"name\": \"maxpool1\", \"trainable\": true, \"pool_size\": [2, 2], \"padding\": \"valid\", \"strides\": [2, 2], \"data_format\": \"channels_last\"}, \"inbound_nodes\": [[[\"conv1\", 0, 0, {}]]]}, {\"name\": \"batchnorm1\", \"class_name\": \"BatchNormalization\", \"config\": {\"name\": \"batchnorm1\", \"trainable\": true, \"axis\": -1, \"momentum\": 0.99, \"epsilon\": 0.001, \"center\": true, \"scale\": true, \"beta_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"gamma_initializer\": {\"class_name\": \"Ones\", \"config\": {}}, \"moving_mean_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"moving_variance_initializer\": {\"class_name\": \"Ones\", \"config\": {}}, \"beta_regularizer\": null, \"gamma_regularizer\": null, \"beta_constraint\": null, \"gamma_constraint\": null}, \"inbound_nodes\": [[[\"maxpool1\", 0, 0, {}]]]}, {\"name\": \"conv2\", \"class_name\": \"Conv2D\", \"config\": {\"name\": \"conv2\", \"trainable\": true, \"filters\": 48, \"kernel_size\": [5, 5], \"strides\": [1, 1], \"padding\": \"valid\", \"data_format\": \"channels_last\", \"dilation_rate\": [1, 1], \"activation\": \"relu\", \"use_bias\": true, \"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"scale\": 1.0, \"mode\": \"fan_avg\", \"distribution\": \"uniform\", \"seed\": null}}, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"kernel_regularizer\": null, \"bias_regularizer\": null, \"activity_regularizer\": null, \"kernel_constraint\": null, \"bias_constraint\": null}, \"inbound_nodes\": [[[\"batchnorm1\", 0, 0, {}]]]}, {\"name\": \"maxpool2\", \"class_name\": \"MaxPooling2D\", \"config\": {\"name\": \"maxpool2\", \"trainable\": true, \"pool_size\": [4, 2], \"padding\": \"valid\", \"strides\": [4, 2], \"data_format\": \"channels_last\"}, \"inbound_nodes\": [[[\"conv2\", 0, 0, {}]]]}, {\"name\": \"batchnorm2\", \"class_name\": \"BatchNormalization\", \"config\": {\"name\": \"batchnorm2\", \"trainable\": true, \"axis\": -1, \"momentum\": 0.99, \"epsilon\": 0.001, \"center\": true, \"scale\": true, \"beta_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"gamma_initializer\": {\"class_name\": \"Ones\", \"config\": {}}, \"moving_mean_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"moving_variance_initializer\": {\"class_name\": \"Ones\", \"config\": {}}, \"beta_regularizer\": null, \"gamma_regularizer\": null, \"beta_constraint\": null, \"gamma_constraint\": null}, \"inbound_nodes\": [[[\"maxpool2\", 0, 0, {}]]]}, {\"name\": \"conv3\", \"class_name\": \"Conv2D\", \"config\": {\"name\": \"conv3\", \"trainable\": true, \"filters\": 48, \"kernel_size\": [5, 5], \"strides\": [1, 1], \"padding\": \"valid\", \"data_format\": \"channels_last\", \"dilation_rate\": [1, 1], \"activation\": \"relu\", \"use_bias\": true, \"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"scale\": 1.0, \"mode\": \"fan_avg\", \"distribution\": \"uniform\", \"seed\": null}}, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"kernel_regularizer\": null, \"bias_regularizer\": null, \"activity_regularizer\": null, \"kernel_constraint\": null, \"bias_constraint\": null}, \"inbound_nodes\": [[[\"batchnorm2\", 0, 0, {}]]]}, {\"name\": \"batchnorm3\", \"class_name\": \"BatchNormalization\", \"config\": {\"name\": \"batchnorm3\", \"trainable\": true, \"axis\": -1, \"momentum\": 0.99, \"epsilon\": 0.001, \"center\": true, \"scale\": true, \"beta_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"gamma_initializer\": {\"class_name\": \"Ones\", \"config\": {}}, \"moving_mean_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"moving_variance_initializer\": {\"class_name\": \"Ones\", \"config\": {}}, \"beta_regularizer\": null, \"gamma_regularizer\": null, \"beta_constraint\": null, \"gamma_constraint\": null}, \"inbound_nodes\": [[[\"conv3\", 0, 0, {}]]]}, {\"name\": \"flatten\", \"class_name\": \"Flatten\", \"config\": {\"name\": \"flatten\", \"trainable\": true, \"data_format\": \"channels_last\"}, \"inbound_nodes\": [[[\"batchnorm3\", 0, 0, {}]]]}, {\"name\": \"dropout1\", \"class_name\": \"Dropout\", \"config\": {\"name\": \"dropout1\", \"trainable\": true, \"rate\": 0.5, \"noise_shape\": null, \"seed\": null}, \"inbound_nodes\": [[[\"flatten\", 0, 0, {}]]]}, {\"name\": \"dense1\", \"class_name\": \"Dense\", \"config\": {\"name\": \"dense1\", \"trainable\": true, \"units\": 64, \"activation\": \"relu\", \"use_bias\": true, \"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"scale\": 1.0, \"mode\": \"fan_avg\", \"distribution\": \"uniform\", \"seed\": null}}, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"kernel_regularizer\": {\"class_name\": \"L1L2\", \"config\": {\"l1\": 0.0, \"l2\": 0.0010000000474974513}}, \"bias_regularizer\": {\"class_name\": \"L1L2\", \"config\": {\"l1\": 0.0, \"l2\": 0.0010000000474974513}}, \"activity_regularizer\": null, \"kernel_constraint\": null, \"bias_constraint\": null}, \"inbound_nodes\": [[[\"dropout1\", 0, 0, {}]]]}, {\"name\": \"dropout2\", \"class_name\": \"Dropout\", \"config\": {\"name\": \"dropout2\", \"trainable\": true, \"rate\": 0.5, \"noise_shape\": null, \"seed\": null}, \"inbound_nodes\": [[[\"dense1\", 0, 0, {}]]]}], \"input_layers\": [[\"input\", 0, 0]], \"output_layers\": [[\"dropout2\", 0, 0]]}, \"inbound_nodes\": [[[\"input\", 0, 0, {}]]]}, {\"name\": \"new_dense_layer\", \"class_name\": \"Dense\", \"config\": {\"name\": \"new_dense_layer\", \"trainable\": true, \"units\": 50, \"activation\": \"softmax\", \"use_bias\": true, \"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"scale\": 1.0, \"mode\": \"fan_avg\", \"distribution\": \"uniform\", \"seed\": null}}, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"kernel_regularizer\": null, \"bias_regularizer\": null, \"activity_regularizer\": null, \"kernel_constraint\": null, \"bias_constraint\": null}, \"inbound_nodes\": [[[\"source_model\", 1, 0, {}]]]}], \"input_layers\": [[\"input\", 0, 0]], \"output_layers\": [[\"new_dense_layer\", 0, 0]]}, \"keras_version\": \"2.2.4\", \"backend\": \"tensorflow\"}"
51 changes: 51 additions & 0 deletions tests/SB_CNN/ESC50/fold1/training.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
epoch,Acc,loss
0,0.03,7.502168061392648
1,0.0625,6.382974977039155
2,0.0925,5.609923143840971
3,0.1225,4.946143490019299
4,0.1275,4.51800890604655
5,0.14,4.206934458414714
6,0.17,3.9105675583794004
7,0.1825,3.74058198928833
8,0.185,3.5537690730321976
9,0.1975,3.4097133327665783
10,0.1975,3.3246297645568847
11,0.2025,3.1981849284399124
12,0.205,3.157173556373233
13,0.2075,3.0660635684785387
14,0.2125,3.041565242948986
15,0.2225,2.971737453823998
16,0.22,2.9743683887663344
17,0.2275,2.918078219095866
18,0.2225,2.9116986974080405
19,0.22,2.8902962466648647
20,0.23,2.8917558279491606
21,0.225,2.869637153262184
22,0.2325,2.869133186340332
23,0.2425,2.8532540253230505
24,0.2375,2.8584180604843867
25,0.235,2.833264215106056
26,0.235,2.8339362516857327
27,0.2325,2.8220349543435232
28,0.23,2.8212475331624347
29,0.2225,2.8232532464890254
30,0.2225,2.841775826045445
31,0.225,2.803494078318278
32,0.23,2.81758319627671
33,0.23,2.8031206031072706
34,0.2375,2.84076034228007
35,0.2375,2.8026808257330034
36,0.2375,2.798538010006859
37,0.2275,2.8218897683279853
38,0.2225,2.8118302486056375
39,0.2325,2.812475911095029
40,0.2325,2.794565626780192
41,0.2325,2.832269555046445
42,0.2225,2.8263108544122604
43,0.22,2.812968007950556
44,0.2175,2.815446391786848
45,0.23,2.7967070988246374
46,0.225,2.801809174673898
47,0.2325,2.8028654884156725
48,0.2375,2.802789167676653
49,0.2325,2.8161884684789746
Binary file modified tests/SB_CNN/UrbanSound8k/fold1/best_weights.hdf5
Binary file not shown.
Loading

0 comments on commit b8a5842

Please sign in to comment.