NguyenTanPhucThinh/Anime_characters_recognition

Open Set Anime Character Classification aims to identify anime characters while detecting unseen classes that are absent from the training set. The model must correctly classify known characters and reject unknown ones, improving robustness in real-world scenarios.

1

stars

26

commits

Jupyter Notebook

primary language

Jul 28, 2026

updated

README

Machine Learning Project

Mô Tả Bài Toán

Dự án này nhằm giải quyết bài toán nhận diện nhân vật anime bằng cách sử dụng các mô hình học máy hiện đại.

Mục Tiêu Chính

  • Xây dựng và huấn luyện mô hình dự đoán/phân loại
  • Đạt được độ chính xác cao trên tập dữ liệu
  • Cải tiến mô hình và hỗ trợ nhận diện các nhân vật mới

Pipeline

flowchart TD
    A([🖼️ Ảnh đầu vào]) --> B

    subgraph S1["📦 Giai đoạn 1 — Thu thập & Tiền xử lý"]
        B[Thu thập dữ liệu\nGrabber Booru] --> C
        C[Lọc ảnh thủ công\nLoại ảnh không thỏa điều kiện] --> D
        D[Face detection & localization\nLoại background noise] --> E
        E[Resize & Normalize\n448×448 · normalize -1 to 1]
    end

    E --> F

    subgraph S2["🧠 Giai đoạn 2 — Huấn luyện mô hình"]
        F[ViT-Base model\nwd-vit-tagger-v3] --> G
        G[Transfer learning\nFine-tune · 45 nhân vật · 7k ảnh] --> H
        H[Lưu checkpoint\nbest_vit_model.pth] --> I & J
        I[Mô hình phân loại\nAccuracy / F1-Score]
        J[Trích xuất đặc trưng\nTạo embedding gallery]
    end

    I & J --> K

    subgraph S3["⚡ Giai đoạn 3 — Suy luận thời gian thực"]
        K([Ảnh query]) --> L
        L[Tiền xử lý\nMTCNN detect · crop · expand 20–30%] --> M
        M[ViT backbone frozen\nTrích xuất + L2-normalize CLS token] --> N & O
        N[Cosine similarity\nmax sim query vs gallery]
        O[Đầu phân loại\nXác suất softmax]
        N & O --> P{max_sim ≥ τ = 0.657?}
        P -->|Không| Q([❌ UNKNOWN])
        P -->|Có| R[Weighted fusion\nα · gallery + 1-α · cls_prob]
        R --> S([✅ Kết quả nhận diện\nchar_id + điểm tin cậy])
    end

    style S1 fill:#0d3b2e,stroke:#2fa882,color:#c8ede5
    style S2 fill:#1e1040,stroke:#6b5fbe,color:#d4cfee
    style S3 fill:#161624,stroke:#555570,color:#d0d0d8
    style Q fill:#7a2c18,stroke:#b04428,color:#f5c4b0
    style S fill:#1d7a5f,stroke:#2fa882,color:#c8ede5

Dataset

Bộ dữ liệu sử dụng trong dự án này có thể được tải xuống từ:

📊 Google Drive Dataset Link

Cấu Trúc Dataset

  • Số lượng mẫu: 7760 bức ảnh tổng thể trong đó, số lượng ảnh trong thư mục train: 6219 - Số lượng ảnh trong thư mục val: 755 - Số lượng ảnh trong thư mục test: 786
  • Nhãn/Classes: 45 classes

Cấu Trúc Dự Án

Dưới đây là cấu trúc hiện tại của repo và cách mình nên hiểu từng phần:

ML_code/
├── README.md
├── requirements.txt
├── config.yaml
├── main.py
├── data/
│   └── class_names.txt
├── notebooks/
│   └── main.ipynb
├── src/
│   ├── dataset.py
│   ├── eval.py
│   ├── inference.py
│   ├── model.py
│   ├── train.py
│   └── utils.py
├── assets/
│   └── model_link.txt
├── checkpoints/
│   └── best_vit_model.pth
├── embeddings/
├── outputs/
├── logs/
└── scripts/

