def __init__(self, dim=2, model_path=None, input_size=13, depth=3, checkpoint=True): self.model_exists = False self.checkpoint = checkpoint self.model_path = str(model_path) self.use_cache = True self.epochs = 600 print(self.model_path) self.model_name = "{}-epochs-{}-layers-sigmoid-3D-{}-inputSize-model".format( self.epochs, depth, input_size) if model_path == None: self.model_path = os.path.dirname( __file__) + "/../cache/model/" + datetime.datetime.now( ).strftime("%Y%m%d-%H%M%S") + "-" + self.model_name self.use_cache = False self.optimizer = keras.optimizers.Adam(learning_rate=0.002) self.loss_fn = keras.losses.MeanSquaredError() self.validation_metric = keras.metrics.MeanSquaredError() # tensorboard initialization logs_path = os.path.dirname( __file__) + "/../cachesdasdasd/logs/fit/" + datetime.datetime.now( ).strftime("%Y%m%d-%H%M%S") + "-" + self.model_name self.train_summary_writer = tf.summary.create_file_writer(logs_path + "/train") self.val_summary_writer = tf.summary.create_file_writer(logs_path + "/validation") # model definition self.model = keras.Sequential() self.model.add(keras.Input(input_size)) # hidden layers for i in range(depth): self.model.add( keras.layers.Dense(6, activation=keras.activations.sigmoid)) # output self.model.add(keras.layers.Dense(1)) self.model.compile(loss=self.loss_fn) # quick hack to check if hdf5 is in the path or not, if not we are defining a new model if IO.exists(self.model_path) and self.use_cache and "hdf5" in str( model_path): IO.debug("Using the checkpoint!") self.model_exists = True self.model.load_weights(model_path)
def fit(self, x, y, batch_size) -> None: # first we need to convert to tensorflow tensors x = tf.convert_to_tensor(x, dtype=tf.float32) y = tf.convert_to_tensor(y, dtype=tf.float32) # if self.model_exists: # IO.debug("model already exists, so no need to train!") # return self.model.summary() # Prepare the validation dataset. # Reserve 10,000 samples for validation. # Validation set and the training set should be disjoint sets. validation_split = int(0.2 * x.shape[0]) x_val = x[-validation_split:] y_val = y[-validation_split:] val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val)) val_dataset = val_dataset.batch(64) x_train = x[:-validation_split] y_train = y[:-validation_split] # divide into training batches of size batch_size train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)) train_dataset = train_dataset.shuffle( buffer_size=1024).batch(batch_size) epochs = 600 # create path for saving weights for epoch in range(epochs): time_start = time.time_ns() # train over batches loss_value = 0 for step, (x_batch_train, y_batch_train) in enumerate(train_dataset): loss = self.train_step(neighbourhood=x_batch_train, pressure=y_batch_train).numpy() if step % 100 == 0: IO.debug("Epoch: {:03d} \t Loss: {:01.5f}".format( epoch, loss), end="\r") loss_value += loss # get validation error for (val_x, val_y) in val_dataset: predicted_pressure = self.model(val_x, training=False) self.validation_metric.update_state(val_y, predicted_pressure) # display loss and validation_error information val_error = self.validation_metric.result() deug_info = "{} Epoch: {:03d} \t Loss: {:01.5f} \t Validation error {:01.5f}" IO.debug( deug_info.format( datetime.datetime.now().strftime("%Y/%m/%d-%H:%M:%S"), epoch, loss_value / step, val_error)) # save the information to the tensorboard with self.val_summary_writer.as_default(): tf.summary.scalar("epoch_loss", val_error.numpy(), step=epoch) with self.train_summary_writer.as_default(): tf.summary.scalar("epoch_loss", loss_value / step, step=epoch) # reset the validation metric and loss at the end of each epoch self.validation_metric.reset_states() # save model at the of each epoch, to a file specified as in checkpoint_path checkpoint_path = self.model_path + "/weights.epoch{:04d}.hdf5".format( epoch) self.model.save_weights(checkpoint_path) time_end = time.time_ns() print("Epoch took: {:01.5f} minutes.".format( (time_end - time_start) / (1e9 * 60))) print("Saved model in: {} ".format(checkpoint_path)) return None