diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000000000000000000000000000000000..50dd9e4e8606a474ad7b0eda3f95c258471adea9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/hardware/src/hardware/lib/pico-tflmicro"] + path = src/hardware/src/hardware/lib/pico-tflmicro + url = https://github.com/raspberrypi/pico-tflmicro diff --git a/src/PC/sign_language_detector.ipynb b/src/PC/sign_language_detector.ipynb deleted file mode 100644 index 576434268599c5f3884f0c29649da02ca72baa31..0000000000000000000000000000000000000000 --- a/src/PC/sign_language_detector.ipynb +++ /dev/null @@ -1,170 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# SIGN LANGUAGE TRANSLATOR" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import tensorflow as tf\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import random\n", - "\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Get data and label from train and test dataset." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "train_path = \"dataset/sign_mnist_train.csv\"\n", - "test_path = \"dataset/sign_mnist_test.csv\"\n", - "\n", - "train = pd.read_csv(train_path)\n", - "test = pd.read_csv(test_path)\n", - "\n", - "train_data = np.array(train)[:, 1:]\n", - "train_label = np.array(train)[:, 0]\n", - "\n", - "test_data = np.array(test)[:, 1:]\n", - "test_label = np.array(test)[:, 0]\n", - "\n", - "train_data = np.reshape(train_data, (-1, 28, 28, 1))\n", - "test_data = np.reshape(test_data, (-1, 28, 28, 1))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Show random image from train dataset." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "alphabet = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n", - "\n", - "rand_i = random.randint(1, train_data.shape[0])\n", - "img = train_data[rand_i]\n", - "print(f\"Letter : {alphabet[train_label[rand_i]]}\")\n", - "plt.imshow(img, cmap='gray')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# CNN\n", - "Entrainement et evaluation du modèle." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from tensorflow.keras.models import Sequential\n", - "from tensorflow.keras.layers import Conv2D, Dense, MaxPool2D, Flatten, Rescaling, Dropout\n", - "from tensorflow.keras.losses import SparseCategoricalCrossentropy\n", - "\n", - "\n", - "CLASS_COUNT = int(np.max(train_label) + 1)\n", - "INPUT_SHAPE = train_data.shape[1]\n", - "BATCH_SIZE = 32#train_data.shape[0] // 4\n", - "EPOCHS = 15\n", - "\n", - "train_label = tf.keras.utils.to_categorical(train_label, CLASS_COUNT)\n", - "test_label = tf.keras.utils.to_categorical(test_label, CLASS_COUNT)\n", - "\n", - "model = Sequential()\n", - "model.add(Rescaling(1./255, input_shape=(INPUT_SHAPE, INPUT_SHAPE, 1)))\n", - "model.add(Conv2D(filters=32, kernel_size=3, padding=\"same\", activation='relu'))\n", - "model.add(MaxPool2D())\n", - "model.add(Conv2D(filters=64, kernel_size=3, padding=\"same\", activation='relu'))\n", - "model.add(MaxPool2D())\n", - "model.add(Flatten())\n", - "model.add(Dropout(0.5))\n", - "model.add(Dense(CLASS_COUNT, activation=\"softmax\"))\n", - "model.summary()\n", - "\n", - "model.compile(optimizer='adam', loss=\"categorical_crossentropy\", metrics=['accuracy'])\n", - "history = model.fit(train_data, train_label, batch_size=BATCH_SIZE, epochs=EPOCHS)\n", - "\n", - "plt.plot(history.history[\"loss\"])\n", - "plt.xlabel(\"Epochs\")\n", - "plt.ylabel(\"Loss value\")\n", - "plt.title(\"Evolution of Loss\")\n", - "plt.show()\n", - "\n", - "plt.plot(history.history[\"accuracy\"])\n", - "plt.xlabel(\"Epochs\")\n", - "plt.ylabel(\"Accuracy\")\n", - "plt.title(\"Evolution of Accuracy\")\n", - "plt.show()\n", - "\n", - "evaluate = model.evaluate(test_data, test_label, verbose=2) # ~58%\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Export as Keras model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "model.save('sign_model.keras')" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": ".venv", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.8" - }, - "orig_nbformat": 4 - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/src/hardware/CMakeLists.txt b/src/hardware/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e8882ca0b7ac0c56e9f84e84aa781773e139a7e0 --- /dev/null +++ b/src/hardware/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.12) + +include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake) + + +project(sign_translator CXX C ASM) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) +#set(PICO_SDK_PATH "/home/jonas/installs/pico/pico-sdk") + +add_compile_options(-Wall) + +# Initialize the RP2040 SDK +include(${PICO_SDK_PATH}/pico_sdk_init.cmake) + +# Set the CMake project type to RP2040 +pico_sdk_init() + +add_executable(${PROJECT_NAME} + main.c + fonts.c + st7735.c + DEV_Config.c +) + +target_link_libraries(${PROJECT_NAME} + pico_stdlib + hardware_spi + hardware_i2c + hardware_pwm +) + +# Create a UF2 file for flashing the RP2040 +pico_add_extra_outputs(${PROJECT_NAME}) + +# Set the output directory for the built binary (if desired) +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) + +# Enable USB output, disable UART output +pico_enable_stdio_usb(${PROJECT_NAME} 1) +pico_enable_stdio_uart(${PROJECT_NAME} 0) \ No newline at end of file diff --git a/src/hardware/lib/pico-tflmicro b/src/hardware/lib/pico-tflmicro new file mode 160000 index 0000000000000000000000000000000000000000..03cbb1e7b89792aef2c59e2dbe8cb2c81c049bbd --- /dev/null +++ b/src/hardware/lib/pico-tflmicro @@ -0,0 +1 @@ +Subproject commit 03cbb1e7b89792aef2c59e2dbe8cb2c81c049bbd diff --git a/src/hardware/main.c b/src/hardware/main.c new file mode 100644 index 0000000000000000000000000000000000000000..3690407585b4dc5f742fe50fb63452343480be7d --- /dev/null +++ b/src/hardware/main.c @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "pico/stdlib.h" + +int main() +{ + // INIT SERIAL + stdio_init_all(); + + while (true) + { + + } + return 0; +} diff --git a/src/PC/dataset/amer_sign2.png b/src/pc/dataset/amer_sign2.png similarity index 100% rename from src/PC/dataset/amer_sign2.png rename to src/pc/dataset/amer_sign2.png diff --git a/src/PC/dataset/amer_sign3.png b/src/pc/dataset/amer_sign3.png similarity index 100% rename from src/PC/dataset/amer_sign3.png rename to src/pc/dataset/amer_sign3.png diff --git a/src/PC/dataset/american_sign_language.PNG b/src/pc/dataset/american_sign_language.PNG similarity index 100% rename from src/PC/dataset/american_sign_language.PNG rename to src/pc/dataset/american_sign_language.PNG diff --git a/src/PC/dataset/sign_mnist_test.csv b/src/pc/dataset/sign_mnist_test.csv similarity index 100% rename from src/PC/dataset/sign_mnist_test.csv rename to src/pc/dataset/sign_mnist_test.csv diff --git a/src/PC/dataset/sign_mnist_test/sign_mnist_test.csv b/src/pc/dataset/sign_mnist_test/sign_mnist_test.csv similarity index 100% rename from src/PC/dataset/sign_mnist_test/sign_mnist_test.csv rename to src/pc/dataset/sign_mnist_test/sign_mnist_test.csv diff --git a/src/PC/dataset/sign_mnist_train.csv b/src/pc/dataset/sign_mnist_train.csv similarity index 100% rename from src/PC/dataset/sign_mnist_train.csv rename to src/pc/dataset/sign_mnist_train.csv diff --git a/src/PC/dataset/sign_mnist_train/sign_mnist_train.csv b/src/pc/dataset/sign_mnist_train/sign_mnist_train.csv similarity index 100% rename from src/PC/dataset/sign_mnist_train/sign_mnist_train.csv rename to src/pc/dataset/sign_mnist_train/sign_mnist_train.csv diff --git a/src/pc/sign_language_detector.ipynb b/src/pc/sign_language_detector.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..a919e1f9976f4f7c9b72bab83aeb531ec02b12f0 --- /dev/null +++ b/src/pc/sign_language_detector.ipynb @@ -0,0 +1,383 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# SIGN LANGUAGE TRANSLATOR" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2024-04-25 11:02:05.961370: I external/local_tsl/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.\n", + "2024-04-25 11:02:05.968007: I external/local_tsl/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.\n", + "2024-04-25 11:02:06.043719: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n", + "To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n", + "2024-04-25 11:02:07.241551: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import tensorflow as tf\n", + "import matplotlib.pyplot as plt\n", + "import pandas as pd\n", + "import random\n", + "\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get data and label from train and test dataset." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "train_path = \"dataset/sign_mnist_train.csv\"\n", + "test_path = \"dataset/sign_mnist_test.csv\"\n", + "\n", + "train = pd.read_csv(train_path)\n", + "test = pd.read_csv(test_path)\n", + "\n", + "train_data = np.array(train)[:, 1:]\n", + "train_label = np.array(train)[:, 0]\n", + "\n", + "test_data = np.array(test)[:, 1:]\n", + "test_label = np.array(test)[:, 0]\n", + "\n", + "train_data = np.reshape(train_data, (-1, 28, 28, 1))\n", + "test_data = np.reshape(test_data, (-1, 28, 28, 1))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Show random image from train dataset." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Letter : O\n" + ] + }, + { + "data": { + "text/plain": [ + "<matplotlib.image.AxesImage at 0x7f46dc0c9ad0>" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "alphabet = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n", + "\n", + "rand_i = random.randint(1, train_data.shape[0])\n", + "img = train_data[rand_i]\n", + "print(f\"Letter : {alphabet[train_label[rand_i]]}\")\n", + "plt.imshow(img, cmap='gray')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# CNN\n", + "Entrainement et evaluation du modèle." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/djokzer/Documents/hepia/sem_6/smart_sensors/embedded_ml_sign_language/.venv/lib/python3.11/site-packages/keras/src/layers/preprocessing/tf_data_layer.py:18: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n", + " super().__init__(**kwargs)\n" + ] + }, + { + "data": { + "text/html": [ + "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential\"</span>\n", + "</pre>\n" + ], + "text/plain": [ + "\u001b[1mModel: \"sequential\"\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n", + "┃<span style=\"font-weight: bold\"> Layer (type) </span>┃<span style=\"font-weight: bold\"> Output Shape </span>┃<span style=\"font-weight: bold\"> Param # </span>┃\n", + "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n", + "│ rescaling (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Rescaling</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">28</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">28</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ conv2d (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv2D</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">28</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">28</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">320</span> │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ max_pooling2d (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling2D</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">14</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">14</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ conv2d_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv2D</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">14</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">14</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">18,496</span> │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ max_pooling2d_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling2D</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">7</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">7</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ flatten (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Flatten</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">3136</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ dropout (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dropout</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">3136</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ dense (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">25</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">78,425</span> │\n", + "└─────────────────────────────────┴────────────────────────┴───────────────┘\n", + "</pre>\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", + "│ rescaling (\u001b[38;5;33mRescaling\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m28\u001b[0m, \u001b[38;5;34m28\u001b[0m, \u001b[38;5;34m1\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ conv2d (\u001b[38;5;33mConv2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m28\u001b[0m, \u001b[38;5;34m28\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m320\u001b[0m │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ max_pooling2d (\u001b[38;5;33mMaxPooling2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m14\u001b[0m, \u001b[38;5;34m14\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ conv2d_1 (\u001b[38;5;33mConv2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m14\u001b[0m, \u001b[38;5;34m14\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m18,496\u001b[0m │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ max_pooling2d_1 (\u001b[38;5;33mMaxPooling2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m7\u001b[0m, \u001b[38;5;34m7\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ flatten (\u001b[38;5;33mFlatten\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m3136\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ dropout (\u001b[38;5;33mDropout\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m3136\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ dense (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m25\u001b[0m) │ \u001b[38;5;34m78,425\u001b[0m │\n", + "└─────────────────────────────────┴────────────────────────┴───────────────┘\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">97,241</span> (379.85 KB)\n", + "</pre>\n" + ], + "text/plain": [ + "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m97,241\u001b[0m (379.85 KB)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">97,241</span> (379.85 KB)\n", + "</pre>\n" + ], + "text/plain": [ + "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m97,241\u001b[0m (379.85 KB)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n", + "</pre>\n" + ], + "text/plain": [ + "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/15\n", + "\u001b[1m858/858\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 11ms/step - accuracy: 0.4431 - loss: 1.8881\n", + "Epoch 2/15\n", + "\u001b[1m858/858\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 11ms/step - accuracy: 0.9393 - loss: 0.1967\n", + "Epoch 3/15\n", + "\u001b[1m858/858\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 10ms/step - accuracy: 0.9785 - loss: 0.0718\n", + "Epoch 4/15\n", + "\u001b[1m858/858\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 10ms/step - accuracy: 0.9888 - loss: 0.0411\n", + "Epoch 5/15\n", + "\u001b[1m858/858\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 10ms/step - accuracy: 0.9904 - loss: 0.0304\n", + "Epoch 6/15\n", + "\u001b[1m858/858\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 11ms/step - accuracy: 0.9944 - loss: 0.0187\n", + "Epoch 7/15\n", + "\u001b[1m858/858\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 11ms/step - accuracy: 0.9944 - loss: 0.0189\n", + "Epoch 8/15\n", + "\u001b[1m858/858\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 10ms/step - accuracy: 0.9955 - loss: 0.0139\n", + "Epoch 9/15\n", + "\u001b[1m858/858\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 11ms/step - accuracy: 0.9974 - loss: 0.0105\n", + "Epoch 10/15\n", + "\u001b[1m858/858\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 10ms/step - accuracy: 0.9968 - loss: 0.0114\n", + "Epoch 11/15\n", + "\u001b[1m858/858\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 11ms/step - accuracy: 0.9973 - loss: 0.0104\n", + "Epoch 12/15\n", + "\u001b[1m858/858\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 11ms/step - accuracy: 0.9965 - loss: 0.0111\n", + "Epoch 13/15\n", + "\u001b[1m858/858\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 10ms/step - accuracy: 0.9984 - loss: 0.0069\n", + "Epoch 14/15\n", + "\u001b[1m858/858\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 11ms/step - accuracy: 0.9972 - loss: 0.0081\n", + "Epoch 15/15\n", + "\u001b[1m858/858\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 11ms/step - accuracy: 0.9967 - loss: 0.0102\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAHHCAYAAABDUnkqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAABFhUlEQVR4nO3de3yT5f3/8XeSNumBHoDSE1ZakK8gIDKQWnDDQxWBueFhIqIgTv2p6MCqU1TAw7SiX12nIggqsk0E5SvOKaCIh01EEZCpE/AAAgptqdADhZ6S+/dHm7ShLbSQ5CbJ6/l45NHkyn0nn7S1vL2u674ui2EYhgAAAEKE1ewCAAAAfIlwAwAAQgrhBgAAhBTCDQAACCmEGwAAEFIINwAAIKQQbgAAQEgh3AAAgJBCuAEAACGFcAPgqFgsFt13330+fc0XX3xRFotFP/zwg09f19cee+wxde/eXTabTaeddprZ5QA4BOEGCGLuMNDa7ZNPPjG7xBY9/PDDev31180u46i88847+uMf/6ihQ4dq/vz5evjhh1s99uqrr1aHDh0CWB0ASYowuwAAx+6BBx5QVlZWs/aTTjrJhGqO7OGHH9all16q0aNHe7VfddVVuvzyy+VwOMwprA3ee+89Wa1WPf/887Lb7WaXA6AFhBsgBIwYMUKDBg0yu4xjZrPZZLPZzC7jsIqLixUdHU2wAY5jDEsBIa62tladOnXSxIkTmz1XXl6uqKgo3X777Z624uJi/f73v1dKSoqioqLUv39/LViw4Ijvc/XVVyszM7NZ+3333SeLxeJ5bLFYVFlZqQULFniGz66++mpJrc+5eeaZZ9SnTx85HA6lp6dr0qRJKi0t9TrmrLPOUt++ffX111/r7LPPVkxMjLp27apHH330iLVLUl1dnR588EH16NFDDodDmZmZuvvuu1VdXe1V+/z581VZWemp/cUXX2zT6x/Oq6++qoEDByo6OlpJSUm68sor9dNPP3kdU1hYqIkTJ+qEE06Qw+FQWlqafvvb33p9r9atW6fhw4crKSlJ0dHRysrK0jXXXHPM9QHBhp4bIASUlZWppKTEq81isahz586KjIzURRddpNdee03PPvusV4/D66+/rurqal1++eWSpIMHD+qss87Sd999p5tvvllZWVl69dVXdfXVV6u0tFSTJ08+5lr/9re/6dprr9XgwYN1/fXXS5J69OjR6vH33Xef7r//fuXm5urGG2/Uli1bNHv2bH322WdavXq1IiMjPcfu27dPF1xwgS6++GJddtllWrJkie68807169dPI0aMOGxd1157rRYsWKBLL71Ut912mz799FPl5+dr06ZNWrp0qaf2uXPnau3atXruueckSUOGDDmm78eLL76oiRMn6vTTT1d+fr6Kior0l7/8RatXr9bnn3+uxMRESdIll1yi//73v7rllluUmZmp4uJirVy5Ujt27PA8Pv/889WlSxfdddddSkxM1A8//KDXXnvtmOoDgpIBIGjNnz/fkNTizeFweI57++23DUnGP//5T6/zR44caXTv3t3zuKCgwJBk/P3vf/e01dTUGDk5OUaHDh2M8vJyT7skY8aMGZ7HEyZMMLp169asxhkzZhiH/qmJjY01JkyY0Orn2bZtm2EYhlFcXGzY7Xbj/PPPN5xOp+e4p59+2pBkvPDCC562YcOGGZKMv/71r5626upqIzU11bjkkkuavVdTGzduNCQZ1157rVf77bffbkgy3nvvPa/PGRsbe9jXa+uxNTU1RnJystG3b1/j4MGDnvY333zTkGRMnz7dMAzD2LdvnyHJeOyxx1p9raVLlxqSjM8++6xNtQGhjGEpIATMmjVLK1eu9LotX77c8/w555yjpKQkLV682NO2b98+rVy5UmPGjPG0LVu2TKmpqRo7dqynLTIyUn/4wx+0f/9+ffjhh4H5QA3effdd1dTUaMqUKbJaG/9cXXfddYqPj9dbb73ldXyHDh105ZVXeh7b7XYNHjxYW7duPez7LFu2TJKUl5fn1X7bbbdJUrP38ZV169apuLhYN910k6Kiojzto0aNUq9evTzv657j88EHH2jfvn0tvpa7h+fNN99UbW2tX+oFggXhBggBgwcPVm5urtft7LPP9jwfERGhSy65RP/4xz88c0hee+011dbWeoWb7du3q2fPnl5BQpJ69+7teT6Q3O938skne7Xb7XZ17969WT0nnHCC1/weSerYsWOrgaDp+1it1mZXl6WmpioxMdFvn7u1zydJvXr18jzvcDg0c+ZMLV++XCkpKfrVr36lRx99VIWFhZ7jhw0bpksuuUT333+/kpKS9Nvf/lbz58/3mjMEhAvCDRAmLr/8clVUVHh6dF555RX16tVL/fv398nrHxoq3JxOp09evy1au9LKMIw2nd/aZzgeTJkyRd98843y8/MVFRWladOmqXfv3vr8888l1de+ZMkSrVmzRjfffLN++uknXXPNNRo4cKD2799vcvVAYBFugDDxq1/9SmlpaVq8eLFKSkr03nvvefXaSFK3bt307bffyuVyebVv3rzZ83xrOnbs2OwKJqnl3p62hgj3+23ZssWrvaamRtu2bTtsPe3RrVs3uVwuffvtt17tRUVFKi0t9dn7tPS+UvPP52479H179Oih2267Te+8846++uor1dTU6PHHH/c65owzztBDDz2kdevW6aWXXtJ///tfLVq0yC/1A8crwg0QJqxWqy699FL985//1N/+9jfV1dU1CzcjR45UYWGh19ycuro6PfXUU+rQoYOGDRvW6uv36NFDZWVl+uKLLzxtu3fv9lxp1FRsbGyLQehQubm5stvtevLJJ716X55//nmVlZVp1KhRR3yNthg5cqQkqaCgwKv9iSeekCSfvc+hBg0apOTkZM2ZM8dr+Gj58uXatGmT530PHDigqqoqr3N79OihuLg4z3n79u1r1kPl3hqCoSmEGy4FB0LA8uXLPb0rTQ0ZMkTdu3f3PB4zZoyeeuopzZgxQ/369fPMpXG7/vrr9eyzz+rqq6/W+vXrlZmZqSVLlmj16tUqKChQXFxcqzVcfvnluvPOO3XRRRfpD3/4gw4cOKDZs2frf/7nf7RhwwavYwcOHKh3331XTzzxhNLT05WVlaXs7Oxmr9mlSxdNnTpV999/vy644AL95je/0ZYtW/TMM8/o9NNP95o8fCz69++vCRMmaO7cuSotLdWwYcO0du1aLViwQKNHj/aav9RetbW1+tOf/tSsvVOnTrrppps0c+ZMTZw4UcOGDdPYsWM9l4JnZmbq1ltvlSR98803Ovfcc3XZZZfplFNOUUREhJYuXaqioiLPZfwLFizQM888o4suukg9evRQRUWF5s2bp/j4eE94A8KGyVdrATgGh7sUXJIxf/58r+NdLpeRkZFhSDL+9Kc/tfiaRUVFxsSJE42kpCTDbrcb/fr1a/Y6htH8UnDDMIx33nnH6Nu3r2G3242TTz7Z+Pvf/97ipeCbN282fvWrXxnR0dGGJM9l4YdeCu729NNPG7169TIiIyONlJQU48YbbzT27dvndcywYcOMPn36NKuztUvUD1VbW2vcf//9RlZWlhEZGWlk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", + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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w4YN02effaaMjAy1aNFCl156qebNm6d9+/Z5Hcd93lar1TMr7Ntvv63wfu793KHkyy+/9DznXnagptw9aSd+5rm5uZo/f77Xfv3791fjxo01ffr0ClPZT+51GzBggGJiYvT000/riy++oPcH9Qo9QECA+uijjzy9NCfq06ePV8/JsGHD9OKLL2rq1Knq0qWLV2+HVLouy8svv6xbbrlFGzZsUEJCgt555x199dVXmjlzpmcgb2WGDx+uhx56SEOHDtU999yjY8eOafbs2frd736njRs3eu3bvXt3ffrpp5oxY4bi4+OVmJiopKSkCsds0aKFJkyYoMcee0xXX321rrnmGu3cuVP//Oc/1bNnT599iXbt2lVjxozRK6+8opycHPXr10/r16/XggULNGTIEF1++eW1PuaiRYtks9mqDE/XXHONHnnkES1ZskRpaWl64YUX1LdvX1100UW68847lZiYqJ9++kkffPCBNm3aJKl0Be1PPvlE/fr105133qnzzjtPmZmZevvtt7V69Wo1adJE/fv3V9u2bXXbbbfpgQcekM1m07x589SiRYsK4aoq/fv3l91u1+DBg/WnP/1JR48e1auvvqqWLVsqMzPTs19UVJSee+453X777erZs6duvvlmNW3aVJs3b9axY8e8QldoaKiGDx+ul156STabzWugPRDwTJyBBqAS1U2Dl2TMnz/fa3+Xy2W0adPGkGT87W9/q/SY2dnZRmpqqhETE2PY7XajS5cuFY5jGBWnwRuGYXzyySfG+eefb9jtdqNjx47GG2+8Uem07B07dhiXXnqpER4ebkjyTImvbKq2YZROez/33HON0NBQIzY21hg7dqzx22+/ee3Tr18/o3PnzhXqrGp6/smKi4uNxx57zEhMTDRCQ0ONNm3aGBMmTDAKCgoqHO9U0+CLioqM5s2bG5dcckm1+yUmJhoXXnih5/HWrVuNoUOHGk2aNDHCwsKMjh07GpMnT/Z6zd69e43Ro0cbLVq0MBwOh9G+fXtj3LhxRmFhoWefDRs2GElJSYbdbjfatm1rzJgxo8pp8IMGDaq0tvfee8+44IILjLCwMCMhIcF4+umnjXnz5lX67/Pee+8Zffr0McLDw42oqCijV69exptvvlnhmOvXrzckGf3796/2cwECjcUwajiSEACAk2zevFndunXT66+/rlGjRpldDlBj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l5enc889VzabTU6nU08++aRGjhxpdml+l5WVJUmV/k50PxdsCgoK9NBDD2nEiBFBc4PUp59+WiEhIbrnnntMeX8CEPxu3Lhx2rp1q1avXm12KX6zf/9+3XvvvVq5cqXCwsLMLsfvXC6XevTooWnTpkmSLrzwQm3dulVz5swJmgD01ltvadGiRVq8eLE6d+6sTZs2afz48YqPjw+azwCVKy4u1k033STDMDR79myzy/GLDRs26Pnnn9fGjRtlsVhMqYFLYH4QExMjm82m7Oxsr/bs7GzFxcWZVJU57r77bv3nP//RZ599prPOOsvscvxmw4YNOnDggC666CKFhIQoJCREX3zxhV544QWFhITI6XSaXWKdatWqlTp16uTVdt5552nfvn0mVeR/DzzwgB5++GENHz5cXbp00ahRo3Tfffdp+vTpZpfmd+7fe/xOLA8/e/fu1cqVK4Om9+e///2vDhw4oLZt23p+J+7du1d//etflZCQ4JcaCEB+YLfb1b17d6Wnp3vaXC6X0tPT1bt3bxMr8x/DMHT33Xfr3Xff1apVq5SYmGh2SX515ZVX6vvvv9emTZs8W48ePTRy5Eht2rRJNpvN7BLr1MUXX1xh2YP//e9/ateunUkV+d+xY8dktXr/yrXZbHK5XCZVZJ7ExETFxcV5/U7My8vTunXrguZ3olQefn744Qd9+umnat68udkl+c2oUaO0ZcsWr9+J8fHxeuCBB/Txxx/7pQYugflJWlqaxowZox49eqhXr16aOXOm8vPzlZqaanZpfjFu3DgtXrxY/+///T81btzYc50/Ojpa4eHhJldX9xo3blxhvFNkZKSaN28eFOOg7rvvPvXp00fTpk3TTTfdpPXr1+uVV17RK6+8YnZpfjN48GA9+eSTatu2rTp37qzvvvtOM2bM0K233mp2aXXi6NGj2rVrl+fxnj17tGnTJjVr1kxt27bV+PHj9be//U0dOnRQYmKiJk+erPj4eA0ZMsS8on2sus+gVatWuuGGG7Rx40b95z//kdPp9PxebNasmex2u1ll+8ypfgZODnyhoaGKi4tTx44d/VOg3+abwXjxxReNtm3bGna73ejVq5exdu1as0vyG0mVbvPnzze7NNME0zR4wzCM999/3zj//PMNh8NhnHvuucYrr7xidkl+lZeXZ9x7771G27ZtjbCwMKN9+/bGI488YhQWFppdWp347LPPKv1vfsyYMYZhlE6Fnzx5shEbG2s4HA7jyiuvNHbu3Glu0T5W3WewZ8+eKn8vfvbZZ2aX7hOn+hk4mb+nwVsMo4EuQwoAAFAFxgABAICgQwACAABBhwAEAACCDgEIAAAEHQIQAAAIOgQgAAAQdAhAAAAg6BCAAKAKFotFy5cvN7sMAHWAAAQgIN1yyy2yWCwVtquvvtrs0gA0ANwLDEDAuvrqqzV//nyvNofDYVI1ABoSeoAABCyHw6G4uDivrWnTppJKL0/Nnj1bAwYMUHh4uNq3b6933nnH6/Xff/+9rrjiCoWHh6t58+a68847dfToUa995s2bp86dO8vhcKhVq1a6++67vZ4/dOiQhg4dqoiICHXo0EHvvfee57nffvtNI0eOVIsWLRQeHq4OHTpUCGwAAhMBCEC9NXnyZF1//fXavHmzRo4cqeHDh2v79u2SpPz8fKWkpKhp06b65ptv9Pbbb+vTTz/1CjizZ8/WuHHjdOedd+r777/Xe++9p3POOcfrPR577DHddNNN2rJliwYOHKiRI0fq119/9bz/tm3b9NFHH2n79u2aPXu2YmJi/PcBADh9frvtKgDUwpgxYwybzWZERkZ6bU8++aRhGIYhybjrrru8XpOUlGSMHTvWMAzDeOWVV4ymTZsaR48e9Tz/wQcfGFar1cjKyjIMwzDi4+ONRx55pMoaJBmTJk3yPD569Kghyfjoo48MwzCMwYMHG6mpqb45YQB+xRggAAHr8ssv1+zZs73amjVr5vl77969vZ7r3bu3Nm3aJEnavn27unbtqsjISM/zF198sVwul3bu3CmLxaKMjAxdeeWV1dZwwQUXeP4eGRmpqKgoHThwQJI0duxYXX/99dq4caP69++vIUOGqE+fPqd1rgD8iwAEIGBFRkZWuCTlK+Hh4TXaLzQ01OuxxWKRy+WSJA0YMEB79+7Vhx9+qJUrV+rKK6/UuHHj9I9//MPn9QLwLcYAAai31q5dW+HxeeedJ0k677zztHnzZuXn53ue/+qrr2S1WtWxY0c1btxYCQkJSk9PP6MaWrRooTFjxuiNN97QzJkz9corr5zR8QD4Bz1AAAJWYWGhsrKyvNpCQkI8A43ffvtt9ejRQ3379tWiRYu0fv16zZ07V5I0cuRITZ06VWPGjNGjjz6qgwcP6i9/+YtGjRql2NhYSdKjjz6qu+66Sy1bttSAAQN05MgRffXVV/rLX/5So/qmTJmi7t27q3PnziosLNR//vMfTwADENgIQAAC1ooVK9SqVSuvto4dO2rHjh2SSmdoLVmyRH/+85/VqlUrvfnmm+rUqZMkKSIiQh9//LHuvfde9ezZUxEREbr++us1Y8YMz7HGjBmjgoICPffcc7r//vsVExOjG264ocb12e12TZgwQT/99JPCw8N1ySWXaMmSJT44cwB1zWIYhmF2EQBQWxaLRe+++66GDBlidikA6iHGAAEAgKBDAAIAAEGHMUAA6iWu3gM4E/QAAQCAoEMAAgAAQYcABAAAgg4BCAAABB0CEAAACDoEIAAAEHQIQAAAIOgQgAAAQNAhAAEAgKDz/wGDmZw3srwI9AAAAABJRU5ErkJggg==", + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "225/225 - 1s - 4ms/step - accuracy: 0.9286 - loss: 0.4360\n" + ] + } + ], + "source": [ + "from tensorflow.keras.models import Sequential\n", + "from tensorflow.keras.layers import Conv2D, Dense, MaxPool2D, Flatten, Rescaling, Dropout\n", + "from tensorflow.keras.losses import SparseCategoricalCrossentropy\n", + "\n", + "\n", + "CLASS_COUNT = int(np.max(train_label) + 1)\n", + "INPUT_SHAPE = train_data.shape[1]\n", + "BATCH_SIZE = 32#train_data.shape[0] // 4\n", + "EPOCHS = 15\n", + "\n", + "train_label = tf.keras.utils.to_categorical(train_label, CLASS_COUNT)\n", + "test_label = tf.keras.utils.to_categorical(test_label, CLASS_COUNT)\n", + "\n", + "model = Sequential()\n", + "model.add(Rescaling(1./255, input_shape=(INPUT_SHAPE, INPUT_SHAPE, 1)))\n", + "model.add(Conv2D(filters=32, kernel_size=3, padding=\"same\", activation='relu'))\n", + "model.add(MaxPool2D())\n", + "model.add(Conv2D(filters=64, kernel_size=3, padding=\"same\", activation='relu'))\n", + "model.add(MaxPool2D())\n", + "model.add(Flatten())\n", + "model.add(Dropout(0.5))\n", + "model.add(Dense(CLASS_COUNT, activation=\"softmax\"))\n", + "model.summary()\n", + "\n", + "model.compile(optimizer='adam', loss=\"categorical_crossentropy\", metrics=['accuracy'])\n", + "history = model.fit(train_data, train_label, batch_size=BATCH_SIZE, epochs=EPOCHS)\n", + "\n", + "plt.plot(history.history[\"loss\"])\n", + "plt.xlabel(\"Epochs\")\n", + "plt.ylabel(\"Loss value\")\n", + "plt.title(\"Evolution of Loss\")\n", + "plt.show()\n", + "\n", + "plt.plot(history.history[\"accuracy\"])\n", + "plt.xlabel(\"Epochs\")\n", + "plt.ylabel(\"Accuracy\")\n", + "plt.title(\"Evolution of Accuracy\")\n", + "plt.show()\n", + "\n", + "evaluate = model.evaluate(test_data, test_label, verbose=2) # ~58%\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Export as Keras model" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "model.save('sign_model.keras')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.8" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/src/PC/sign_model.keras b/src/pc/sign_model.keras similarity index 100% rename from src/PC/sign_model.keras rename to src/pc/sign_model.keras