Quy Ước Sử Dụng

  • main.py là entry point chính để chạy toàn bộ pipeline bằng CLI.
  • src/ chỉ nên chứa code xử lý, train, eval, inference và các hàm dùng lại.
  • notebooks/ dùng cho thử nghiệm, phân tích và trình bày kết quả.
  • data/ dành cho dữ liệu đầu vào hoặc file metadata như danh sách class.
  • assets/ chứa tài nguyên tĩnh như ghi chú, hình minh họa hoặc file tham khảo.
  • checkpoints/ chỉ nên dùng cho checkpoint mô hình.
  • embeddings/ lưu gallery, centroid và các file trung gian phục vụ open-set.
  • outputs/ lưu ảnh, biểu đồ và kết quả đánh giá.
  • logs/ dành cho log khi train hoặc chạy pipeline.
  • scripts/ là nơi để đặt các script tiện ích nếu sau này tách nhỏ luồng chạy.

Ghi Chú Ngắn

Nếu sau này repo lớn hơn, có thể tách thêm data/raw, data/processed, data/external để quản lý dữ liệu rõ hơn. Hiện tại, cấu trúc ở trên là đủ gọn và phù hợp với cách repo này đang chạy.

Yêu Cầu Môi Trường

  • Python 3.9+ (khuyến nghị 3.10)
  • pip
  • (Tùy chọn) môi trường ảo: venv/conda

Thiết lập nhanh (venv):

python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate
pip install -r requirements.txt

Các thư viện chính:

  • pandas
  • numpy
  • scikit-learn
  • torch (PyTorch)
  • matplotlib / seaborn

Hướng Dẫn Sử Dụng

Toàn bộ pipeline được điều phối qua main.py kết hợp file cấu hình config.yaml. Bạn có thể ghi đè bất kỳ tham số nào trong config.yaml bằng cách truyền trực tiếp qua CLI.

Lưu ý: Trước khi chạy, hãy kiểm tra lại các đường dẫn trong config.yaml cho khớp với máy của bạn, đặc biệt là data.input_dir, data.output_dir, và model.model_path.


Bước 1 — Tiền xử lý dataset

Crop khuôn mặt anime từ ảnh gốc và lưu thành cấu trúc split train/val/test.

python main.py preprocess --config config.yaml

Tham số có thể ghi đè:

ArgumentMặc định (từ config)Mô tả
--input_dir./data_splitThư mục dataset gốc theo dạng split
--output_dir./faces_splitThư mục xuất ảnh đã crop mặt
--cascade./lbpcascade_animeface.xmlFile cascade XML (tự tải nếu chưa có)
--splitstrain val testCác split cần xử lý

Ví dụ ghi đè:

python main.py preprocess --config config.yaml --input_dir ./my_data --splits train val

Bước 2 — Huấn luyện model

Fine-tune classification head của ViT backbone trên tập dữ liệu đã crop mặt.

python main.py train --config config.yaml

Tham số có thể ghi đè:

ArgumentMặc định (từ config)Mô tả
--train_dir./faces_split/trainThư mục ảnh train
--val_dir./faces_split/valThư mục ảnh validation
--model_nameSmilingWolf/wd-vit-tagger-v3Tên pretrained backbone trên HuggingFace
--epochs30Số epoch tối đa
--batch_size256Kích thước batch
--lr1e-5Learning rate
--patience5Số epoch chịu đựng khi val loss không cải thiện (early stopping)
--model_save_path./checkpoints/best_vit_model.pthĐường dẫn lưu checkpoint tốt nhất
--metrics_save_path./outputs/training_metrics.txtFile lưu kết quả metric
--plot_save_path./outputs/training_plots.pngFile lưu biểu đồ loss/accuracy
--num_workers-1 (auto)Số worker cho DataLoader (-1 = tự phát hiện)

Ví dụ chạy nhanh với batch nhỏ hơn:

