|
|
@ -2,11 +2,10 @@ import keras_tuner |
|
|
import numpy as np |
|
|
import numpy as np |
|
|
import pandas as pd |
|
|
import pandas as pd |
|
|
import shutil |
|
|
import shutil |
|
|
import os |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from keras import Input |
|
|
from keras.src.metrics import F1Score |
|
|
from keras.src.metrics import F1Score |
|
|
from pandas import ExcelWriter |
|
|
from pandas import ExcelWriter |
|
|
import keras_tuner as kt |
|
|
|
|
|
from tensorflow.keras.models import Sequential |
|
|
from tensorflow.keras.models import Sequential |
|
|
from tensorflow.keras.layers import LSTM, Dense, Dropout, Bidirectional,GRU |
|
|
from tensorflow.keras.layers import LSTM, Dense, Dropout, Bidirectional,GRU |
|
|
from tensorflow.keras.optimizers import Adam |
|
|
from tensorflow.keras.optimizers import Adam |
|
|
@ -14,7 +13,7 @@ from tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping |
|
|
from keras_tuner import RandomSearch |
|
|
from keras_tuner import RandomSearch |
|
|
from sklearn.metrics import accuracy_score |
|
|
from sklearn.metrics import accuracy_score |
|
|
|
|
|
|
|
|
epochs = 30 |
|
|
|
|
|
|
|
|
epochs = 50 |
|
|
model_type_gru = 'GRU' |
|
|
model_type_gru = 'GRU' |
|
|
model_type_lstm = 'LSTM' |
|
|
model_type_lstm = 'LSTM' |
|
|
model_type_bilstm = 'BiLSTM' |
|
|
model_type_bilstm = 'BiLSTM' |
|
|
@ -144,10 +143,10 @@ def train_models(user_data, user_data_val, sequence_lengths, tuner_dir="./workin |
|
|
|
|
|
|
|
|
# === Training & Validation === |
|
|
# === Training & Validation === |
|
|
def train_models_v2(user_data, user_data_val, sequence_length, model_type): |
|
|
def train_models_v2(user_data, user_data_val, sequence_length, model_type): |
|
|
tuner_dir = "./working/tuner" |
|
|
|
|
|
|
|
|
tuner_dir = "./working/tuner/"+model_type |
|
|
|
|
|
|
|
|
early_stopping = EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True) |
|
|
|
|
|
lr_scheduler = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=2) |
|
|
|
|
|
|
|
|
early_stopping = EarlyStopping(monitor='val_f1', patience=3, restore_best_weights=True) |
|
|
|
|
|
lr_scheduler = ReduceLROnPlateau(monitor='val_f1', factor=0.5, patience=2) |
|
|
|
|
|
|
|
|
shutil.rmtree(tuner_dir, ignore_errors=True) |
|
|
shutil.rmtree(tuner_dir, ignore_errors=True) |
|
|
|
|
|
|
|
|
@ -157,41 +156,39 @@ def train_models_v2(user_data, user_data_val, sequence_length, model_type): |
|
|
n_features = x.shape[2] |
|
|
n_features = x.shape[2] |
|
|
users = list(user_data.keys()) |
|
|
users = list(user_data.keys()) |
|
|
|
|
|
|
|
|
|
|
|
y_val = np.array(y_val).reshape(-1, 1) |
|
|
|
|
|
y = np.array(y).reshape(-1, 1) |
|
|
|
|
|
|
|
|
def build_model(hp): |
|
|
def build_model(hp): |
|
|
|
|
|
units_hp = hp.Int('units', 2, 256, step=2, sampling="log") |
|
|
|
|
|
|
|
|
model = Sequential() |
|
|
model = Sequential() |
|
|
|
|
|
model.add(Input((sequence_length, n_features))) |
|
|
if model_type==model_type_bilstm: |
|
|
if model_type==model_type_bilstm: |
|
|
model.add(Bidirectional(LSTM(units=hp.Int('units', 32, 256, step=2), |
|
|
|
|
|
input_shape=(sequence_length, n_features)))) |
|
|
|
|
|
|
|
|
model.add(Bidirectional(LSTM(units=units_hp))) |
|
|
if model_type==model_type_lstm: |
|
|
if model_type==model_type_lstm: |
|
|
model.add(LSTM(units=hp.Int('units', 32, 256, step=2), |
|
|
|
|
|
input_shape=(sequence_length, n_features))) |
|
|
|
|
|
|
|
|
model.add(LSTM(units=units_hp)) |
|
|
if model_type==model_type_gru: |
|
|
if model_type==model_type_gru: |
|
|
model.add(GRU(units=hp.Int('units', 32, 256, step=2), |
|
|
|
|
|
input_shape=(sequence_length, n_features))) |
|
|
|
|
|
|
|
|
model.add(GRU(units=units_hp)) |
|
|
model.add(Dropout(hp.Float('dropout_rate', 0.1, 0.5, step=0.1))) |
|
|
model.add(Dropout(hp.Float('dropout_rate', 0.1, 0.5, step=0.1))) |
|
|
model.add(Dense(len(users), activation='softmax')) |
|
|
model.add(Dense(len(users), activation='softmax')) |
|
|
model.compile( |
|
|
model.compile( |
|
|
optimizer=Adam(learning_rate=hp.Choice('learning_rate', [1e-2, 1e-3, 1e-4])), |
|
|
optimizer=Adam(learning_rate=hp.Choice('learning_rate', [1e-2, 1e-3, 1e-4])), |
|
|
loss='sparse_categorical_crossentropy', |
|
|
loss='sparse_categorical_crossentropy', |
|
|
metrics=['accuracy'] |
|
|
|
|
|
|
|
|
metrics=[F1Score(name='f1', average='weighted')] |
|
|
) |
|
|
) |
|
|
return model |
|
|
return model |
|
|
|
|
|
|
|
|
tuner = RandomSearch( |
|
|
tuner = RandomSearch( |
|
|
build_model, |
|
|
build_model, |
|
|
objective='val_loss', |
|
|
|
|
|
max_trials=100, |
|
|
|
|
|
|
|
|
objective=keras_tuner.Objective("val_f1", direction="max"), |
|
|
|
|
|
max_trials=120, |
|
|
directory=tuner_dir, |
|
|
directory=tuner_dir, |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
tuner.search(x, y, epochs=epochs, validation_data=(x_val, y_val), |
|
|
tuner.search(x, y, epochs=epochs, validation_data=(x_val, y_val), |
|
|
callbacks=[early_stopping, lr_scheduler]) |
|
|
callbacks=[early_stopping, lr_scheduler]) |
|
|
|
|
|
|
|
|
best_hps = tuner.get_best_hyperparameters(1)[0] |
|
|
|
|
|
best_model = tuner.hypermodel.build(best_hps) |
|
|
|
|
|
best_model.fit(x, y, epochs=epochs, validation_data=(x_val, y_val), |
|
|
|
|
|
callbacks=[early_stopping, lr_scheduler]) |
|
|
|
|
|
return best_model |
|
|
|
|
|
|
|
|
return tuner.get_best_models(num_models=1)[0] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# === Evaluation === |
|
|
# === Evaluation === |
|
|
|