Xây dựng Hệ thống Phân loại Chó Mèo với ResNet18: Từ Xử lý Dữ liệu đến Triển khai Web

1. Giới thiệu Dự án

Dự án này triển khai một hệ thống phân loại ảnh chó và mèo sử dụng học sâu (deep learning) với kỹ thuật học chuyển giao (transfer learning). Mục tiêu là xây dựng một quy trình hoàn chỉnh từ thu thập dữ liệu, tiền xử lý, huấn luyện mô hình, đánh giá, cho đến triển khai ứng dụng web. Mô hình sử dụng ResNet18 đạt độ chính xác 98,2% trên tập kiểm tra.

2. Dữ liệu và Tiền xử lý

2.1 Nguồn dữ liệu

  • Tập dữ liệu chính: Bộ dữ liệu Microsoft Cats and Dogs (12.500 ảnh, mỗi loài 6.250 ảnh).
  • Dữ liệu bổ sung: 200 ảnh tự chụp từ điện thoại với nhiều góc độ và điều kiện ánh sáng khác nhau.

2.2 Quy trình xử lý

Làm sạch dữ liệu

Loại bỏ 4 file bị lỗi, tổng số ảnh hợp lệ là 12.499 ảnh cho mỗi loại.

Chia tập dữ liệu

LoạiTập huấn luyệnTập kiểm traTổng
Mèo9.9992.50012.499
Chó9.9992.50012.499

Tăng cường dữ liệu (Data Augmentation)

transforms_augment = transforms.Compose([
    transforms.RandomCrop(224),
    transforms.RandomHorizontalFlip(),
    transforms.RandomRotation(10),
    transforms.ColorJitter(brightness=0.2, contrast=0.2),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

Các kỹ thuật được áp dụng: cắt ngẫu nhiên (224×224), lật ngang (50%), xoay ngẫu nhiên (±10 độ), điều chỉnh độ sáng/tương phản.

3. Xây dựng và Huấn luyện Mô hình

3.1 Lựa chọn Framework

FrameworkƯu điểmNhược điểmLựa chọn
PyTorchĐồ thị tính động dễ gỡ lỗi, API trực quanHỗ trợ mobile kémPhù hợp cho phát triển nhanh
TensorFlowTriển khai sản xuất mạnh mẽĐồ thị tĩnh khó gỡ lỗiKhông được chọn

3.2 Kiến trúc Mô hình

Sử dụng ResNet18 với học chuyển giao (transfer learning):

model = models.resnet18(pretrained=True)

# Đóng băng các lớp tích chập
for param in model.parameters():
    param.requires_grad = False

# Tùy chỉnh lớp kết nối đầy đủ
model.fc = nn.Sequential(
    nn.Linear(512, 256),
    nn.ReLU(),
    nn.Dropout(0.5),
    nn.Linear(256, 2)
)

Luồng dữ liệu: Ảnh đầu vào (224×224×3) → Các lớp tích chập ResNet18 (đóng băng) → Global Average Pooling → FC (512→256, ReLU) → Dropout (0.5) → Đầu ra (256→2, xác suất Mèo/Chó).

3.3 Tinh chỉnh Siêu tham số

Thử nghiệmBộ tối ưuTốc độ họcBatch SizeSố epochĐộ chính xác
1SGD0.01321092.1%
2Adam0.001641596.8%
3Adam0.001321598.2%

Tham số cuối cùng:
- Hàm mất mát: CrossEntropyLoss
- Bộ tối ưu: Adam (lr=0.001)
- Lịch trình tốc độ học: StepLR (giảm 0.1 lần sau mỗi 3 epoch)
- Batch Size: 32
- Số epoch: 15

3.4 Xử lý Overfitting

Phát hiện: Sau epoch thứ 5, loss trên tập kiểm tra bắt đầu tăng, chênh lệch độ chính xác giữa huấn luyện và kiểm tra lên đến 4,3%.

Giải pháp:

# Tăng cường regularization
nn.Dropout(0.7)  # Tăng tỷ lệ Dropout

# Cơ chế dừng sớm (early stopping)
if val_loss > best_loss * 1.1:
    early_stop_counter += 1
    if early_stop_counter >= 2:
        break

Các biện pháp: tăng Dropout lên 0.7; thêm cơ chế dừng sớm (patience=2); bổ sung kỹ thuật che ngẫu nhiên (random occlusion) trong tăng cường dữ liệu.

3.5 Kết quả Huấn luyện

Biểu đồ loss và độ chính xác trên tập huấn luyện và kiểm tra được trực quan hóa. Kết quả cuối cùng:
- Độ chính xác trên tập huấn luyện: 99,3%
- Độ chính xác trên tập kiểm tra: 98,2%

3.6 Đánh giá Mô hình

Chỉ sốMèoChóTrung bình
Precision98,5%97,9%98,2%
Recall97,8%98,6%98,2%
F1-score98,1%98,2%98,15%

4. Triển khai Giao diện Web

4.1 Xây dựng API với Gradio

def phan_loai_anh(img):
    # Tiền xử lý
    transform = transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ])

    # Dự đoán
    img_tensor = transform(img).unsqueeze(0).to(device)
    with torch.no_grad():
        probabilities = torch.nn.functional.softmax(model(img_tensor)[0], dim=0)

    return {'Mèo': float(probabilities[0]), 'Chó': float(probabilities[1])}

# Tạo giao diện
interface = gr.Interface(
    fn=phan_loai_anh,
    inputs=gr.Image(type="pil"),
    outputs=gr.Label(num_top_classes=2),
    examples=[anh_meo_1, anh_meo_2, anh_cho_1, anh_cho_2],
    title="Phân loại Chó Mèo"
)
interface.launch(share=True)

4.2 Chức năng Giao diện

  • Khu vực tải lên: Cho phép kéo/thả hoặc nhấp để chọn ảnh.
  • Ảnh mẫu: Các nút để kiểm tra nhanh.
  • Kết quả: Hiển thị xác suất Mèo/Chó theo thời gian thực.
  • Thời gian phản hồi: Dưới 1 giây (trên GPU T4).

5. So sánh và Khuyến nghị Thuật toán

5.1 Các mô hình thay thế

MobileNet: Nhẹ (4,2 triệu tham số), giảm tính toán nhờ tích chập phân tách chiều sâu (depthwise separable convolution), phù hợp cho thiết bị di động.

5.2 Khuyến nghị

Trường hợp sử dụngMô hình đề xuấtTốc độ suy luậnĐộ chính xác
Triển khai máy chủResNet5045ms>99%
Thiết bị biên (edge)MobileNetV318ms96%
Dự án hiện tạiResNet1828ms98,2%

Thẻ: ResNet18 PyTorch gradio Transfer Learning Image Classification

Đăng vào ngày 11 tháng 6 lúc 04:29