python main.py train --config config.yaml --batch_size 64 --epochs 10

Trích xuất embedding từ tập train và biên soạn gallery centroid dùng cho open-set inference.

python main.py build_index --config config.yaml

Tham số có thể ghi đè:

ArgumentMặc định (từ config)Mô tả
--train_dir./faces_split/trainThư mục ảnh train để trích xuất
--model_nameSmilingWolf/wd-vit-tagger-v3Tên pretrained backbone
--model_path./checkpoints/best_vit_model.pthCheckpoint đã train
--gallery_dir./embeddingsThư mục lưu các file gallery
--num_classes45Số lớp của model đã train
--batch_size64Batch size khi trích xuất embedding

Các file được sinh ra trong ./embeddings/:

  • gallery_embeddings.npy — toàn bộ embedding theo ảnh
  • gallery_index.pkl — index ánh xạ embedding → class
  • class_centroids.npy — vector centroid trung bình mỗi lớp
  • class_names.pkl — danh sách tên các lớp

Bước 4 — Đánh giá

Đánh giá độ chính xác phân loại, open-set recognition và trực quan hóa embedding (t-SNE).

python main.py eval --config config.yaml

Tham số có thể ghi đè:

ArgumentMặc định (từ config)Mô tả
--eval_modeallChế độ đánh giá: accuracy / open_set / tsne / all
--test_dir./faces_split/testThư mục ảnh test
--model_nameSmilingWolf/wd-vit-tagger-v3Tên pretrained backbone
--model_path./checkpoints/best_vit_model.pthCheckpoint đã train
--gallery_dir./embeddingsThư mục chứa gallery index
--output_dir./outputsThư mục lưu biểu đồ và confusion matrix
--cascade./lbpcascade_animeface.xmlFile cascade XML
--num_known36Số lớp "known" dùng cho open-set split

Ví dụ chỉ đánh giá accuracy:

python main.py eval --config config.yaml --eval_mode accuracy

Ví dụ chỉ vẽ t-SNE:

python main.py eval --config config.yaml --eval_mode tsne

Lưu ý: run_eval luôn đọc class_names.pkl từ gallery_dir trước tiên ở tất cả các mode. Do đó bạn phải chạy build_index trước khi chạy eval, dù chỉ dùng --eval_mode accuracy.


Bước 5 — Dự đoán ảnh riêng lẻ

Nhận diện nhân vật từ một hoặc nhiều ảnh đầu vào qua dual-branch pipeline (cosine similarity + softmax fusion).

python main.py predict --config config.yaml --image_paths path/to/image1.jpg path/to/image2.jpg

Tham số có thể ghi đè:

ArgumentMặc định (từ config)Mô tả
--image_paths(bắt buộc)Một hoặc nhiều đường dẫn ảnh cần nhận diện
--model_nameSmilingWolf/wd-vit-tagger-v3Tên pretrained backbone
--model_path./checkpoints/best_vit_model.pthCheckpoint đã train
--gallery_dir./embeddingsThư mục chứa class_centroids.npyclass_names.pkl
--cascade./lbpcascade_animeface.xmlFile cascade XML
--threshold0.657Ngưỡng cosine similarity tối thiểu để chấp nhận kết quả (dưới ngưỡng → UNKNOWN)
--alpha0.7Trọng số kết hợp giữa gallery score và softmax probability

Ví dụ với nhiều ảnh và ghi đè ngưỡng (PowerShell):

python main.py predict --config config.yaml `
    --image_paths ./test1.jpg ./test2.jpg ./test3.jpg `
    --threshold 0.70

Ví dụ tương đương trên một dòng:

python main.py predict --config config.yaml --image_paths ./test1.jpg ./test2.jpg ./test3.jpg --threshold 0.70

Lưu ý: Cần chạy build_index trước để tạo file gallery trong ./embeddings/ trước khi dùng lệnh predict.


Chạy toàn bộ pipeline từ đầu đến cuối

