diff --git a/README.md b/README.md index dcbe9e3..636dcc7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ # Machine-Learning: Real-Time-Object-Classification + +[![CML](https://github.com/Arief-AK/Machine-Learning-Real-Time-Object-Classification/actions/workflows/ci.yml/badge.svg)](https://github.com/Arief-AK/Machine-Learning-Real-Time-Object-Classification/actions/workflows/ci.yml) + Application of machine learning models to recognise objects from the [CIFAR-10](https://www.cs.toronto.edu/~kriz/cifar.html) dataset. This work uses the [TensorFlow](https://www.tensorflow.org/) framework to build, train, and deploy models to produce real-time object classifications. >[!NOTE] diff --git a/Train.py b/Train.py index d0d6e1b..7fa7243 100644 --- a/Train.py +++ b/Train.py @@ -6,13 +6,18 @@ from include.TensorModel import TensorModel from include.ModelProfiler import ModelProfiler -NUM_EPOCHS = 25 +NUM_EPOCHS = 5 BATCH_FITTING = 128 BATCH_PROFILING = [32, 64, 128] MODELS = ["base_model", "batch_norm_model", "batch_norm_model_sgd", "batch_norm_model_rmsprop"] USE_EXISTING_MODELS = True +SAVE_MODELS = True +SAVE_MODELS_AS_H5 = True +SAVE_MODELS_AS_KERAS = True +SAVE_MODELS_AS_SavedModel = True + def create_predicition_matrix(model_handler: TensorModel, visualiser: Visualiser, model, x_test, y_test, str_model): conf_matrix = model_handler.compute_confusion_matrix(model, x_test, y_test) visualiser.plot_confusion_matrix(conf_matrix, model_handler.get_class_names(), str_model) @@ -22,8 +27,6 @@ def create_predicition_matrix(model_handler: TensorModel, visualiser: Visualiser visualiser.plot_diagonal_confusion_matrix(diagonal_matrix, model_handler.get_class_names(), str_model) def train_model(model_name:str, model_handler: TensorModel, visualiser: Visualiser, logger: Logger, x_train, y_train, x_test, y_test, batch_size) -> tuple: - logger.info(f"Eager enabled: {tf.executing_eagerly()}") - # Check if model exists if USE_EXISTING_MODELS and os.path.exists(f"models/{model_name}.h5"): model = model = tf.keras.models.load_model(f"models/{model_name}.h5") @@ -38,7 +41,16 @@ def train_model(model_name:str, model_handler: TensorModel, visualiser: Visualis history = model.fit(x_train, y_train, epochs=NUM_EPOCHS, batch_size=batch_size, validation_data=(x_test, y_test)) test_loss, test_acc = model.evaluate(x_test, y_test) - model.save(f"models/{model_name}.h5") + + if SAVE_MODELS: + if SAVE_MODELS_AS_H5: + model.save(f"models/{model_name}.h5") + + if SAVE_MODELS_AS_KERAS: + model.save(f"models/{model_name}.keras") + + if SAVE_MODELS_AS_SavedModel: + model.export(f"models/{model_name}_saved_model") logger.info(f"Model accuracy: {test_acc * 100:.2f}%") visualiser.plot_training_history(history, model_name) @@ -76,14 +88,14 @@ def profile_models(model_acc_results:dict, visualiser: Visualiser, logger: Logge logger.info(f"Accuracy:{accuracy * 100:.2f}%\n") if __name__ == "__main__": - # Initialise variables + # # Initialise variables model_acc_results = {} - # Create a logger + # # Create a logger logger = Logger(__name__) logger.set_level(logging.INFO) - # Initialise visualiser + # # Initialise visualiser visualiser = Visualiser() # Initalise model handler diff --git a/images/Inference/base_model/base_model_128_inference_timings.png b/images/Inference/base_model/base_model_128_inference_timings.png index 5f1bfba..5a7cdbe 100644 Binary files a/images/Inference/base_model/base_model_128_inference_timings.png and b/images/Inference/base_model/base_model_128_inference_timings.png differ diff --git a/images/Inference/base_model/base_model_32_inference_timings.png b/images/Inference/base_model/base_model_32_inference_timings.png index 0623492..bbbba00 100644 Binary files a/images/Inference/base_model/base_model_32_inference_timings.png and b/images/Inference/base_model/base_model_32_inference_timings.png differ diff --git a/images/Inference/base_model/base_model_64_inference_timings.png b/images/Inference/base_model/base_model_64_inference_timings.png index a5c9075..d576546 100644 Binary files a/images/Inference/base_model/base_model_64_inference_timings.png and b/images/Inference/base_model/base_model_64_inference_timings.png differ diff --git a/images/Inference/batch_norm_model/batch_norm_model_128_inference_timings.png b/images/Inference/batch_norm_model/batch_norm_model_128_inference_timings.png index 5c9e6e9..cd52106 100644 Binary files a/images/Inference/batch_norm_model/batch_norm_model_128_inference_timings.png and b/images/Inference/batch_norm_model/batch_norm_model_128_inference_timings.png differ diff --git a/images/Inference/batch_norm_model/batch_norm_model_32_inference_timings.png b/images/Inference/batch_norm_model/batch_norm_model_32_inference_timings.png index d08e08e..7bf0f11 100644 Binary files a/images/Inference/batch_norm_model/batch_norm_model_32_inference_timings.png and b/images/Inference/batch_norm_model/batch_norm_model_32_inference_timings.png differ diff --git a/images/Inference/batch_norm_model/batch_norm_model_64_inference_timings.png b/images/Inference/batch_norm_model/batch_norm_model_64_inference_timings.png index 87c382e..5bfff4e 100644 Binary files a/images/Inference/batch_norm_model/batch_norm_model_64_inference_timings.png and b/images/Inference/batch_norm_model/batch_norm_model_64_inference_timings.png differ diff --git a/images/Inference/batch_norm_model_rmsprop/batch_norm_model_rmsprop_128_inference_timings.png b/images/Inference/batch_norm_model_rmsprop/batch_norm_model_rmsprop_128_inference_timings.png index c2b6c9c..aaeeeb3 100644 Binary files a/images/Inference/batch_norm_model_rmsprop/batch_norm_model_rmsprop_128_inference_timings.png and b/images/Inference/batch_norm_model_rmsprop/batch_norm_model_rmsprop_128_inference_timings.png differ diff --git a/images/Inference/batch_norm_model_rmsprop/batch_norm_model_rmsprop_32_inference_timings.png b/images/Inference/batch_norm_model_rmsprop/batch_norm_model_rmsprop_32_inference_timings.png index 511bc09..a921a8f 100644 Binary files a/images/Inference/batch_norm_model_rmsprop/batch_norm_model_rmsprop_32_inference_timings.png and b/images/Inference/batch_norm_model_rmsprop/batch_norm_model_rmsprop_32_inference_timings.png differ diff --git a/images/Inference/batch_norm_model_rmsprop/batch_norm_model_rmsprop_64_inference_timings.png b/images/Inference/batch_norm_model_rmsprop/batch_norm_model_rmsprop_64_inference_timings.png index 12957b0..a768093 100644 Binary files a/images/Inference/batch_norm_model_rmsprop/batch_norm_model_rmsprop_64_inference_timings.png and b/images/Inference/batch_norm_model_rmsprop/batch_norm_model_rmsprop_64_inference_timings.png differ diff --git a/images/Inference/batch_norm_model_sgd/batch_norm_model_sgd_128_inference_timings.png b/images/Inference/batch_norm_model_sgd/batch_norm_model_sgd_128_inference_timings.png index a1d681e..08ad5a4 100644 Binary files a/images/Inference/batch_norm_model_sgd/batch_norm_model_sgd_128_inference_timings.png and b/images/Inference/batch_norm_model_sgd/batch_norm_model_sgd_128_inference_timings.png differ diff --git a/images/Inference/batch_norm_model_sgd/batch_norm_model_sgd_32_inference_timings.png b/images/Inference/batch_norm_model_sgd/batch_norm_model_sgd_32_inference_timings.png index ca3b349..e91b12e 100644 Binary files a/images/Inference/batch_norm_model_sgd/batch_norm_model_sgd_32_inference_timings.png and b/images/Inference/batch_norm_model_sgd/batch_norm_model_sgd_32_inference_timings.png differ diff --git a/images/Inference/batch_norm_model_sgd/batch_norm_model_sgd_64_inference_timings.png b/images/Inference/batch_norm_model_sgd/batch_norm_model_sgd_64_inference_timings.png index 14c7f67..4db2449 100644 Binary files a/images/Inference/batch_norm_model_sgd/batch_norm_model_sgd_64_inference_timings.png and b/images/Inference/batch_norm_model_sgd/batch_norm_model_sgd_64_inference_timings.png differ diff --git a/images/Training/base_model/base_model_training_confusion_matrix.png b/images/Training/base_model/base_model_training_confusion_matrix.png index 48291af..0a33d86 100644 Binary files a/images/Training/base_model/base_model_training_confusion_matrix.png and b/images/Training/base_model/base_model_training_confusion_matrix.png differ diff --git a/images/Training/base_model/base_model_training_diagonal_confusion_matrix.png b/images/Training/base_model/base_model_training_diagonal_confusion_matrix.png index 7c16e73..0b0c716 100644 Binary files a/images/Training/base_model/base_model_training_diagonal_confusion_matrix.png and b/images/Training/base_model/base_model_training_diagonal_confusion_matrix.png differ diff --git a/images/Training/base_model/base_model_training_history.png b/images/Training/base_model/base_model_training_history.png index b3fe88a..ede9c1f 100644 Binary files a/images/Training/base_model/base_model_training_history.png and b/images/Training/base_model/base_model_training_history.png differ diff --git a/images/Training/batch_norm_model/batch_norm_model_training_confusion_matrix.png b/images/Training/batch_norm_model/batch_norm_model_training_confusion_matrix.png index 947b49d..8ce9333 100644 Binary files a/images/Training/batch_norm_model/batch_norm_model_training_confusion_matrix.png and b/images/Training/batch_norm_model/batch_norm_model_training_confusion_matrix.png differ diff --git a/images/Training/batch_norm_model/batch_norm_model_training_diagonal_confusion_matrix.png b/images/Training/batch_norm_model/batch_norm_model_training_diagonal_confusion_matrix.png index ec871ee..72c1346 100644 Binary files a/images/Training/batch_norm_model/batch_norm_model_training_diagonal_confusion_matrix.png and b/images/Training/batch_norm_model/batch_norm_model_training_diagonal_confusion_matrix.png differ diff --git a/images/Training/batch_norm_model/batch_norm_model_training_history.png b/images/Training/batch_norm_model/batch_norm_model_training_history.png index 6e85848..7ab7aaa 100644 Binary files a/images/Training/batch_norm_model/batch_norm_model_training_history.png and b/images/Training/batch_norm_model/batch_norm_model_training_history.png differ diff --git a/images/Training/batch_norm_model_rmsprop/batch_norm_model_rmsprop_training_confusion_matrix.png b/images/Training/batch_norm_model_rmsprop/batch_norm_model_rmsprop_training_confusion_matrix.png index 0deb965..b128fa1 100644 Binary files a/images/Training/batch_norm_model_rmsprop/batch_norm_model_rmsprop_training_confusion_matrix.png and b/images/Training/batch_norm_model_rmsprop/batch_norm_model_rmsprop_training_confusion_matrix.png differ diff --git a/images/Training/batch_norm_model_rmsprop/batch_norm_model_rmsprop_training_diagonal_confusion_matrix.png b/images/Training/batch_norm_model_rmsprop/batch_norm_model_rmsprop_training_diagonal_confusion_matrix.png index 6d81a6e..b296099 100644 Binary files a/images/Training/batch_norm_model_rmsprop/batch_norm_model_rmsprop_training_diagonal_confusion_matrix.png and b/images/Training/batch_norm_model_rmsprop/batch_norm_model_rmsprop_training_diagonal_confusion_matrix.png differ diff --git a/images/Training/batch_norm_model_rmsprop/batch_norm_model_rmsprop_training_history.png b/images/Training/batch_norm_model_rmsprop/batch_norm_model_rmsprop_training_history.png index d6bb336..46bf52c 100644 Binary files a/images/Training/batch_norm_model_rmsprop/batch_norm_model_rmsprop_training_history.png and b/images/Training/batch_norm_model_rmsprop/batch_norm_model_rmsprop_training_history.png differ diff --git a/images/Training/batch_norm_model_sgd/batch_norm_model_sgd_training_confusion_matrix.png b/images/Training/batch_norm_model_sgd/batch_norm_model_sgd_training_confusion_matrix.png index 3dfcdfe..a0c13ea 100644 Binary files a/images/Training/batch_norm_model_sgd/batch_norm_model_sgd_training_confusion_matrix.png and b/images/Training/batch_norm_model_sgd/batch_norm_model_sgd_training_confusion_matrix.png differ diff --git a/images/Training/batch_norm_model_sgd/batch_norm_model_sgd_training_diagonal_confusion_matrix.png b/images/Training/batch_norm_model_sgd/batch_norm_model_sgd_training_diagonal_confusion_matrix.png index f22e7b1..4ad1c0c 100644 Binary files a/images/Training/batch_norm_model_sgd/batch_norm_model_sgd_training_diagonal_confusion_matrix.png and b/images/Training/batch_norm_model_sgd/batch_norm_model_sgd_training_diagonal_confusion_matrix.png differ diff --git a/images/Training/batch_norm_model_sgd/batch_norm_model_sgd_training_history.png b/images/Training/batch_norm_model_sgd/batch_norm_model_sgd_training_history.png index 6d1050d..627bb41 100644 Binary files a/images/Training/batch_norm_model_sgd/batch_norm_model_sgd_training_history.png and b/images/Training/batch_norm_model_sgd/batch_norm_model_sgd_training_history.png differ diff --git a/images/augmented_sample_image.png b/images/augmented_sample_image.png index 309a28d..a1a795c 100644 Binary files a/images/augmented_sample_image.png and b/images/augmented_sample_image.png differ diff --git a/include/TensorModel.py b/include/TensorModel.py index 2fb6676..f302b3e 100644 --- a/include/TensorModel.py +++ b/include/TensorModel.py @@ -47,9 +47,13 @@ def load_data(self) -> tuple: def get_augmentation(self) -> tf.keras.Sequential: # Create a data augmentation layer data_augmentation = tf.keras.Sequential([ - tf.keras.layers.RandomFlip("horizontal"), # Randomly flip images horizontally - tf.keras.layers.RandomRotation(0.1), # Randomly rotate image up to 10% - tf.keras.layers.RandomZoom(0.1) # Randomly zoom image up to 10% + tf.keras.layers.RandomFlip("horizontal"), # Randomly flip images horizontally + tf.keras.layers.RandomRotation(0.1), # Randomly rotate image up to 10% + tf.keras.layers.RandomZoom(0.1), # Randomly zoom image up to 10% + tf.keras.layers.RandomContrast(0.1), # Randomly adjust contrast up to 10% + tf.keras.layers.Lambda(lambda x: tf.image.random_brightness(x, max_delta=0.2)), # Randomly adjust brightness + tf.keras.layers.Lambda(lambda x: tf.image.random_crop(x, size=[tf.shape(x)[0], tf.shape(x)[1] - 8, tf.shape(x)[2] - 8, tf.shape(x)[3]])), # Cutout augmentation + tf.keras.layers.Lambda(lambda x: 0.5 * x + 0.5 * tf.roll(x, shift=1, axis=0)) # MixUp augmentation (approximate) ]) return data_augmentation diff --git a/models/base_model.h5 b/models/base_model.h5 index 978d665..7fb26da 100644 Binary files a/models/base_model.h5 and b/models/base_model.h5 differ diff --git a/models/base_model.keras b/models/base_model.keras new file mode 100644 index 0000000..bcf927f Binary files /dev/null and b/models/base_model.keras differ diff --git a/models/base_model_saved_model/fingerprint.pb b/models/base_model_saved_model/fingerprint.pb new file mode 100644 index 0000000..f9331d4 --- /dev/null +++ b/models/base_model_saved_model/fingerprint.pb @@ -0,0 +1 @@ +ݙٝx (2 \ No newline at end of file diff --git a/models/base_model_saved_model/saved_model.pb b/models/base_model_saved_model/saved_model.pb new file mode 100644 index 0000000..bc79688 Binary files /dev/null and b/models/base_model_saved_model/saved_model.pb differ diff --git a/models/base_model_saved_model/variables/variables.data-00000-of-00001 b/models/base_model_saved_model/variables/variables.data-00000-of-00001 new file mode 100644 index 0000000..01076dc Binary files /dev/null and b/models/base_model_saved_model/variables/variables.data-00000-of-00001 differ diff --git a/models/base_model_saved_model/variables/variables.index b/models/base_model_saved_model/variables/variables.index new file mode 100644 index 0000000..61b9f9c Binary files /dev/null and b/models/base_model_saved_model/variables/variables.index differ diff --git a/models/batch_norm_model.h5 b/models/batch_norm_model.h5 index 006f174..b673c91 100644 Binary files a/models/batch_norm_model.h5 and b/models/batch_norm_model.h5 differ diff --git a/models/batch_norm_model.keras b/models/batch_norm_model.keras new file mode 100644 index 0000000..3c3a2ea Binary files /dev/null and b/models/batch_norm_model.keras differ diff --git a/models/batch_norm_model_rmsprop.h5 b/models/batch_norm_model_rmsprop.h5 index 37f8e43..6f615b2 100644 Binary files a/models/batch_norm_model_rmsprop.h5 and b/models/batch_norm_model_rmsprop.h5 differ diff --git a/models/batch_norm_model_rmsprop.keras b/models/batch_norm_model_rmsprop.keras new file mode 100644 index 0000000..4a28d2a Binary files /dev/null and b/models/batch_norm_model_rmsprop.keras differ diff --git a/models/batch_norm_model_rmsprop_saved_model/fingerprint.pb b/models/batch_norm_model_rmsprop_saved_model/fingerprint.pb new file mode 100644 index 0000000..09a7d67 --- /dev/null +++ b/models/batch_norm_model_rmsprop_saved_model/fingerprint.pb @@ -0,0 +1 @@ +қuﳆЭ8 گւ(Ȅ=2 \ No newline at end of file diff --git a/models/batch_norm_model_rmsprop_saved_model/saved_model.pb b/models/batch_norm_model_rmsprop_saved_model/saved_model.pb new file mode 100644 index 0000000..f81ea64 Binary files /dev/null and b/models/batch_norm_model_rmsprop_saved_model/saved_model.pb differ diff --git a/models/batch_norm_model_rmsprop_saved_model/variables/variables.data-00000-of-00001 b/models/batch_norm_model_rmsprop_saved_model/variables/variables.data-00000-of-00001 new file mode 100644 index 0000000..2adb480 Binary files /dev/null and b/models/batch_norm_model_rmsprop_saved_model/variables/variables.data-00000-of-00001 differ diff --git a/models/batch_norm_model_rmsprop_saved_model/variables/variables.index b/models/batch_norm_model_rmsprop_saved_model/variables/variables.index new file mode 100644 index 0000000..2a8304e Binary files /dev/null and b/models/batch_norm_model_rmsprop_saved_model/variables/variables.index differ diff --git a/models/batch_norm_model_saved_model/fingerprint.pb b/models/batch_norm_model_saved_model/fingerprint.pb new file mode 100644 index 0000000..6e1f99a --- /dev/null +++ b/models/batch_norm_model_saved_model/fingerprint.pb @@ -0,0 +1 @@ +̸ҕξ$\ 왉ŏܐ(֓ɻ[2 \ No newline at end of file diff --git a/models/batch_norm_model_saved_model/saved_model.pb b/models/batch_norm_model_saved_model/saved_model.pb new file mode 100644 index 0000000..1bcbc0b Binary files /dev/null and b/models/batch_norm_model_saved_model/saved_model.pb differ diff --git a/models/batch_norm_model_saved_model/variables/variables.data-00000-of-00001 b/models/batch_norm_model_saved_model/variables/variables.data-00000-of-00001 new file mode 100644 index 0000000..38c504d Binary files /dev/null and b/models/batch_norm_model_saved_model/variables/variables.data-00000-of-00001 differ diff --git a/models/batch_norm_model_saved_model/variables/variables.index b/models/batch_norm_model_saved_model/variables/variables.index new file mode 100644 index 0000000..14c8c47 Binary files /dev/null and b/models/batch_norm_model_saved_model/variables/variables.index differ diff --git a/models/batch_norm_model_sgd.h5 b/models/batch_norm_model_sgd.h5 index 7c6f1d3..50bae93 100644 Binary files a/models/batch_norm_model_sgd.h5 and b/models/batch_norm_model_sgd.h5 differ diff --git a/models/batch_norm_model_sgd.keras b/models/batch_norm_model_sgd.keras new file mode 100644 index 0000000..db1978b Binary files /dev/null and b/models/batch_norm_model_sgd.keras differ diff --git a/models/batch_norm_model_sgd_saved_model/fingerprint.pb b/models/batch_norm_model_sgd_saved_model/fingerprint.pb new file mode 100644 index 0000000..e0a498b --- /dev/null +++ b/models/batch_norm_model_sgd_saved_model/fingerprint.pb @@ -0,0 +1 @@ +ЂՎp͝ H(ˌ󄴓2 \ No newline at end of file diff --git a/models/batch_norm_model_sgd_saved_model/saved_model.pb b/models/batch_norm_model_sgd_saved_model/saved_model.pb new file mode 100644 index 0000000..0af99c3 Binary files /dev/null and b/models/batch_norm_model_sgd_saved_model/saved_model.pb differ diff --git a/models/batch_norm_model_sgd_saved_model/variables/variables.data-00000-of-00001 b/models/batch_norm_model_sgd_saved_model/variables/variables.data-00000-of-00001 new file mode 100644 index 0000000..dbca7ef Binary files /dev/null and b/models/batch_norm_model_sgd_saved_model/variables/variables.data-00000-of-00001 differ diff --git a/models/batch_norm_model_sgd_saved_model/variables/variables.index b/models/batch_norm_model_sgd_saved_model/variables/variables.index new file mode 100644 index 0000000..2dd3669 Binary files /dev/null and b/models/batch_norm_model_sgd_saved_model/variables/variables.index differ