{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Retrieving speedtest.net configuration...\n", "Testing from VNPT (14.177.252.75)...\n", "Retrieving speedtest.net server list...\n", "Selecting best server based on ping...\n", "Hosted by Viettel IDC (Vinh) [261.88 km]: 10.311 ms\n", "Testing download speed................................................................................\n", "Download: 184.35 Mbit/s\n", "Testing upload speed......................................................................................................\n", "Upload: 202.71 Mbit/s\n" ] } ], "source": [ "import tensorflow as tf\n", "import matplotlib.pyplot as plt\n", "import h5py\n", "\n", "tf.get_logger().setLevel('ERROR')\n", "!curl -s https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py | python -" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "TRAIN_PATH = 'D:/UETCodeCamp/dataset/dataset/Images/Train'\n", "VALIDATE_PATH = 'D:/UETCodeCamp/dataset/dataset/Images/Validate'\n", "TEST_PATH = 'D:/UETCodeCamp/dataset/dataset/Images/Test'" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import os\n", "PATH = 'Models/ResNet152V2'\n", "\n", "BASE_MODEL_BEST = os.path.join(PATH, 'base_model_best.hdf5')\n", "BASE_MODEL_TRAINED = os.path.join(PATH, 'base_model_trained.hdf5')\n", "BASE_MODEL_FIG = os.path.join(PATH, 'base_model_fig.jpg')\n", "\n", "FINE_TUNE_MODEL_BEST = os.path.join(PATH, 'fine_tune_model_best.hdf5')\n", "FINE_TUNE_MODEL_TRAINED = os.path.join(PATH, 'fine_tune_model_trained.hdf5')\n", "FINE_TUNE_MODE_FIG = os.path.join(PATH, 'fine_tune_model_fig.jpg')" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "IMAGE_SIZE = (300, 300)\n", "BATCH_SIZE = 128" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n", "train_generator = ImageDataGenerator(\n", " rescale = 1./255,\n", " rotation_range = 40, \n", " width_shift_range = 0.2, \n", " height_shift_range = 0.2,\n", " shear_range = 0.2,\n", " zoom_range = 0.2,\n", " horizontal_flip = True\n", ")\n", "validate_generator = ImageDataGenerator(rescale=1./255)\n", "test_generator = ImageDataGenerator(rescale=1./255)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "d:\\UETCodeCamp\\Model\n" ] } ], "source": [ "print(os.getcwd())" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Found 18751 images belonging to 38 classes.\n", "Found 2757 images belonging to 38 classes.\n", "Found 5169 images belonging to 38 classes.\n" ] } ], "source": [ "generated_train_data = train_generator.flow_from_directory(TRAIN_PATH, target_size=IMAGE_SIZE, batch_size=BATCH_SIZE)\n", "generated_validate_data = validate_generator.flow_from_directory(VALIDATE_PATH, target_size=IMAGE_SIZE, batch_size=BATCH_SIZE)\n", "generated_test_data = test_generator.flow_from_directory(TEST_PATH, target_size=IMAGE_SIZE)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "CLASSES = 38\n", "INITIAL_EPOCHS = 15\n", "FINE_TUNE_EPOCHS = 15\n", "TOTAL_EPOCHS = INITIAL_EPOCHS + FINE_TUNE_EPOCHS\n", "FINE_TUNE_AT = 516" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "from tensorflow.keras.applications.resnet_v2 import ResNet152V2\n", "from tensorflow.keras.layers import GlobalAveragePooling2D, Dense, Dropout\n", "from tensorflow.keras.models import Model" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "pretrained_model = ResNet152V2(weights='imagenet', include_top=False)\n", "last_output = pretrained_model.output\n", "x = GlobalAveragePooling2D()(last_output)\n", "x = Dense(512, activation='relu')(x)\n", "x = Dropout(0.2)(x)\n", "outputs = Dense(CLASSES, activation='softmax')(x)\n", "model = Model(inputs=pretrained_model.input, outputs=outputs)\n" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint\n", "base_checkpointer = ModelCheckpoint(\n", " filepath=BASE_MODEL_BEST.replace('.hdf5', '.keras'), \n", " save_best_only=True, \n", " verbose=1\n", ")\n", "\n", "fine_tune_checkpointer = ModelCheckpoint(\n", " filepath=FINE_TUNE_MODEL_BEST.replace('.hdf5', '.keras'), \n", " save_best_only=True,\n", " verbose=1, \n", ")\n", "\n", "\n", "# Stop if no improvement after 3 epochs\n", "early_stopping = EarlyStopping(monitor='val_loss', patience=3, verbose=1)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "import os\n", "\n", "os.makedirs('Models/ResNet152V2', exist_ok=True)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "for layer in pretrained_model.layers: layer.trainable = False\n", "model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/15\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "c:\\Users\\VuongQuan14\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\keras\\src\\trainers\\data_adapters\\py_dataset_adapter.py:121: UserWarning: Your `PyDataset` class should call `super().__init__(**kwargs)` in its constructor. `**kwargs` can include `workers`, `use_multiprocessing`, `max_queue_size`. Do not pass these arguments to `fit()`, as they will be ignored.\n", " self._warn_if_super_not_called()\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m 55/146\u001b[0m \u001b[32m━━━━━━━\u001b[0m\u001b[37m━━━━━━━━━━━━━\u001b[0m \u001b[1m33:44\u001b[0m 22s/step - accuracy: 0.2474 - loss: 2.9693" ] }, { "name": "stderr", "output_type": "stream", "text": [ "c:\\Users\\VuongQuan14\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\PIL\\Image.py:1056: UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images\n", " warnings.warn(\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 24s/step - accuracy: 0.3447 - loss: 2.4622 \n", "Epoch 1: val_loss improved from inf to 1.41906, saving model to Models/ResNet152V2\\base_model_best.keras\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3788s\u001b[0m 26s/step - accuracy: 0.3453 - loss: 2.4589 - val_accuracy: 0.5796 - val_loss: 1.4191\n", "Epoch 2/15\n", "\u001b[1m 1/146\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m38:06\u001b[0m 16s/step - accuracy: 0.5469 - loss: 1.6239" ] }, { "name": "stderr", "output_type": "stream", "text": [ "c:\\Users\\VuongQuan14\\AppData\\Local\\Programs\\Python\\Python310\\lib\\contextlib.py:153: UserWarning: Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least `steps_per_epoch * epochs` batches. You may need to use the `.repeat()` function when building your dataset.\n", " self.gen.throw(typ, value, traceback)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Epoch 2: val_loss did not improve from 1.41906\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m24s\u001b[0m 59ms/step - accuracy: 0.5469 - loss: 1.6239 - val_accuracy: 0.5217 - val_loss: 1.6660\n", "Epoch 3/15\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 21s/step - accuracy: 0.5845 - loss: 1.3994 \n", "Epoch 3: val_loss improved from 1.41906 to 1.29527, saving model to Models/ResNet152V2\\base_model_best.keras\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3664s\u001b[0m 25s/step - accuracy: 0.5846 - loss: 1.3993 - val_accuracy: 0.6131 - val_loss: 1.2953\n", "Epoch 4/15\n", "\u001b[1m 1/146\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m1:11:06\u001b[0m 29s/step - accuracy: 0.5938 - loss: 1.2649\n", "Epoch 4: val_loss improved from 1.29527 to 1.22025, saving model to Models/ResNet152V2\\base_model_best.keras\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m50s\u001b[0m 143ms/step - accuracy: 0.5938 - loss: 1.2649 - val_accuracy: 0.6667 - val_loss: 1.2203\n", "Epoch 5/15\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 21s/step - accuracy: 0.6200 - loss: 1.2513 \n", "Epoch 5: val_loss improved from 1.22025 to 1.17931, saving model to Models/ResNet152V2\\base_model_best.keras\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3524s\u001b[0m 24s/step - accuracy: 0.6201 - loss: 1.2513 - val_accuracy: 0.6481 - val_loss: 1.1793\n", "Epoch 6/15\n", "\u001b[1m 1/146\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m38:32\u001b[0m 16s/step - accuracy: 0.6484 - loss: 1.1963\n", "Epoch 6: val_loss improved from 1.17931 to 1.05118, saving model to Models/ResNet152V2\\base_model_best.keras\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m30s\u001b[0m 95ms/step - accuracy: 0.6484 - loss: 1.1963 - val_accuracy: 0.6232 - val_loss: 1.0512\n", "Epoch 7/15\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 44s/step - accuracy: 0.6569 - loss: 1.1265 \n", "Epoch 7: val_loss did not improve from 1.05118\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m8147s\u001b[0m 56s/step - accuracy: 0.6569 - loss: 1.1265 - val_accuracy: 0.6715 - val_loss: 1.1207\n", "Epoch 8/15\n", "\u001b[1m 1/146\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m4:56:50\u001b[0m 123s/step - accuracy: 0.7188 - loss: 0.9636\n", "Epoch 8: val_loss did not improve from 1.05118\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m192s\u001b[0m 475ms/step - accuracy: 0.7188 - loss: 0.9636 - val_accuracy: 0.6667 - val_loss: 1.1370\n", "Epoch 9/15\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 20s/step - accuracy: 0.6758 - loss: 1.0515 \n", "Epoch 9: val_loss did not improve from 1.05118\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3502s\u001b[0m 23s/step - accuracy: 0.6758 - loss: 1.0515 - val_accuracy: 0.6864 - val_loss: 1.0649\n", "Epoch 9: early stopping\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] } ], "source": [ "history = model.fit(\n", " generated_train_data,\n", " validation_data = generated_validate_data,\n", " validation_steps = generated_validate_data.n // BATCH_SIZE,\n", " steps_per_epoch = generated_train_data.n // BATCH_SIZE,\n", " callbacks = [base_checkpointer, early_stopping],\n", " epochs = INITIAL_EPOCHS,\n", " verbose = 1,\n", ")\n", "model.save(BASE_MODEL_TRAINED)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(300, 300, 3)\n", "{'Banh beo': 0, 'Banh bot loc': 1, 'Banh can': 2, 'Banh canh': 3, 'Banh chung': 4, 'Banh cuon': 5, 'Banh duc': 6, 'Banh gio': 7, 'Banh khot': 8, 'Banh mi': 9, 'Banh pia': 10, 'Banh tet': 11, 'Banh trang nuong': 12, 'Banh xeo': 13, 'Bun bo Hue': 14, 'Bun dau mam tom': 15, 'Bun mam': 16, 'Bun rieu': 17, 'Bun thit nuong': 18, 'Bánh cu đơ': 19, 'Bánh mì cay': 20, 'Bánh đa cua': 21, 'Bánh đậu xanh': 22, 'Bò bía': 23, 'Bún cá': 24, 'Ca kho to': 25, 'Canh chua': 26, 'Cao lau': 27, 'Chao long': 28, 'Com tam': 29, 'Cơm cháy': 30, 'Goi cuon': 31, 'Hu tieu': 32, 'Mi quang': 33, 'Nem chua': 34, 'Nem nướng': 35, 'Pho': 36, 'Xoi xeo': 37}\n" ] } ], "source": [ "print(generated_train_data.image_shape)\n", "print(generated_train_data.class_indices)\n" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "\n", "for layer in pretrained_model.layers[:FINE_TUNE_AT]: layer.trainable = False\n", "for layer in pretrained_model.layers[FINE_TUNE_AT:]: layer.trainable = True" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "from tensorflow.keras.optimizers import SGD\n", "model.compile(\n", " optimizer = SGD(learning_rate=1e-4, momentum=0.9), \n", " loss = 'categorical_crossentropy', \n", " metrics = ['accuracy']\n", ")" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 9/30\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 25s/step - accuracy: 0.5182 - loss: 1.7415 \n", "Epoch 9: val_loss improved from inf to 1.11962, saving model to Models/ResNet152V2\\fine_tune_model_best.keras\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4345s\u001b[0m 30s/step - accuracy: 0.5186 - loss: 1.7399 - val_accuracy: 0.6819 - val_loss: 1.1196\n", "Epoch 10/30\n", "\u001b[1m 1/146\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m1:22:53\u001b[0m 34s/step - accuracy: 0.7031 - loss: 1.0933\n", "Epoch 10: val_loss did not improve from 1.11962\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m51s\u001b[0m 112ms/step - accuracy: 0.7031 - loss: 1.0933 - val_accuracy: 0.6667 - val_loss: 1.5291\n", "Epoch 11/30\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 33s/step - accuracy: 0.6629 - loss: 1.1745 \n", "Epoch 11: val_loss improved from 1.11962 to 1.06462, saving model to Models/ResNet152V2\\fine_tune_model_best.keras\n", "\u001b[1m146/146\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5206s\u001b[0m 35s/step - accuracy: 0.6630 - loss: 1.1742 - val_accuracy: 0.6886 - val_loss: 1.0646\n", "Epoch 11: early stopping\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] } ], "source": [ "history_fine = model.fit(\n", " generated_train_data,\n", " validation_data = generated_validate_data,\n", " validation_steps = generated_validate_data.n // BATCH_SIZE,\n", " steps_per_epoch = generated_train_data.n // BATCH_SIZE,\n", " epochs = TOTAL_EPOCHS,\n", " initial_epoch = history.epoch[-1],\n", " callbacks = [fine_tune_checkpointer, early_stopping],\n", " verbose = 1,\n", ")\n", "model.save(FINE_TUNE_MODEL_TRAINED)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m162/162\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1063s\u001b[0m 7s/step - accuracy: 0.6897 - loss: 1.0454\n", "Test accuracy: 0.6889146566390991\n" ] } ], "source": [ "loss, accuracy = model.evaluate(generated_test_data)\n", "print('Test accuracy:', accuracy)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: scipy in c:\\users\\vuongquan14\\appdata\\roaming\\python\\python310\\site-packages (1.10.1)\n", "Collecting scipy\n", " Downloading scipy-1.14.0-cp310-cp310-win_amd64.whl.metadata (60 kB)\n", "Requirement already satisfied: numpy<2.3,>=1.23.5 in c:\\users\\vuongquan14\\appdata\\local\\programs\\python\\python310\\lib\\site-packages (from scipy) (1.23.5)\n", "Downloading scipy-1.14.0-cp310-cp310-win_amd64.whl (44.8 MB)\n", " ---------------------------------------- 0.0/44.8 MB ? eta -:--:--\n", " --------------------------------------- 1.0/44.8 MB 7.1 MB/s eta 0:00:07\n", " ---- ----------------------------------- 5.0/44.8 MB 13.7 MB/s eta 0:00:03\n", " ----------- ---------------------------- 12.6/44.8 MB 22.5 MB/s eta 0:00:02\n", " ------------------ --------------------- 20.2/44.8 MB 26.0 MB/s eta 0:00:01\n", " ------------------------ --------------- 27.0/44.8 MB 27.1 MB/s eta 0:00:01\n", " ------------------------------ --------- 34.1/44.8 MB 28.1 MB/s eta 0:00:01\n", " ------------------------------------- -- 41.7/44.8 MB 29.5 MB/s eta 0:00:01\n", " ---------------------------------------- 44.8/44.8 MB 27.9 MB/s eta 0:00:00\n", "Installing collected packages: scipy\n", " Attempting uninstall: scipy\n", " Found existing installation: scipy 1.10.1\n", " Uninstalling scipy-1.10.1:\n", " Successfully uninstalled scipy-1.10.1\n", " Rolling back uninstall of scipy\n", " Moving to c:\\users\\vuongquan14\\appdata\\roaming\\python\\python310\\site-packages\\scipy-1.10.1-cp310-cp310-win_amd64.whl\n", " from C:\\Users\\VuongQuan14\\AppData\\Local\\Temp\\pip-uninstall-bxl8tsg7\\scipy-1.10.1-cp310-cp310-win_amd64.whl\n", " Moving to c:\\users\\vuongquan14\\appdata\\roaming\\python\\python310\\site-packages\\scipy-1.10.1.dist-info\\\n", " from C:\\Users\\VuongQuan14\\AppData\\Roaming\\Python\\Python310\\site-packages\\~cipy-1.10.1.dist-info\n", " Moving to c:\\users\\vuongquan14\\appdata\\roaming\\python\\python310\\site-packages\\scipy.libs\\\n", " from C:\\Users\\VuongQuan14\\AppData\\Roaming\\Python\\Python310\\site-packages\\~cipy.libs\n", " Moving to c:\\users\\vuongquan14\\appdata\\roaming\\python\\python310\\site-packages\\scipy\\\n", " from C:\\Users\\VuongQuan14\\AppData\\Roaming\\Python\\Python310\\site-packages\\~cipy\n", "Note: you may need to restart the kernel to use updated packages.\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING: Ignoring invalid distribution -cipy (c:\\users\\vuongquan14\\appdata\\local\\programs\\python\\python310\\lib\\site-packages)\n", "WARNING: Ignoring invalid distribution -cipy (c:\\users\\vuongquan14\\appdata\\local\\programs\\python\\python310\\lib\\site-packages)\n", "ERROR: Could not install packages due to an OSError: [WinError 5] Access is denied: 'c:\\\\Users\\\\VuongQuan14\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python310\\\\Lib\\\\site-packages\\\\scipy\\\\linalg\\\\cython_blas.cp310-win_amd64.pyd'\n", "Consider using the `--user` option or check the permissions.\n", "\n" ] } ], "source": [ "pip install --upgrade scipy\n" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Found 5169 images belonging to 38 classes.\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "c:\\Users\\VuongQuan14\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\keras\\src\\trainers\\data_adapters\\py_dataset_adapter.py:121: UserWarning: Your `PyDataset` class should call `super().__init__(**kwargs)` in its constructor. `**kwargs` can include `workers`, `use_multiprocessing`, `max_queue_size`. Do not pass these arguments to `fit()`, as they will be ignored.\n", " self._warn_if_super_not_called()\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m41/41\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m883s\u001b[0m 22s/step\n", " precision recall f1-score support\n", "\n", " Banh beo 0.84 0.71 0.77 129\n", " Banh bot loc 0.60 0.61 0.60 144\n", " Banh can 0.83 0.69 0.75 149\n", " Banh canh 0.44 0.37 0.40 193\n", " Banh chung 0.80 0.77 0.79 102\n", " Banh cuon 0.70 0.68 0.69 228\n", " Banh duc 0.41 0.20 0.27 133\n", " Banh gio 0.75 0.81 0.78 129\n", " Banh khot 0.69 0.83 0.76 167\n", " Banh mi 0.92 0.91 0.91 268\n", " Banh pia 0.86 0.84 0.85 89\n", " Banh tet 0.83 0.73 0.78 138\n", "Banh trang nuong 0.90 0.75 0.82 159\n", " Banh xeo 0.81 0.83 0.82 235\n", " Bun bo Hue 0.54 0.68 0.60 306\n", " Bun dau mam tom 0.90 0.90 0.90 184\n", " Bun mam 0.62 0.61 0.62 155\n", " Bun rieu 0.54 0.68 0.60 231\n", " Bun thit nuong 0.57 0.65 0.61 150\n", " Bánh cu đơ 0.68 0.72 0.70 18\n", " Bánh mì cay 0.82 0.64 0.72 14\n", " Bánh đa cua 0.50 0.21 0.30 14\n", " Bánh đậu xanh 0.91 0.59 0.71 17\n", " Bò bía 0.57 0.42 0.48 19\n", " Bún cá 0.00 0.00 0.00 13\n", " Ca kho to 0.86 0.86 0.86 136\n", " Canh chua 0.62 0.63 0.62 165\n", " Cao lau 0.60 0.67 0.63 124\n", " Chao long 0.71 0.73 0.72 215\n", " Com tam 0.77 0.81 0.79 189\n", " Cơm cháy 0.81 0.72 0.76 18\n", " Goi cuon 0.78 0.78 0.78 172\n", " Hu tieu 0.46 0.38 0.42 197\n", " Mi quang 0.55 0.75 0.63 177\n", " Nem chua 0.67 0.55 0.61 109\n", " Nem nướng 0.56 0.56 0.56 16\n", " Pho 0.55 0.48 0.51 162\n", " Xoi xeo 0.89 0.77 0.83 105\n", "\n", " accuracy 0.69 5169\n", " macro avg 0.68 0.65 0.66 5169\n", " weighted avg 0.69 0.69 0.69 5169\n", "\n" ] } ], "source": [ "from sklearn.metrics import classification_report\n", "import numpy as np\n", "\n", "\n", "# Sử dụng generator để dự đoán nhãn cho dữ liệu kiểm tra\n", "generated_test_data = test_generator.flow_from_directory(TEST_PATH, target_size=IMAGE_SIZE, batch_size=BATCH_SIZE, shuffle=False)\n", "\n", "# Dự đoán nhãn\n", "predictions = model.predict(generated_test_data)\n", "y_pred = np.argmax(predictions, axis=1)\n", "y_true = generated_test_data.classes\n", "\n", "# Tính toán và in ra các chỉ số\n", "class_labels = list(generated_test_data.class_indices.keys())\n", "report = classification_report(y_true, y_pred, target_names=class_labels)\n", "print(report)\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.10.9" } }, "nbformat": 4, "nbformat_minor": 2 }