python main.py preprocess --config config.yaml
python main.py train      --config config.yaml
python main.py build_index --config config.yaml
python main.py eval       --config config.yaml

Kết Quả

Pretrained Backbone và so sánh với Baseline model

Chúng tôi sử dụng SmilingWolf/wd-vit-tagger-v3 làm pretrained backbone thay vì baseline để so sánh, do sự khác biệt về domain và objective giữa hai task:

  • Model gốc được thiết kế cho general anime tagging trên ~10k class
  • Model của chúng tôi được fine-tune cho identity recognition trên 45 nhân vật cụ thể với open-set capability

Việc so sánh accuracy trực tiếp sẽ không phản ánh đúng bản chất của hai bài toán. Thay vào đó, chúng tôi đánh giá hiệu quả của transfer learning từ backbone pretrained sang task cụ thể.

  • Đường cong học ( epochs): loss giảm dần (train/val ~3.58 -> ~0.23), accuracy tăng dần (train ~0.11 -> ~0.95, val ~0.14 -> ~0.93).
  • Confusion matrix: đường chéo đậm rõ, đa số lớp được nhận đúng; một số lớp nhầm lẫn nhẹ ở ngoài đường chéo.
  • Phân tách known/unknown: phân bố cosine similarity tách biệt rõ; ngưỡng tối ưu $\tau$ ~0.66 để loại UNKNOWN.
  • Suy luận mẫu: các truy vấn minh họa cho thấy dự đoán đúng với độ tin cậy cao cho lớp known, UNKNOWN cho trường hợp ngoài lớp.

Loss curves

Accuracy curves

Confusion matrix

Confusion matrix (normalized)

Open-set metrics

Embedding visualization

Embedding visualization (alt)

Prediction samples

Ghi chú: các biểu đồ loss/accuracy, confusion matrix, và phân bố cosine similarity được vẽ trong notebooks/main.ipynb.

Nhận xét:

  • Tổng quan: Pipeline có tính hợp lý cho bài toán nhận diện nhân vật anime (ViT + fine-tune + embedding gallery + open-set gate). Các biểu đồ cho thấy mô hình đã học được biểu diễn có nghĩa.
  • Độ phân tách lớp: Confusion matrix tập trung trên đường chéo, và embedding visualization có xu hướng gom cụm theo lớp -> khả năng phân biệt tốt giữa các nhân vật chính.
  • Open-set: Histogram cosine similarity cho thấy có khoảng tách giữa known và unknown, phù hợp với cơ chế ngưỡng $\tau$ để từ chối nhân vật lạ.
  • Dấu hiệu cần cải thiện: Đường cong học vẫn tăng chậm và chưa hội tụ rõ ràng -> cần thêm dữ liệu, tăng epochs hợp lý, hoặc điều chỉnh learning rate/regularization.
  • Rủi ro: Mô hình có thể nhạy cảm với ảnh bị che mặt, góc mặt lạ, hoặc nhiều nhân vật có thiết kế giống nhau; cần đánh giá thêm trên tập test thực tế đa dạng.
  • Khuyến nghị: Thử tiền xử lý ổn định (face detect + align), bổ sung augmentations, và báo cáo thêm chỉ số macro-F1/Top-1 trên tập test độc lập.

Tác Giả

Nguyễn Tấn Phúc Thịnh - 24521696

Hướng Phát Triển

  • Thêm random_seed cố định để đảm bảo tính tái hiện (reproducibility)
  • Phân tích lỗi chi tiết (error analysis): xác định các lớp hay bị nhầm lẫn và nguyên nhân
  • Bổ sung augmentation (random flip, color jitter, rotation) để tăng độ bền mô hình
  • Thêm Makefile hoặc run.sh để chạy toàn bộ pipeline bằng một lệnh duy nhất
  • Mở rộng tập nhân vật và hỗ trợ thêm lớp mới mà không cần re-train toàn bộ
  • Triển khai demo lên Hugging Face Spaces

License

This project is licensed under the MIT License — see the LICENSE file for details.

Contributors

