diff --git "a/Models/Final_EfficientNetB3_Code.ipynb" "b/Models/Final_EfficientNetB3_Code.ipynb"
new file mode 100644--- /dev/null
+++ "b/Models/Final_EfficientNetB3_Code.ipynb"
@@ -0,0 +1,1779 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# EfficientNetB3 Model Training Process\n",
+ "### Training an EfficientNetB3 model to classify between Real and AI generated images.\n",
+ "### Model Developer: Tesneem Essa || Assisted by: Keira James, Georgios Ioannou\n",
+ "### Dataset Created and Cleaned by: Farhikhta Farzan\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Loading Libraries \n",
+ "### We begin by first loading in the necessary libraries. The training will be done using the TensorFlow Keras Application."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2024-11-23T22:47:16.473884Z",
+ "iopub.status.busy": "2024-11-23T22:47:16.473521Z",
+ "iopub.status.idle": "2024-11-23T22:47:29.779636Z",
+ "shell.execute_reply": "2024-11-23T22:47:29.778442Z",
+ "shell.execute_reply.started": "2024-11-23T22:47:16.473852Z"
+ },
+ "trusted": true
+ },
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "WARNING: Logging before InitGoogle() is written to STDERR\n",
+ "E0000 00:00:1732402042.329575 13 common_lib.cc:798] Could not set metric server port: INVALID_ARGUMENT: Could not find SliceBuilder port 8471 in any of the 0 ports provided in `tpu_process_addresses`=\"local\"\n",
+ "=== Source Location Trace: ===\n",
+ "learning/45eac/tfrc/runtime/common_lib.cc:479\n",
+ "D1123 22:47:22.337726001 13 config.cc:196] gRPC EXPERIMENT call_status_override_on_cancellation OFF (default:OFF)\n",
+ "D1123 22:47:22.337739399 13 config.cc:196] gRPC EXPERIMENT call_v3 OFF (default:OFF)\n",
+ "D1123 22:47:22.337742644 13 config.cc:196] gRPC EXPERIMENT canary_client_privacy ON (default:ON)\n",
+ "D1123 22:47:22.337744892 13 config.cc:196] gRPC EXPERIMENT capture_base_context ON (default:ON)\n",
+ "D1123 22:47:22.337747462 13 config.cc:196] gRPC EXPERIMENT client_idleness ON (default:ON)\n",
+ "D1123 22:47:22.337749715 13 config.cc:196] gRPC EXPERIMENT client_privacy ON (default:ON)\n",
+ "D1123 22:47:22.337752001 13 config.cc:196] gRPC EXPERIMENT dapper_request_wire_size OFF (default:OFF)\n",
+ "D1123 22:47:22.337754202 13 config.cc:196] gRPC EXPERIMENT empty_experiment OFF (default:OFF)\n",
+ "D1123 22:47:22.337756362 13 config.cc:196] gRPC EXPERIMENT event_engine_client OFF (default:OFF)\n",
+ "D1123 22:47:22.337758512 13 config.cc:196] gRPC EXPERIMENT event_engine_dns ON (default:ON)\n",
+ "D1123 22:47:22.337760766 13 config.cc:196] gRPC EXPERIMENT event_engine_listener ON (default:ON)\n",
+ "D1123 22:47:22.337762920 13 config.cc:196] gRPC EXPERIMENT free_large_allocator OFF (default:OFF)\n",
+ "D1123 22:47:22.337765103 13 config.cc:196] gRPC EXPERIMENT google_no_envelope_resolver OFF (default:OFF)\n",
+ "D1123 22:47:22.337767250 13 config.cc:196] gRPC EXPERIMENT http2_stats_fix OFF (default:OFF)\n",
+ "D1123 22:47:22.337769399 13 config.cc:196] gRPC EXPERIMENT keepalive_fix OFF (default:OFF)\n",
+ "D1123 22:47:22.337771579 13 config.cc:196] gRPC EXPERIMENT keepalive_server_fix ON (default:ON)\n",
+ "D1123 22:47:22.337773867 13 config.cc:196] gRPC EXPERIMENT loas_do_not_prefer_rekey_next_protocol OFF (default:OFF)\n",
+ "D1123 22:47:22.337776070 13 config.cc:196] gRPC EXPERIMENT loas_prod_to_cloud_prefer_pfs_ciphers OFF (default:OFF)\n",
+ "D1123 22:47:22.337778232 13 config.cc:196] gRPC EXPERIMENT monitoring_experiment ON (default:ON)\n",
+ "D1123 22:47:22.337780435 13 config.cc:196] gRPC EXPERIMENT multiping OFF (default:OFF)\n",
+ "D1123 22:47:22.337782590 13 config.cc:196] gRPC EXPERIMENT peer_state_based_framing OFF (default:OFF)\n",
+ "D1123 22:47:22.337784788 13 config.cc:196] gRPC EXPERIMENT pending_queue_cap ON (default:ON)\n",
+ "D1123 22:47:22.337787030 13 config.cc:196] gRPC EXPERIMENT pick_first_happy_eyeballs ON (default:ON)\n",
+ "D1123 22:47:22.337789232 13 config.cc:196] gRPC EXPERIMENT promise_based_client_call OFF (default:OFF)\n",
+ "D1123 22:47:22.337791311 13 config.cc:196] gRPC EXPERIMENT promise_based_inproc_transport OFF (default:OFF)\n",
+ "D1123 22:47:22.337793441 13 config.cc:196] gRPC EXPERIMENT promise_based_server_call OFF (default:OFF)\n",
+ "D1123 22:47:22.337795652 13 config.cc:196] gRPC EXPERIMENT registered_method_lookup_in_transport ON (default:ON)\n",
+ "D1123 22:47:22.337797840 13 config.cc:196] gRPC EXPERIMENT rfc_max_concurrent_streams ON (default:ON)\n",
+ "D1123 22:47:22.337800093 13 config.cc:196] gRPC EXPERIMENT round_robin_delegate_to_pick_first ON (default:ON)\n",
+ "D1123 22:47:22.337803409 13 config.cc:196] gRPC EXPERIMENT rstpit OFF (default:OFF)\n",
+ "D1123 22:47:22.337805666 13 config.cc:196] gRPC EXPERIMENT schedule_cancellation_over_write OFF (default:OFF)\n",
+ "D1123 22:47:22.337807972 13 config.cc:196] gRPC EXPERIMENT server_privacy ON (default:ON)\n",
+ "D1123 22:47:22.337810323 13 config.cc:196] gRPC EXPERIMENT tcp_frame_size_tuning OFF (default:OFF)\n",
+ "D1123 22:47:22.337812495 13 config.cc:196] gRPC EXPERIMENT tcp_rcv_lowat OFF (default:OFF)\n",
+ "D1123 22:47:22.337814628 13 config.cc:196] gRPC EXPERIMENT trace_record_callops OFF (default:OFF)\n",
+ "D1123 22:47:22.337816755 13 config.cc:196] gRPC EXPERIMENT unconstrained_max_quota_buffer_size OFF (default:OFF)\n",
+ "D1123 22:47:22.337818853 13 config.cc:196] gRPC EXPERIMENT v3_backend_metric_filter OFF (default:OFF)\n",
+ "D1123 22:47:22.337820994 13 config.cc:196] gRPC EXPERIMENT v3_channel_idle_filters ON (default:ON)\n",
+ "D1123 22:47:22.337823227 13 config.cc:196] gRPC EXPERIMENT v3_compression_filter ON (default:ON)\n",
+ "D1123 22:47:22.337825358 13 config.cc:196] gRPC EXPERIMENT v3_server_auth_filter OFF (default:OFF)\n",
+ "D1123 22:47:22.337827485 13 config.cc:196] gRPC EXPERIMENT work_serializer_clears_time_cache OFF (default:OFF)\n",
+ "D1123 22:47:22.337829573 13 config.cc:196] gRPC EXPERIMENT work_serializer_dispatch OFF (default:OFF)\n",
+ "D1123 22:47:22.337831714 13 config.cc:196] gRPC EXPERIMENT write_size_cap ON (default:ON)\n",
+ "D1123 22:47:22.337833892 13 config.cc:196] gRPC EXPERIMENT write_size_policy ON (default:ON)\n",
+ "D1123 22:47:22.337836100 13 config.cc:196] gRPC EXPERIMENT wrr_delegate_to_pick_first ON (default:ON)\n",
+ "I1123 22:47:22.337989542 13 ev_epoll1_linux.cc:123] grpc epoll fd: 59\n",
+ "D1123 22:47:22.338000410 13 ev_posix.cc:113] Using polling engine: epoll1\n",
+ "D1123 22:47:22.348136202 13 lb_policy_registry.cc:46] registering LB policy factory for \"priority_experimental\"\n",
+ "D1123 22:47:22.348146322 13 lb_policy_registry.cc:46] registering LB policy factory for \"outlier_detection_experimental\"\n",
+ "D1123 22:47:22.348153722 13 lb_policy_registry.cc:46] registering LB policy factory for \"weighted_target_experimental\"\n",
+ "D1123 22:47:22.348156630 13 lb_policy_registry.cc:46] registering LB policy factory for \"pick_first\"\n",
+ "D1123 22:47:22.348159633 13 lb_policy_registry.cc:46] registering LB policy factory for \"round_robin\"\n",
+ "D1123 22:47:22.348162361 13 lb_policy_registry.cc:46] registering LB policy factory for \"weighted_round_robin\"\n",
+ "D1123 22:47:22.348187820 13 lb_policy_registry.cc:46] registering LB policy factory for \"grpclb\"\n",
+ "D1123 22:47:22.348201432 13 dns_resolver_plugin.cc:43] Using EventEngine dns resolver\n",
+ "D1123 22:47:22.348216133 13 lb_policy_registry.cc:46] registering LB policy factory for \"rls_experimental\"\n",
+ "D1123 22:47:22.348235256 13 lb_policy_registry.cc:46] registering LB policy factory for \"xds_cluster_manager_experimental\"\n",
+ "D1123 22:47:22.348242294 13 lb_policy_registry.cc:46] registering LB policy factory for \"xds_cluster_impl_experimental\"\n",
+ "D1123 22:47:22.348245163 13 lb_policy_registry.cc:46] registering LB policy factory for \"cds_experimental\"\n",
+ "D1123 22:47:22.348249052 13 lb_policy_registry.cc:46] registering LB policy factory for \"xds_override_host_experimental\"\n",
+ "D1123 22:47:22.348254728 13 lb_policy_registry.cc:46] registering LB policy factory for \"xds_wrr_locality_experimental\"\n",
+ "D1123 22:47:22.348257770 13 lb_policy_registry.cc:46] registering LB policy factory for \"ring_hash_experimental\"\n",
+ "D1123 22:47:22.348260822 13 certificate_provider_registry.cc:33] registering certificate provider factory for \"file_watcher\"\n",
+ "D1123 22:47:22.348287458 13 channel_init.cc:157] Filter server-auth not registered, but is referenced in the after clause of grpc-server-authz when building channel stack SERVER_CHANNEL\n",
+ "I1123 22:47:22.350287239 13 ev_epoll1_linux.cc:359] grpc epoll fd: 61\n",
+ "I1123 22:47:22.351377022 13 tcp_socket_utils.cc:689] Disabling AF_INET6 sockets because ::1 is not available.\n",
+ "I1123 22:47:22.373168541 106 socket_utils_common_posix.cc:452] Disabling AF_INET6 sockets because ::1 is not available.\n",
+ "I1123 22:47:22.373233309 106 socket_utils_common_posix.cc:379] TCP_USER_TIMEOUT is available. TCP_USER_TIMEOUT will be used thereafter\n",
+ "E1123 22:47:22.379351349 13 oauth2_credentials.cc:238] oauth_fetch: UNKNOWN:C-ares status is not ARES_SUCCESS qtype=A name=metadata.google.internal. is_balancer=0: Domain name not found {grpc_status:2, created_time:\"2024-11-23T22:47:22.379337981+00:00\"}\n"
+ ]
+ }
+ ],
+ "source": [
+ "import tensorflow as tf\n",
+ "import pandas as pd\n",
+ "from tensorflow.keras import layers, models, optimizers\n",
+ "from PIL import Image\n",
+ "from tensorflow.keras import layers, models\n",
+ "from tensorflow.keras.preprocessing.image import load_img, img_to_array \n",
+ "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
+ "from tensorflow.keras.models import Sequential\n",
+ "from tensorflow.keras.applications import EfficientNetB3\n",
+ "from tensorflow.keras.layers import Dropout, Dense, GlobalAveragePooling2D\n",
+ "from tensorflow.keras.models import Model\n",
+ "import os\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "import seaborn as sns\n",
+ "from keras.preprocessing.image import load_img, img_to_array\n",
+ "from sklearn.metrics import confusion_matrix, classification_report\n",
+ "from sklearn.metrics import f1_score, precision_score, recall_score, accuracy_score\n",
+ "from tensorflow.keras.preprocessing import image\n",
+ "import matplotlib.image as mpimg"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# TPU Strategy\n",
+ "### Next, we check for the TPU and create a TPU strategy on which our model will be compiled, trained, and tested. If TPU is not found, we make sure to default to a a CPU/GPU strategy."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2024-11-23T22:47:29.781362Z",
+ "iopub.status.busy": "2024-11-23T22:47:29.780837Z",
+ "iopub.status.idle": "2024-11-23T22:47:38.615783Z",
+ "shell.execute_reply": "2024-11-23T22:47:38.614724Z",
+ "shell.execute_reply.started": "2024-11-23T22:47:29.781330Z"
+ },
+ "trusted": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "INFO:tensorflow:Deallocate tpu buffers before initializing tpu system.\n",
+ "INFO:tensorflow:Initializing the TPU system: local\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\n",
+ "I0000 00:00:1732402053.776734 13 service.cc:145] XLA service 0x56101aff8aa0 initialized for platform TPU (this does not guarantee that XLA will be used). Devices:\n",
+ "I0000 00:00:1732402053.776794 13 service.cc:153] StreamExecutor device (0): TPU, 2a886c8\n",
+ "I0000 00:00:1732402053.776799 13 service.cc:153] StreamExecutor device (1): TPU, 2a886c8\n",
+ "I0000 00:00:1732402053.776802 13 service.cc:153] StreamExecutor device (2): TPU, 2a886c8\n",
+ "I0000 00:00:1732402053.776807 13 service.cc:153] StreamExecutor device (3): TPU, 2a886c8\n",
+ "I0000 00:00:1732402053.776809 13 service.cc:153] StreamExecutor device (4): TPU, 2a886c8\n",
+ "I0000 00:00:1732402053.776812 13 service.cc:153] StreamExecutor device (5): TPU, 2a886c8\n",
+ "I0000 00:00:1732402053.776815 13 service.cc:153] StreamExecutor device (6): TPU, 2a886c8\n",
+ "I0000 00:00:1732402053.776817 13 service.cc:153] StreamExecutor device (7): TPU, 2a886c8\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "INFO:tensorflow:Finished initializing TPU system.\n",
+ "INFO:tensorflow:Found TPU system:\n",
+ "INFO:tensorflow:*** Num TPU Cores: 8\n",
+ "INFO:tensorflow:*** Num TPU Workers: 1\n",
+ "INFO:tensorflow:*** Num TPU Cores Per Worker: 8\n",
+ "INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:localhost/replica:0/task:0/device:CPU:0, CPU, 0, 0)\n",
+ "INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:localhost/replica:0/task:0/device:TPU:0, TPU, 0, 0)\n",
+ "INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:localhost/replica:0/task:0/device:TPU:1, TPU, 0, 0)\n",
+ "INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:localhost/replica:0/task:0/device:TPU:2, TPU, 0, 0)\n",
+ "INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:localhost/replica:0/task:0/device:TPU:3, TPU, 0, 0)\n",
+ "INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:localhost/replica:0/task:0/device:TPU:4, TPU, 0, 0)\n",
+ "INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:localhost/replica:0/task:0/device:TPU:5, TPU, 0, 0)\n",
+ "INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:localhost/replica:0/task:0/device:TPU:6, TPU, 0, 0)\n",
+ "INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:localhost/replica:0/task:0/device:TPU:7, TPU, 0, 0)\n",
+ "INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:localhost/replica:0/task:0/device:TPU_SYSTEM:0, TPU_SYSTEM, 0, 0)\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Check for TPU\n",
+ "try:\n",
+ " resolver = tf.distribute.cluster_resolver.TPUClusterResolver()\n",
+ " tf.config.experimental_connect_to_cluster(resolver)\n",
+ " tf.tpu.experimental.initialize_tpu_system(resolver)\n",
+ " strategy = tf.distribute.TPUStrategy(resolver)\n",
+ "except ValueError:\n",
+ " strategy = tf.distribute.get_strategy() # Default to CPU/GPU strategy if TPU is not found"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Loading Train and Val Data\n",
+ "### We define a function to augment images by applying random flips and brightness adjustments. This augmentation introduces variability, helping the model generalize better and reducing the risk of overfitting. Next, we load in the train dataset using Keras ImageDataGen and split it so that 20% of the train data is used for validation testing. We also load in our images with the size (300,300) as this is the target size for the EfficientNetB3 model."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2024-11-23T22:47:38.618312Z",
+ "iopub.status.busy": "2024-11-23T22:47:38.617940Z",
+ "iopub.status.idle": "2024-11-23T22:50:26.341139Z",
+ "shell.execute_reply": "2024-11-23T22:50:26.340018Z",
+ "shell.execute_reply.started": "2024-11-23T22:47:38.618281Z"
+ },
+ "trusted": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Found 87408 files belonging to 2 classes.\n",
+ "Using 69927 files for training.\n",
+ "Found 87408 files belonging to 2 classes.\n",
+ "Using 17481 files for validation.\n"
+ ]
+ }
+ ],
+ "source": [
+ "def augment_image(image, label):\n",
+ " image = tf.image.random_flip_left_right(image) # Randomly flip images\n",
+ " image = tf.image.random_brightness(image, max_delta=0.1) # Random brightness\n",
+ " return image, label\n",
+ "train_data = tf.keras.utils.image_dataset_from_directory(\n",
+ " '/kaggle/input/ai-vs-real-dataset/_DATASET/dataset/train',\n",
+ " image_size=(300, 300),\n",
+ " batch_size=128,\n",
+ " shuffle=True,\n",
+ " validation_split=0.2, # 20% for validation\n",
+ " subset=\"training\",\n",
+ " seed=123 #must be the same as for val_data\n",
+ ")\n",
+ "\n",
+ "val_data = tf.keras.utils.image_dataset_from_directory(\n",
+ " '/kaggle/input/ai-vs-real-dataset/_DATASET/dataset/train',\n",
+ " image_size=(300, 300),\n",
+ " batch_size=128,\n",
+ " shuffle=True,\n",
+ " validation_split=0.2,\n",
+ " subset=\"validation\",\n",
+ " seed=123\n",
+ ")\n",
+ "train_data = train_data.map(augment_image, num_parallel_calls=tf.data.AUTOTUNE)\n",
+ "# Prefetch to improve performance\n",
+ "train_data = train_data.prefetch(tf.data.AUTOTUNE)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Load and Compile Model\n",
+ "### Next, we load in the EfficientNetB3 model as our base model and exclude the top layer. Again the input shape is (300,300) and we make sure to make this base model untrainable for fine tuning. Then we add in our custom layers using the functional API:\n",
+ "#### GlobalAveragePooling2D layer computes the average value of each feature map across spatial dimensions, overall reducing the spatial dimensions of the model’s output and bridging the feature extraction layers to the dense layers. \n",
+ "#### Dense layer 128 units and ReLU activation adds a fully connected layer on top of the pooled features, allowing for more complex learning for the specific task of binary classification that our project is trying to accomplish. \n",
+ "#### Dropout layer to further prevent overfitting by randomly deactivating neurons, thereby enhancing generalization.\n",
+ "#### A final Dense layer with sigmoid activation is then added to compound the output between 0 and 1 for classification. \n",
+ "#### Finally, I compiled with ‘Adam’ optimizer, which combines adaptive learning rates with momentum, and is often used by CNN’s.\n",
+ "#### The second parameter for compiling is the binary cross-entropy loss, which is suitable for binary classification, as it evaluates the difference between predicted probabilities and actual labels.\n",
+ "#### And the last parmeter is the metric for evaluating model performance, which I chose to be ‘accuracy’.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2024-11-23T22:50:26.342603Z",
+ "iopub.status.busy": "2024-11-23T22:50:26.342335Z",
+ "iopub.status.idle": "2024-11-23T22:50:50.938523Z",
+ "shell.execute_reply": "2024-11-23T22:50:50.937574Z",
+ "shell.execute_reply.started": "2024-11-23T22:50:26.342568Z"
+ },
+ "trusted": true
+ },
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "I0000 00:00:1732402226.414719 13 device_compiler.h:188] Compiled cluster using XLA! This line is logged at most once for the lifetime of the process.\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "
Model: \"functional\"\n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[1mModel: \"functional\"\u001b[0m\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
+ "┃ Layer (type) ┃ Output Shape ┃ Param # ┃\n",
+ "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
+ "│ input_layer_1 (InputLayer) │ (None, 300, 300, 3) │ 0 │\n",
+ "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+ "│ efficientnetb3 (Functional) │ (None, 10, 10, 1536) │ 10,783,535 │\n",
+ "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+ "│ global_average_pooling2d │ (None, 1536) │ 0 │\n",
+ "│ (GlobalAveragePooling2D) │ │ │\n",
+ "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+ "│ dense (Dense) │ (None, 128) │ 196,736 │\n",
+ "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+ "│ dropout (Dropout) │ (None, 128) │ 0 │\n",
+ "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+ "│ dense_1 (Dense) │ (None, 1) │ 129 │\n",
+ "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
+ "
\n"
+ ],
+ "text/plain": [
+ "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
+ "┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
+ "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
+ "│ input_layer_1 (\u001b[38;5;33mInputLayer\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m300\u001b[0m, \u001b[38;5;34m300\u001b[0m, \u001b[38;5;34m3\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
+ "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+ "│ efficientnetb3 (\u001b[38;5;33mFunctional\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m, \u001b[38;5;34m10\u001b[0m, \u001b[38;5;34m1536\u001b[0m) │ \u001b[38;5;34m10,783,535\u001b[0m │\n",
+ "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+ "│ global_average_pooling2d │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1536\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
+ "│ (\u001b[38;5;33mGlobalAveragePooling2D\u001b[0m) │ │ │\n",
+ "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+ "│ dense (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m196,736\u001b[0m │\n",
+ "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+ "│ dropout (\u001b[38;5;33mDropout\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
+ "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+ "│ dense_1 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m) │ \u001b[38;5;34m129\u001b[0m │\n",
+ "└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " Total params: 10,980,400 (41.89 MB)\n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m10,980,400\u001b[0m (41.89 MB)\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " Trainable params: 196,865 (769.00 KB)\n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m196,865\u001b[0m (769.00 KB)\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " Non-trainable params: 10,783,535 (41.14 MB)\n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m10,783,535\u001b[0m (41.14 MB)\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "# Load the EfficientNet base model\n",
+ "with strategy.scope():\n",
+ " \n",
+ " base_model = tf.keras.applications.EfficientNetB3(\n",
+ " weights=\"/kaggle/input/efficientnetb3-notoph5/efficientnetb3_notop.h5\", # Use pre-trained weights\n",
+ " include_top=False, # Exclude the classifier head\n",
+ " input_shape=(300, 300, 3) # Adjust to EfficientNetB3's input size\n",
+ " )\n",
+ "\n",
+ "# Freeze the base model layers during the first training phase\n",
+ " base_model.trainable = False\n",
+ "# Build the custom model\n",
+ " inputs = tf.keras.Input(shape=(300, 300, 3))\n",
+ " x = base_model(inputs, training=False) # Keep base model frozen\n",
+ " x = layers.GlobalAveragePooling2D()(x)\n",
+ " x = layers.Dense(128, activation=\"relu\")(x)\n",
+ " x = layers.Dropout(0.5)(x) # Regularization\n",
+ " outputs = layers.Dense(1, activation=\"sigmoid\")(x) # Binary classification\n",
+ "\n",
+ " model = models.Model(inputs, outputs)\n",
+ "\n",
+ "# Compile the model\n",
+ " model.compile(\n",
+ " optimizer=optimizers.Adam(learning_rate=1e-3),\n",
+ " loss=\"binary_crossentropy\",\n",
+ " metrics=[\"accuracy\"]\n",
+ " )\n",
+ " model.summary()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Model Fit\n",
+ "### Now we can start training our model. We use the history=model.fit() so that we can later plot our train and validation accuracy and loss. We set the starting epochs for 15 and add EarlyStopping and ReduceLROnPlateau callbacks to ensure our model is improving in it's training. These callbacks are set to monitor validation loss as this is a good inidicator of a model's performance in terms of generalization and overfititng."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2024-11-23T22:50:50.940007Z",
+ "iopub.status.busy": "2024-11-23T22:50:50.939698Z",
+ "iopub.status.idle": "2024-11-23T23:14:07.540272Z",
+ "shell.execute_reply": "2024-11-23T23:14:07.538944Z",
+ "shell.execute_reply.started": "2024-11-23T22:50:50.939976Z"
+ },
+ "trusted": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 1/15\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "2024-11-23 22:51:10.572501: E tensorflow/core/grappler/optimizers/meta_optimizer.cc:961] model_pruner failed: INVALID_ARGUMENT: Graph does not contain terminal node StatefulPartitionedCall.\n",
+ "I0000 00:00:1732402273.495714 813 tpu_compilation_cache_interface.cc:441] TPU host compilation cache miss: cache_key(92d1db5660fc6155:0:0), session_name()\n",
+ "I0000 00:00:1732402318.316498 813 tpu_compile_op_common.cc:245] Compilation of 92d1db5660fc6155:0:0 with session name took 44.820701323s and succeeded\n",
+ "I0000 00:00:1732402318.428517 813 tpu_compilation_cache_interface.cc:475] TPU host compilation cache: compilation complete for cache_key(92d1db5660fc6155:0:0), session_name(), subgraph_key(std::string(property.function_name) = \"cluster_one_step_on_iterator_1568928126473911795\", property.function_library_fingerprint = 354415044868241532, property.mlir_module_fingerprint = 0, property.num_replicas = 8, topology.chip_bounds().x = 2, topology.chip_bounds().y = 2, topology.chip_bounds().z = 1, topology.wrap().x = false, topology.wrap().y = false, topology.wrap().z = false, std::string(property.shapes_prefix) = \"16,300,300,3,;16,;\", property.guaranteed_constants_size = 0, embedding_partitions_fingerprint = \"1688352644216761960\")\n",
+ "I0000 00:00:1732402318.428609 813 tpu_compilation_cache_interface.cc:541] After adding entry for key 92d1db5660fc6155:0:0 with session_name cache is 1 entries (133024500 bytes), marked for eviction 0 entries (0 bytes).\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\u001b[1m546/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 115ms/step - accuracy: 0.8210 - loss: 0.3884"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "I0000 00:00:1732402381.400134 773 tpu_compilation_cache_interface.cc:441] TPU host compilation cache miss: cache_key(4de9de6d28ec10ca:0:0), session_name()\n",
+ "I0000 00:00:1732402422.941184 773 tpu_compile_op_common.cc:245] Compilation of 4de9de6d28ec10ca:0:0 with session name took 41.541003613s and succeeded\n",
+ "I0000 00:00:1732402423.079522 773 tpu_compilation_cache_interface.cc:475] TPU host compilation cache: compilation complete for cache_key(4de9de6d28ec10ca:0:0), session_name(), subgraph_key(std::string(property.function_name) = \"cluster_one_step_on_iterator_1568928126473911795\", property.function_library_fingerprint = 354415044868241532, property.mlir_module_fingerprint = 0, property.num_replicas = 8, topology.chip_bounds().x = 2, topology.chip_bounds().y = 2, topology.chip_bounds().z = 1, topology.wrap().x = false, topology.wrap().y = false, topology.wrap().z = false, std::string(property.shapes_prefix) = \"5,300,300,3,;5,;\", property.guaranteed_constants_size = 0, embedding_partitions_fingerprint = \"1688352644216761960\")\n",
+ "I0000 00:00:1732402423.079561 773 tpu_compilation_cache_interface.cc:541] After adding entry for key 4de9de6d28ec10ca:0:0 with session_name cache is 2 entries (272787183 bytes), marked for eviction 0 entries (0 bytes).\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 192ms/step - accuracy: 0.8211 - loss: 0.3882"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "2024-11-23 22:53:48.731305: E tensorflow/core/grappler/optimizers/meta_optimizer.cc:961] model_pruner failed: INVALID_ARGUMENT: Graph does not contain terminal node Add/ReadVariableOp.\n",
+ "I0000 00:00:1732402429.736116 809 tpu_compilation_cache_interface.cc:441] TPU host compilation cache miss: cache_key(67ba0b4ab4b6345c:0:0), session_name()\n",
+ "I0000 00:00:1732402438.199222 809 tpu_compile_op_common.cc:245] Compilation of 67ba0b4ab4b6345c:0:0 with session name took 8.463048252s and succeeded\n",
+ "I0000 00:00:1732402438.217827 809 tpu_compilation_cache_interface.cc:475] TPU host compilation cache: compilation complete for cache_key(67ba0b4ab4b6345c:0:0), session_name(), subgraph_key(std::string(property.function_name) = \"cluster_one_step_on_iterator_3654818894138208684\", property.function_library_fingerprint = 17184398301921755350, property.mlir_module_fingerprint = 0, property.num_replicas = 8, topology.chip_bounds().x = 2, topology.chip_bounds().y = 2, topology.chip_bounds().z = 1, topology.wrap().x = false, topology.wrap().y = false, topology.wrap().z = false, std::string(property.shapes_prefix) = \"16,300,300,3,;16,;\", property.guaranteed_constants_size = 0, embedding_partitions_fingerprint = \"1688352644216761960\")\n",
+ "I0000 00:00:1732402438.217871 809 tpu_compilation_cache_interface.cc:541] After adding entry for key 67ba0b4ab4b6345c:0:0 with session_name cache is 3 entries (305901318 bytes), marked for eviction 0 entries (0 bytes).\n",
+ "I0000 00:00:1732402451.373896 792 tpu_compilation_cache_interface.cc:441] TPU host compilation cache miss: cache_key(78f97bc6b9a70a7f:0:0), session_name()\n",
+ "I0000 00:00:1732402467.720226 792 tpu_compile_op_common.cc:245] Compilation of 78f97bc6b9a70a7f:0:0 with session name took 16.346289089s and succeeded\n",
+ "I0000 00:00:1732402467.741335 792 tpu_compilation_cache_interface.cc:475] TPU host compilation cache: compilation complete for cache_key(78f97bc6b9a70a7f:0:0), session_name(), subgraph_key(std::string(property.function_name) = \"cluster_one_step_on_iterator_3654818894138208684\", property.function_library_fingerprint = 17184398301921755350, property.mlir_module_fingerprint = 0, property.num_replicas = 8, topology.chip_bounds().x = 2, topology.chip_bounds().y = 2, topology.chip_bounds().z = 1, topology.wrap().x = false, topology.wrap().y = false, topology.wrap().z = false, std::string(property.shapes_prefix) = \"10,300,300,3,;10,;\", property.guaranteed_constants_size = 0, embedding_partitions_fingerprint = \"1688352644216761960\")\n",
+ "I0000 00:00:1732402467.741366 792 tpu_compilation_cache_interface.cc:541] After adding entry for key 78f97bc6b9a70a7f:0:0 with session_name cache is 4 entries (339250694 bytes), marked for eviction 0 entries (0 bytes).\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Epoch 1: val_loss improved from inf to 0.22920, saving model to /kaggle/working/efficientnetb3_binary_classifier_pre_8.keras\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m208s\u001b[0m 277ms/step - accuracy: 0.8212 - loss: 0.3881 - val_accuracy: 0.9076 - val_loss: 0.2292 - learning_rate: 0.0010\n",
+ "Epoch 2/15\n",
+ "\u001b[1m546/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 126ms/step - accuracy: 0.8910 - loss: 0.2596\n",
+ "Epoch 2: val_loss improved from 0.22920 to 0.20956, saving model to /kaggle/working/efficientnetb3_binary_classifier_pre_8.keras\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m87s\u001b[0m 157ms/step - accuracy: 0.8910 - loss: 0.2595 - val_accuracy: 0.9149 - val_loss: 0.2096 - learning_rate: 0.0010\n",
+ "Epoch 3/15\n",
+ "\u001b[1m546/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 124ms/step - accuracy: 0.9074 - loss: 0.2279\n",
+ "Epoch 3: val_loss improved from 0.20956 to 0.19180, saving model to /kaggle/working/efficientnetb3_binary_classifier_pre_8.keras\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m86s\u001b[0m 154ms/step - accuracy: 0.9074 - loss: 0.2279 - val_accuracy: 0.9181 - val_loss: 0.1918 - learning_rate: 0.0010\n",
+ "Epoch 4/15\n",
+ "\u001b[1m546/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 124ms/step - accuracy: 0.8948 - loss: 0.2385\n",
+ "Epoch 4: val_loss improved from 0.19180 to 0.17203, saving model to /kaggle/working/efficientnetb3_binary_classifier_pre_8.keras\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m86s\u001b[0m 154ms/step - accuracy: 0.8948 - loss: 0.2384 - val_accuracy: 0.9341 - val_loss: 0.1720 - learning_rate: 0.0010\n",
+ "Epoch 5/15\n",
+ "\u001b[1m546/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 125ms/step - accuracy: 0.9206 - loss: 0.1942\n",
+ "Epoch 5: val_loss did not improve from 0.17203\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m84s\u001b[0m 152ms/step - accuracy: 0.9206 - loss: 0.1942 - val_accuracy: 0.9250 - val_loss: 0.1864 - learning_rate: 0.0010\n",
+ "Epoch 6/15\n",
+ "\u001b[1m546/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 123ms/step - accuracy: 0.9216 - loss: 0.1930\n",
+ "Epoch 6: val_loss did not improve from 0.17203\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m83s\u001b[0m 149ms/step - accuracy: 0.9216 - loss: 0.1930 - val_accuracy: 0.9309 - val_loss: 0.1760 - learning_rate: 0.0010\n",
+ "Epoch 7/15\n",
+ "\u001b[1m546/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 122ms/step - accuracy: 0.9193 - loss: 0.1975\n",
+ "Epoch 7: val_loss improved from 0.17203 to 0.15025, saving model to /kaggle/working/efficientnetb3_binary_classifier_pre_8.keras\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m84s\u001b[0m 151ms/step - accuracy: 0.9193 - loss: 0.1975 - val_accuracy: 0.9414 - val_loss: 0.1502 - learning_rate: 0.0010\n",
+ "Epoch 8/15\n",
+ "\u001b[1m546/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 123ms/step - accuracy: 0.9282 - loss: 0.1800\n",
+ "Epoch 8: val_loss did not improve from 0.15025\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m84s\u001b[0m 150ms/step - accuracy: 0.9282 - loss: 0.1800 - val_accuracy: 0.9346 - val_loss: 0.1545 - learning_rate: 0.0010\n",
+ "Epoch 9/15\n",
+ "\u001b[1m546/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 123ms/step - accuracy: 0.9277 - loss: 0.1832\n",
+ "Epoch 9: val_loss did not improve from 0.15025\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m83s\u001b[0m 150ms/step - accuracy: 0.9276 - loss: 0.1832 - val_accuracy: 0.9369 - val_loss: 0.1681 - learning_rate: 0.0010\n",
+ "Epoch 10/15\n",
+ "\u001b[1m546/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 122ms/step - accuracy: 0.9312 - loss: 0.1868\n",
+ "Epoch 10: val_loss improved from 0.15025 to 0.13902, saving model to /kaggle/working/efficientnetb3_binary_classifier_pre_8.keras\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m84s\u001b[0m 151ms/step - accuracy: 0.9312 - loss: 0.1868 - val_accuracy: 0.9474 - val_loss: 0.1390 - learning_rate: 0.0010\n",
+ "Epoch 11/15\n",
+ "\u001b[1m546/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 123ms/step - accuracy: 0.9344 - loss: 0.1681\n",
+ "Epoch 11: val_loss did not improve from 0.13902\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m83s\u001b[0m 149ms/step - accuracy: 0.9344 - loss: 0.1681 - val_accuracy: 0.9355 - val_loss: 0.1672 - learning_rate: 0.0010\n",
+ "Epoch 12/15\n",
+ "\u001b[1m546/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 123ms/step - accuracy: 0.9338 - loss: 0.1647\n",
+ "Epoch 12: val_loss did not improve from 0.13902\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m83s\u001b[0m 149ms/step - accuracy: 0.9338 - loss: 0.1647 - val_accuracy: 0.9478 - val_loss: 0.1442 - learning_rate: 0.0010\n",
+ "Epoch 13/15\n",
+ "\u001b[1m546/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 123ms/step - accuracy: 0.9368 - loss: 0.1679\n",
+ "Epoch 13: ReduceLROnPlateau reducing learning rate to 0.0005000000237487257.\n",
+ "\n",
+ "Epoch 13: val_loss did not improve from 0.13902\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m84s\u001b[0m 151ms/step - accuracy: 0.9368 - loss: 0.1679 - val_accuracy: 0.9392 - val_loss: 0.1467 - learning_rate: 0.0010\n",
+ "Epoch 14/15\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 122ms/step - accuracy: 0.9365 - loss: 0.1509\n",
+ "Epoch 14: val_loss did not improve from 0.13902\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m83s\u001b[0m 149ms/step - accuracy: 0.9365 - loss: 0.1509 - val_accuracy: 0.9392 - val_loss: 0.1427 - learning_rate: 5.0000e-04\n",
+ "Epoch 15/15\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 119ms/step - accuracy: 0.9448 - loss: 0.1435\n",
+ "Epoch 15: val_loss did not improve from 0.13902\n",
+ "\u001b[1m547/547\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m81s\u001b[0m 146ms/step - accuracy: 0.9448 - loss: 0.1435 - val_accuracy: 0.9456 - val_loss: 0.1430 - learning_rate: 5.0000e-04\n"
+ ]
+ }
+ ],
+ "source": [
+ "with strategy.scope():\n",
+ " history = model.fit(\n",
+ " train_data, \n",
+ " validation_data=val_data,\n",
+ " epochs=15,\n",
+ " callbacks=[\n",
+ " tf.keras.callbacks.EarlyStopping(monitor=\"val_loss\", patience=5, restore_best_weights=True),\n",
+ " tf.keras.callbacks.ReduceLROnPlateau(monitor=\"val_loss\", factor=0.5, patience=3, min_lr=1e-6, verbose=1)\n",
+ " ]\n",
+ " )"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Model Accuracy and Loss\n",
+ "### After this we plot our Model Accuracy and Model Loss Charts. The model seems to be underfitting a bit as validation accuracy is higher than that of the training, but this is most likely due to data augmentation and the dropout layer that is applied to the training data. The plot also shows convergance at the 15th epochs, which is a good sign of a well balanced model."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2024-11-23T23:14:07.543552Z",
+ "iopub.status.busy": "2024-11-23T23:14:07.543215Z",
+ "iopub.status.idle": "2024-11-23T23:14:09.887690Z",
+ "shell.execute_reply": "2024-11-23T23:14:09.886698Z",
+ "shell.execute_reply.started": "2024-11-23T23:14:07.543518Z"
+ },
+ "trusted": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ "