-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhypermodel.py
More file actions
133 lines (109 loc) · 4.11 KB
/
Copy pathhypermodel.py
File metadata and controls
133 lines (109 loc) · 4.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# @author: lucasmiranda42
"""
Transfer-learning based hypermodel for the covidX_transfer project
To be used under the keras-tuner framework
"""
from tensorflow import keras
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras import Model
from tensorflow.keras.losses import categorical_crossentropy
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import layers
from tensorflow.keras.applications.nasnet import NASNetLarge
from kerastuner import *
import tensorflow as tf
import datetime
log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)
class NASnet_transfer(HyperModel):
def __init__(self, input_shape, fine_tune):
self.input_shape = input_shape
self.finetune = fine_tune
def build(self, hp):
pretrained_model = NASNetLarge(
input_shape=(331, 331, 3), include_top=False, weights="imagenet"
)
if not self.finetune:
for layer in pretrained_model.layers:
layer.trainable = False
# Hyperparameters to tune
Dense_layers = hp.Int(
"number of dense layers", min_value=0, max_value=2, step=1, default=0
)
Dense_units = hp.Int(
"dense units of the first dense layer",
min_value=128,
max_value=512,
step=32,
default=256,
)
DROPOUT_RATE = hp.Float(
"dropout_rate", min_value=0.0, max_value=0.5, default=0.25, step=0.05
)
last_layer = pretrained_model.get_layer(pretrained_model.layers[-1].name)
last_output = last_layer.output
# Adds a global average pooling to reduce the dimensionality of the output
x = layers.GlobalAveragePooling2D()(last_output)
# Add a fully connected layer with 1,024 hidden units and ReLU activation
x = layers.Dense(Dense_units, activation="relu")(x)
# Tries out adding more dense layers
for i in range(Dense_layers):
x = layers.Dense(Dense_units / (2 if i == 0 else 4 * i), activation="relu")(
x
)
# Add a tunable dropout rate
x = layers.Dropout(DROPOUT_RATE)(x)
# Add a final sigmoid layer for classification
x = layers.Dense(3, activation="softmax")(x)
model = Model(pretrained_model.input, x)
print(model.summary())
model.compile(
loss=categorical_crossentropy,
optimizer=Adam(
lr=hp.Float(
"learning_rate",
min_value=1e-4,
max_value=1e-2,
sampling="LOG",
default=1e-3,
),
),
metrics=[
keras.metrics.TruePositives(),
keras.metrics.FalsePositives(),
keras.metrics.TrueNegatives(),
keras.metrics.FalseNegatives(),
"categorical_accuracy",
],
)
return model
def tune_search(train, test, fine_tune, project_name, verb, bayopt_trials):
"""Define the search space using keras-tuner and bayesian optimization"""
hypermodel = NASnet_transfer(input_shape=(331, 331, 3), fine_tune=fine_tune)
tuner = BayesianOptimization(
hypermodel,
max_trials=bayopt_trials,
executions_per_trial=1,
seed=42,
objective="val_categorical_accuracy",
directory="BayesianOptx",
project_name=project_name,
distribution_strategy=tf.distribute.MirroredStrategy(),
)
if verb == 2:
print(tuner.search_space_summary())
tuner.search(
train,
epochs=30,
validation_data=(test),
verbose=2,
callbacks=[EarlyStopping("val_loss", patience=3), tensorboard_callback],
)
if verb == 2:
print(tuner.results_summary())
return (
tuner.get_best_models(num_models=bayopt_trials-1),
tuner.get_best_hyperparameters(num_trials=1),
)
### TODO:
### 1) Revise metrics and weighted loss for class imbalance correction