NguyenTanPhucThinh/Anime_characters_recognition

Open Set Anime Character Classification aims to identify anime characters while detecting unseen classes that are absent from the training set. The model must correctly classify known characters and reject unknown ones, improving robustness in real-world scenarios.

1

stars

26

commits

Jupyter Notebook

primary language

Jul 28, 2026

updated

README

Machine Learning Project

Mô Tả Bài Toán

Dự án này nhằm giải quyết bài toán nhận diện nhân vật anime bằng cách sử dụng các mô hình học máy hiện đại.

Mục Tiêu Chính

  • Xây dựng và huấn luyện mô hình dự đoán/phân loại
  • Đạt được độ chính xác cao trên tập dữ liệu
  • Cải tiến mô hình và hỗ trợ nhận diện các nhân vật mới

Pipeline

flowchart TD
    A([🖼️ Ảnh đầu vào]) --> B

    subgraph S1["📦 Giai đoạn 1 — Thu thập & Tiền xử lý"]
        B[Thu thập dữ liệu\nGrabber Booru] --> C
        C[Lọc ảnh thủ công\nLoại ảnh không thỏa điều kiện] --> D
        D[Face detection & localization\nLoại background noise] --> E
        E[Resize & Normalize\n448×448 · normalize -1 to 1]
    end

    E --> F

    subgraph S2["🧠 Giai đoạn 2 — Huấn luyện mô hình"]
        F[ViT-Base model\nwd-vit-tagger-v3] --> G
        G[Transfer learning\nFine-tune · 45 nhân vật · 7k ảnh] --> H
        H[Lưu checkpoint\nbest_vit_model.pth] --> I & J
        I[Mô hình phân loại\nAccuracy / F1-Score]
        J[Trích xuất đặc trưng\nTạo embedding gallery]
    end

    I & J --> K

    subgraph S3["⚡ Giai đoạn 3 — Suy luận thời gian thực"]
        K([Ảnh query]) --> L
        L[Tiền xử lý\nMTCNN detect · crop · expand 20–30%] --> M
        M[ViT backbone frozen\nTrích xuất + L2-normalize CLS token] --> N & O
        N[Cosine similarity\nmax sim query vs gallery]
        O[Đầu phân loại\nXác suất softmax]
        N & O --> P{max_sim ≥ τ = 0.657?}
        P -->|Không| Q([❌ UNKNOWN])
        P -->|Có| R[Weighted fusion\nα · gallery + 1-α · cls_prob]
        R --> S([✅ Kết quả nhận diện\nchar_id + điểm tin cậy])
    end

    style S1 fill:#0d3b2e,stroke:#2fa882,color:#c8ede5
    style S2 fill:#1e1040,stroke:#6b5fbe,color:#d4cfee
    style S3 fill:#161624,stroke:#555570,color:#d0d0d8
    style Q fill:#7a2c18,stroke:#b04428,color:#f5c4b0
    style S fill:#1d7a5f,stroke:#2fa882,color:#c8ede5

Dataset

Bộ dữ liệu sử dụng trong dự án này có thể được tải xuống từ:

📊 Google Drive Dataset Link

Cấu Trúc Dataset

  • Số lượng mẫu: 7760 bức ảnh tổng thể trong đó, số lượng ảnh trong thư mục train: 6219 - Số lượng ảnh trong thư mục val: 755 - Số lượng ảnh trong thư mục test: 786
  • Nhãn/Classes: 45 classes

Cấu Trúc Dự Án

Dưới đây là cấu trúc hiện tại của repo và cách mình nên hiểu từng phần:

ML_code/
├── README.md
├── requirements.txt
├── config.yaml
├── main.py
├── data/
│   └── class_names.txt
├── notebooks/
│   └── main.ipynb
├── src/
│   ├── dataset.py
│   ├── eval.py
│   ├── inference.py
│   ├── model.py
│   ├── train.py
│   └── utils.py
├── assets/
│   └── model_link.txt
├── checkpoints/
│   └── best_vit_model.pth
├── embeddings/
├── outputs/
├── logs/
└── scripts/

