| """ |
| This function manages the general RNN architecture |
| """ |
| import os |
| import random |
|
|
| import numpy as np |
| from keras import backend as K |
| from keras.callbacks import EarlyStopping, TensorBoard |
|
|
| |
| IS_COLAB = (os.name == 'posix') |
| LOAD_DATA = not (os.name == 'posix') |
|
|
| if IS_COLAB: |
| from datetime import datetime |
| from packaging import version |
|
|
| |
| logdir = "logs/scalars/" + datetime.now().strftime("%Y%m%d-%H%M%S") |
| tensorboard_callback = TensorBoard(log_dir=logdir) |
|
|
|
|
| class RecurrentNeuralNetwork(object): |
| def __init__(self, seed): |
| """ |
| Seed - The seed used to initialize the weights |
| width, height, cells - used for defining the tensors used for the input images |
| loss, metrics, optimizer, dropout_rate - settings used for compiling the siamese model (e.g., 'Accuracy' and 'ADAM) |
| """ |
| K.clear_session() |
| self.seed = seed |
| self.initialize_seed() |
| self.model = None |
|
|
| def initialize_seed(self): |
| """ |
| Initialize seed all for environment |
| """ |
| os.environ['PYTHONHASHSEED'] = str(self.seed) |
| random.seed(self.seed) |
| np.random.seed(self.seed) |
|
|
| def _load_weights(self, weights_file): |
| """ |
| A function that attempts to load pre-existing weight files for the siamese model. If it succeeds then returns |
| True and updates the weights, otherwise False. |
| :return True if the file is already exists |
| """ |
| self.model.summary() |
| self.load_file = weights_file |
| if os.path.exists(weights_file): |
| print('Loading pre-existed weights file') |
| self.model.load_weights(weights_file) |
| return True |
| return False |
|
|
| def fit(self, weights_file, batch_size, epochs, patience, min_delta, x_train, y_train, x_val, y_val): |
| """ |
| Function for fitting the model. If the weights already exist, just return the summary of the model. Otherwise, |
| perform a whole train/validation/test split and train the model with the given parameters. |
| """ |
| |
| if not self._load_weights(weights_file=weights_file): |
| print('No such pre-existed weights file') |
| print('Beginning to fit the model') |
| if IS_COLAB: |
| callbacks = [ |
| tensorboard_callback, |
| EarlyStopping(monitor='val_loss', patience=patience, min_delta=min_delta) |
| ] |
| else: |
| callbacks = [ |
| EarlyStopping(monitor='val_loss', patience=patience, min_delta=min_delta) |
| ] |
| self.model.fit(x_train, |
| y_train, |
| batch_size=batch_size, |
| epochs=epochs, |
| callbacks=callbacks, |
| validation_data=(x_val, y_val)) |
| self.model.save_weights(self.load_file) |
| |
| loss, accuracy = self.model.evaluate(x_val, y_val, batch_size=batch_size) |
| print(f'Loss on Validation set: {loss}') |
| print(f'Accuracy on Validation set: {accuracy}') |
|
|
| def evaluate(self, x_test, y_test, batch_size): |
| """ |
| Function for evaluating the final model after training. |
| test_file - file path to the test file. |
| batch_size - the batch size used in training. |
| |
| Returns the loss and accuracy results. |
| """ |
| print(f'Available Metrics: {self.model.metrics_names}') |
| y_test = np.array(y_test, dtype='float64') |
| x_test[0] = np.array(x_test[0], dtype='float64') |
| x_test[1] = np.array(x_test[1], dtype='float64') |
| |
| loss, accuracy = self.model.evaluate(x_test, y_test, batch_size=batch_size) |
| return loss, accuracy |
|
|
| def predict(self, data): |
| return self.model.predict(data) |
|
|
|
|
| print('Loaded Successfully') |
|
|