{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":90822,"databundleVersionId":10606680,"sourceType":"competition"}],"dockerImageVersionId":30839,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-01-15T15:44:57.608054Z","iopub.execute_input":"2025-01-15T15:44:57.608542Z","iopub.status.idle":"2025-01-15T15:45:03.907991Z","shell.execute_reply.started":"2025-01-15T15:44:57.608504Z","shell.execute_reply":"2025-01-15T15:45:03.905509Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Import các thư viện \nimport os\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import (Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization)\nfrom tensorflow.keras.callbacks import ModelCheckpoint\nimport matplotlib.pyplot as plt\nimport pandas as pd\nimport seaborn as sns\nfrom sklearn.metrics import confusion_matrix, classification_report","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-15T15:56:03.568011Z","iopub.execute_input":"2025-01-15T15:56:03.568399Z","iopub.status.idle":"2025-01-15T15:56:03.575095Z","shell.execute_reply.started":"2025-01-15T15:56:03.568369Z","shell.execute_reply":"2025-01-15T15:56:03.573542Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Đường dẫn tới dataset\nbase_dir = '/kaggle/input'\ntrain_dir = os.path.join(base_dir, '/kaggle/input/ai-tranining-hutech-1/training_set')\nst_dir = os.path.join(base_dir, '/kaggle/input/ai-tranining-hutech-1/test_set')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-15T15:56:05.549479Z","iopub.execute_input":"2025-01-15T15:56:05.549886Z","iopub.status.idle":"2025-01-15T15:56:05.55471Z","shell.execute_reply.started":"2025-01-15T15:56:05.549856Z","shell.execute_reply":"2025-01-15T15:56:05.553575Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Kiểm tra sự tồn tại của thư mục và in danh sách các tệp tin trong đó\nimport os\n\n# Kiểm tra thư mục train_set\nif os.path.exists(train_dir):\n    print(\"Training set:\", os.listdir(train_dir))\nelse:\n    print(\"Không tìm thấy thư mục train_set.\")\n\n# Kiểm tra thư mục test_set\nif os.path.exists(test_dir):\n    print(\"Test set:\", os.listdir(test_dir))\nelse:\n    print(\"Không tìm thấy thư mục test_set.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-15T15:56:07.616282Z","iopub.execute_input":"2025-01-15T15:56:07.616661Z","iopub.status.idle":"2025-01-15T15:56:07.624408Z","shell.execute_reply.started":"2025-01-15T15:56:07.616614Z","shell.execute_reply":"2025-01-15T15:56:07.623328Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Khởi tạo ImageDataGenerator cho dữ liệu huấn luyện và kiểm tra\ntrain_datagen = ImageDataGenerator(rescale=1./255)  # Chuẩn hóa ảnh trong khoảng [0, 1]\ntest_datagen = ImageDataGenerator(rescale=1./255)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-15T15:56:11.488231Z","iopub.execute_input":"2025-01-15T15:56:11.488568Z","iopub.status.idle":"2025-01-15T15:56:11.493544Z","shell.execute_reply.started":"2025-01-15T15:56:11.488541Z","shell.execute_reply":"2025-01-15T15:56:11.492264Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n# Khởi tạo ImageDataGenerator với các tham số chuẩn hóa và tăng cường dữ liệu\ntrain_datagen = ImageDataGenerator(\n    rescale=1./255,  # Chuẩn hóa dữ liệu (chia pixel cho 255)\n    rotation_range=40,  # Xoay ngẫu nhiên trong khoảng 40 độ\n    width_shift_range=0.2,  # Dịch chuyển chiều rộng ngẫu nhiên\n    height_shift_range=0.2,  # Dịch chuyển chiều cao ngẫu nhiên\n    shear_range=0.2,  # Biến dạng cắt\n    zoom_range=0.2,  # Phóng to hoặc thu nhỏ ngẫu nhiên\n    horizontal_flip=True,  # Lật ngang ngẫu nhiên\n    fill_mode='nearest'  # Cách điền vào các pixel trống sau khi xoay hoặc dịch chuyển\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-15T15:56:13.589767Z","iopub.execute_input":"2025-01-15T15:56:13.590107Z","iopub.status.idle":"2025-01-15T15:56:13.595535Z","shell.execute_reply.started":"2025-01-15T15:56:13.590079Z","shell.execute_reply":"2025-01-15T15:56:13.594106Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Nếu bạn có dữ liệu kiểm tra (test), bạn có thể chỉ cần chuẩn hóa mà không cần tăng cường\ntest_datagen = ImageDataGenerator(rescale=1./255)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-15T15:56:15.853692Z","iopub.execute_input":"2025-01-15T15:56:15.85404Z","iopub.status.idle":"2025-01-15T15:56:15.858218Z","shell.execute_reply.started":"2025-01-15T15:56:15.854013Z","shell.execute_reply":"2025-01-15T15:56:15.857274Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Tạo train_generator với dữ liệu tăng cường và chuẩn hóa\ntrain_generator = train_datagen.flow_from_directory(\n    '/kaggle/input/ai-tranining-hutech-1/training_set',  # Đường dẫn đến thư mục train_set\n    target_size=(224, 224),  # Thay đổi kích thước hình ảnh\n    batch_size=32,\n    class_mode='binary'  # Phân loại nhị phân (nếu có 2 lớp)\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-15T15:56:17.655072Z","iopub.execute_input":"2025-01-15T15:56:17.655423Z","iopub.status.idle":"2025-01-15T15:56:19.879978Z","shell.execute_reply.started":"2025-01-15T15:56:17.655396Z","shell.execute_reply":"2025-01-15T15:56:19.878916Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Tạo test_generator chỉ với chuẩn hóa\ntest_generator = test_datagen.flow_from_directory(\n    '/kaggle/input/ai-tranining-hutech-1/test_set',  # Đường dẫn đến thư mục test_set\n    target_size=(224, 224),  # Thay đổi kích thước hình ảnh\n    batch_size=32,\n    class_mode='binary'  # Phân loại nhị phân (nếu có 2 lớp)\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-15T15:56:21.308146Z","iopub.execute_input":"2025-01-15T15:56:21.308502Z","iopub.status.idle":"2025-01-15T15:56:22.442818Z","shell.execute_reply.started":"2025-01-15T15:56:21.308474Z","shell.execute_reply":"2025-01-15T15:56:22.4418Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Đọc và tạo dữ liệu kiểm tra từ thư mục\nval_generator = test_datagen.flow_from_directory(\n    '/kaggle/input/ai-tranining-hutech-1/training_set',  # Đường dẫn đến thư mục dữ liệu kiểm tra\n    target_size=(224, 224),  # Thay đổi kích thước ảnh về (224, 224)\n    batch_size=32,\n    class_mode='binary'  # 'binary' hoặc 'categorical' tùy thuộc vào bài toán\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-15T15:56:40.006843Z","iopub.execute_input":"2025-01-15T15:56:40.007225Z","iopub.status.idle":"2025-01-15T15:56:40.465884Z","shell.execute_reply.started":"2025-01-15T15:56:40.007162Z","shell.execute_reply":"2025-01-15T15:56:40.464622Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras import layers, models\n\n# Xây dựng mô hình CNN\nmodel = models.Sequential([\n    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(224, 224, 3)),\n    layers.MaxPooling2D((2, 2)),\n    layers.Conv2D(64, (3, 3), activation='relu'),\n    layers.MaxPooling2D((2, 2)),\n    layers.Conv2D(128, (3, 3), activation='relu'),\n    layers.MaxPooling2D((2, 2)),\n    \n    layers.Flatten(),\n    layers.Dense(128, activation='relu'),\n    layers.Dense(1, activation='sigmoid')  # Sử dụng 'sigmoid' cho phân loại nhị phân\n])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-15T15:57:02.20899Z","iopub.execute_input":"2025-01-15T15:57:02.209335Z","iopub.status.idle":"2025-01-15T15:57:02.330293Z","shell.execute_reply.started":"2025-01-15T15:57:02.209309Z","shell.execute_reply":"2025-01-15T15:57:02.328976Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Biên dịch mô hình\nmodel.compile(optimizer='adam', \n              loss='binary_crossentropy',  # Loss function cho phân loại nhị phân\n              metrics=['accuracy'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-15T15:57:04.982892Z","iopub.execute_input":"2025-01-15T15:57:04.983297Z","iopub.status.idle":"2025-01-15T15:57:04.992856Z","shell.execute_reply.started":"2025-01-15T15:57:04.983264Z","shell.execute_reply":"2025-01-15T15:57:04.991721Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Huấn luyện mô hình\nhistory = model.fit(\n    train_generator,\n    epochs=10,  # Số lần lặp lại trên toàn bộ dữ liệu huấn luyện\n   validation_data=val_generator  # Sử dụng dữ liệu kiểm tra để đánh giá mô hình trong mỗi epoch\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-15T15:57:16.903516Z","iopub.execute_input":"2025-01-15T15:57:16.90386Z","iopub.status.idle":"2025-01-15T17:49:33.492118Z","shell.execute_reply.started":"2025-01-15T15:57:16.903833Z","shell.execute_reply":"2025-01-15T17:49:33.490591Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Đánh giá mô hình trên dữ liệu kiểm tra\ntest_loss, test_acc = model.evaluate(val_generator, verbose=2)\nprint(f\"Test accuracy: {test_acc}\")\n\n# Vẽ đồ thị huấn luyện và mất mát\nimport matplotlib.pyplot as plt\n\n# Đồ thị độ chính xác trong quá trình huấn luyện\nplt.plot(history.history['accuracy'], label='Training Accuracy')\nplt.plot(history.history['val_accuracy'], label='Validation Accuracy')\nplt.title('Model Accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend(loc='lower right')\nplt.show()\n\n# Đồ thị mất mát trong quá trình huấn luyện\nplt.plot(history.history['loss'], label='Training Loss')\nplt.plot(history.history['val_loss'], label='Validation Loss')\nplt.title('Model Loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend(loc='upper right')\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-15T17:51:31.10949Z","iopub.execute_input":"2025-01-15T17:51:31.10989Z","iopub.status.idle":"2025-01-15T17:54:00.422293Z","shell.execute_reply.started":"2025-01-15T17:51:31.10986Z","shell.execute_reply":"2025-01-15T17:54:00.421089Z"}},"outputs":[],"execution_count":null}]}