Quy Ước Sử Dụng

  • main.py là entry point chính để chạy toàn bộ pipeline bằng CLI.
  • src/ chỉ nên chứa code xử lý, train, eval, inference và các hàm dùng lại.
  • notebooks/ dùng cho thử nghiệm, phân tích và trình bày kết quả.
  • data/ dành cho dữ liệu đầu vào hoặc file metadata như danh sách class.
  • assets/ chứa tài nguyên tĩnh như ghi chú, hình minh họa hoặc file tham khảo.
  • checkpoints/ chỉ nên dùng cho checkpoint mô hình.
  • embeddings/ lưu gallery, centroid và các file trung gian phục vụ open-set.
  • outputs/ lưu ảnh, biểu đồ và kết quả đánh giá.
  • logs/ dành cho log khi train hoặc chạy pipeline.
  • scripts/ là nơi để đặt các script tiện ích nếu sau này tách nhỏ luồng chạy.

Ghi Chú Ngắn

Nếu sau này repo lớn hơn, có thể tách thêm data/raw, data/processed, data/external để quản lý dữ liệu rõ hơn. Hiện tại, cấu trúc ở trên là đủ gọn và phù hợp với cách repo này đang chạy.

Yêu Cầu Môi Trường

  • Python 3.9+ (khuyến nghị 3.10)
  • pip
  • (Tùy chọn) môi trường ảo: venv/conda

Thiết lập nhanh (venv):

python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate
pip install -r requirements.txt

Các thư viện chính:

  • pandas
  • numpy
  • scikit-learn
  • torch (PyTorch)
  • matplotlib / seaborn

Hướng Dẫn Sử Dụng

Toàn bộ pipeline được điều phối qua main.py kết hợp file cấu hình config.yaml. Bạn có thể ghi đè bất kỳ tham số nào trong config.yaml bằng cách truyền trực tiếp qua CLI.

Lưu ý: Trước khi chạy, hãy kiểm tra lại các đường dẫn trong config.yaml cho khớp với máy của bạn, đặc biệt là data.input_dir, data.output_dir, và model.model_path.


Bước 1 — Tiền xử lý dataset

Crop khuôn mặt anime từ ảnh gốc và lưu thành cấu trúc split train/val/test.

python main.py preprocess --config config.yaml

Tham số có thể ghi đè:

ArgumentMặc định (từ config)Mô tả
--input_dir./data_splitThư mục dataset gốc theo dạng split
--output_dir./faces_splitThư mục xuất ảnh đã crop mặt
--cascade./lbpcascade_animeface.xmlFile cascade XML (tự tải nếu chưa có)
--splitstrain val testCác split cần xử lý

Ví dụ ghi đè:

python main.py preprocess --config config.yaml --input_dir ./my_data --splits train val

Bước 2 — Huấn luyện model

Fine-tune classification head của ViT backbone trên tập dữ liệu đã crop mặt.

python main.py train --config config.yaml

Tham số có thể ghi đè:

ArgumentMặc định (từ config)Mô tả
--train_dir./faces_split/trainThư mục ảnh train
--val_dir./faces_split/valThư mục ảnh validation
--model_nameSmilingWolf/wd-vit-tagger-v3Tên pretrained backbone trên HuggingFace
--epochs30Số epoch tối đa
--batch_size256Kích thước batch
--lr1e-5Learning rate
--patience5Số epoch chịu đựng khi val loss không cải thiện (early stopping)
--model_save_path./checkpoints/best_vit_model.pthĐường dẫn lưu checkpoint tốt nhất
--metrics_save_path./outputs/training_metrics.txtFile lưu kết quả metric
--plot_save_path./outputs/training_plots.pngFile lưu biểu đồ loss/accuracy
--num_workers-1 (auto)Số worker cho DataLoader (-1 = tự phát hiện)

Ví dụ chạy nhanh với batch nhỏ hơn:

python main.py train --config config.yaml --batch_size 64 --epochs 10

Trích xuất embedding từ tập train và biên soạn gallery centroid dùng cho open-set inference.

python main.py build_index --config config.yaml

Tham số có thể ghi đè:

ArgumentMặc định (từ config)Mô tả
--train_dir./faces_split/trainThư mục ảnh train để trích xuất
--model_nameSmilingWolf/wd-vit-tagger-v3Tên pretrained backbone
--model_path./checkpoints/best_vit_model.pthCheckpoint đã train
--gallery_dir./embeddingsThư mục lưu các file gallery
--num_classes45Số lớp của model đã train
--batch_size64Batch size khi trích xuất embedding

Các file được sinh ra trong ./embeddings/:

  • gallery_embeddings.npy — toàn bộ embedding theo ảnh
  • gallery_index.pkl — index ánh xạ embedding → class
  • class_centroids.npy — vector centroid trung bình mỗi lớp
  • class_names.pkl — danh sách tên các lớp

Bước 4 — Đánh giá

Đánh giá độ chính xác phân loại, open-set recognition và trực quan hóa embedding (t-SNE).

python main.py eval --config config.yaml

Tham số có thể ghi đè:

ArgumentMặc định (từ config)Mô tả
--eval_modeallChế độ đánh giá: accuracy / open_set / tsne / all
--test_dir./faces_split/testThư mục ảnh test
--model_nameSmilingWolf/wd-vit-tagger-v3Tên pretrained backbone
--model_path./checkpoints/best_vit_model.pthCheckpoint đã train
--gallery_dir./embeddingsThư mục chứa gallery index
--output_dir./outputsThư mục lưu biểu đồ và confusion matrix
--cascade./lbpcascade_animeface.xmlFile cascade XML
--num_known36Số lớp "known" dùng cho open-set split

Ví dụ chỉ đánh giá accuracy:

python main.py eval --config config.yaml --eval_mode accuracy

Ví dụ chỉ vẽ t-SNE:

python main.py eval --config config.yaml --eval_mode tsne

Lưu ý: run_eval luôn đọc class_names.pkl từ gallery_dir trước tiên ở tất cả các mode. Do đó bạn phải chạy build_index trước khi chạy eval, dù chỉ dùng --eval_mode accuracy.


Bước 5 — Dự đoán ảnh riêng lẻ

Nhận diện nhân vật từ một hoặc nhiều ảnh đầu vào qua dual-branch pipeline (cosine similarity + softmax fusion).

python main.py predict --config config.yaml --image_paths path/to/image1.jpg path/to/image2.jpg

Tham số có thể ghi đè:

ArgumentMặc định (từ config)Mô tả
--image_paths(bắt buộc)Một hoặc nhiều đường dẫn ảnh cần nhận diện
--model_nameSmilingWolf/wd-vit-tagger-v3Tên pretrained backbone
--model_path./checkpoints/best_vit_model.pthCheckpoint đã train
--gallery_dir./embeddingsThư mục chứa class_centroids.npyclass_names.pkl
--cascade./lbpcascade_animeface.xmlFile cascade XML
--threshold0.657Ngưỡng cosine similarity tối thiểu để chấp nhận kết quả (dưới ngưỡng → UNKNOWN)
--alpha0.7Trọng số kết hợp giữa gallery score và softmax probability

Ví dụ với nhiều ảnh và ghi đè ngưỡng (PowerShell):

python main.py predict --config config.yaml `
    --image_paths ./test1.jpg ./test2.jpg ./test3.jpg `
    --threshold 0.70

Ví dụ tương đương trên một dòng:

python main.py predict --config config.yaml --image_paths ./test1.jpg ./test2.jpg ./test3.jpg --threshold 0.70

Lưu ý: Cần chạy build_index trước để tạo file gallery trong ./embeddings/ trước khi dùng lệnh predict.


Chạy toàn bộ pipeline từ đầu đến cuối

python main.py preprocess --config config.yaml
python main.py train      --config config.yaml
python main.py build_index --config config.yaml
python main.py eval       --config config.yaml

Kết Quả

Pretrained Backbone và so sánh với Baseline model

Chúng tôi sử dụng SmilingWolf/wd-vit-tagger-v3 làm pretrained backbone thay vì baseline để so sánh, do sự khác biệt về domain và objective giữa hai task:

  • Model gốc được thiết kế cho general anime tagging trên ~10k class
  • Model của chúng tôi được fine-tune cho identity recognition trên 45 nhân vật cụ thể với open-set capability

Việc so sánh accuracy trực tiếp sẽ không phản ánh đúng bản chất của hai bài toán. Thay vào đó, chúng tôi đánh giá hiệu quả của transfer learning từ backbone pretrained sang task cụ thể.

  • Đường cong học ( epochs): loss giảm dần (train/val ~3.58 -> ~0.23), accuracy tăng dần (train ~0.11 -> ~0.95, val ~0.14 -> ~0.93).
  • Confusion matrix: đường chéo đậm rõ, đa số lớp được nhận đúng; một số lớp nhầm lẫn nhẹ ở ngoài đường chéo.
  • Phân tách known/unknown: phân bố cosine similarity tách biệt rõ; ngưỡng tối ưu $\tau$ ~0.66 để loại UNKNOWN.
  • Suy luận mẫu: các truy vấn minh họa cho thấy dự đoán đúng với độ tin cậy cao cho lớp known, UNKNOWN cho trường hợp ngoài lớp.

Loss curves

Accuracy curves

Confusion matrix

Confusion matrix (normalized)

Open-set metrics

Embedding visualization

Embedding visualization (alt)

Prediction samples

Ghi chú: các biểu đồ loss/accuracy, confusion matrix, và phân bố cosine similarity được vẽ trong notebooks/main.ipynb.

Nhận xét:

  • Tổng quan: Pipeline có tính hợp lý cho bài toán nhận diện nhân vật anime (ViT + fine-tune + embedding gallery + open-set gate). Các biểu đồ cho thấy mô hình đã học được biểu diễn có nghĩa.
  • Độ phân tách lớp: Confusion matrix tập trung trên đường chéo, và embedding visualization có xu hướng gom cụm theo lớp -> khả năng phân biệt tốt giữa các nhân vật chính.
  • Open-set: Histogram cosine similarity cho thấy có khoảng tách giữa known và unknown, phù hợp với cơ chế ngưỡng $\tau$ để từ chối nhân vật lạ.
  • Dấu hiệu cần cải thiện: Đường cong học vẫn tăng chậm và chưa hội tụ rõ ràng -> cần thêm dữ liệu, tăng epochs hợp lý, hoặc điều chỉnh learning rate/regularization.
  • Rủi ro: Mô hình có thể nhạy cảm với ảnh bị che mặt, góc mặt lạ, hoặc nhiều nhân vật có thiết kế giống nhau; cần đánh giá thêm trên tập test thực tế đa dạng.
  • Khuyến nghị: Thử tiền xử lý ổn định (face detect + align), bổ sung augmentations, và báo cáo thêm chỉ số macro-F1/Top-1 trên tập test độc lập.

Tác Giả

Nguyễn Tấn Phúc Thịnh - 24521696

Hướng Phát Triển

  • Thêm random_seed cố định để đảm bảo tính tái hiện (reproducibility)
  • Phân tích lỗi chi tiết (error analysis): xác định các lớp hay bị nhầm lẫn và nguyên nhân
  • Bổ sung augmentation (random flip, color jitter, rotation) để tăng độ bền mô hình
  • Thêm Makefile hoặc run.sh để chạy toàn bộ pipeline bằng một lệnh duy nhất
  • Mở rộng tập nhân vật và hỗ trợ thêm lớp mới mà không cần re-train toàn bộ
  • Triển khai demo lên Hugging Face Spaces

License

This project is licensed under the MIT License — see the LICENSE file for details.

Contributors

Languages

Jupyter Notebook

99.3%