# Thực hiện sinh chú giải ảnh bằng mô hình EN-DE, C[aA]RNet!
Convolutional(and|Attention)RecurrentNet! Mục tiêu của dự án là xây dựng một mô hình Neural để sinh chú giải cho ảnh.
Với một bộ dữ liệu, một mạng thần kinh gồm:
- Bộ mã hóa (Encoder - Mạng Neural Residual đã được huấn luyện trước)
- Bộ giải mã (Decoder - Mô hình LSTM)
Sẽ biểu diễn ảnh trong một không gian do bộ mã hóa xác định, biểu diễn này được đưa vào bộ giải mã (theo nhiều cách khác nhau) để học sinh ra chú thích,
liên kết với ảnh và các từ đã sinh ra ở mỗi bước thời gian bởi LSTM.
Bạn có thể xem bảng mục lục dưới đây:
Trong thư mục ẩn
.savedcó thể tìm thấy tất cả các phiên bản đã huấn luyện của C[aA]RNet. - Link: source deploy
- Một hiện thực Pythonic cho Bài toán Chú thích Ảnh, C[aA]RNet!
- Mục lục
- Kiến thức tiền đề
- Cách chạy mã nguồn
- Pipeline Dữ liệu
- Script sinh ra những gì
- Cấu trúc dự án
- Quy trình huấn luyện
- Thí nghiệm cá nhân
- Tài liệu tham khảo
Để hiểu rõ hơn về mã nguồn và thông tin bên trong, vì repo này hướng tới việc dễ hiểu cho cả người mới tò mò lẫn người đã có chuyên môn, bạn nên tham khảo các tài liệu sau:
-Tài liệu Pytorch -Mạng Neural Tích chập (Stanford Edu) -Mạng Neural Hồi tiếp (Stanford Edu) -Mạng Neural Residual (D2L AI)
Mã nguồn có thể chạy trên mọi hệ điều hành, bạn có thể dùng bất kỳ hệ điều hành nào. Tuy nhiên, một máy cấu hình cao là bắt buộc, vì lượng dữ liệu lớn có thể gây lỗi hết bộ nhớ trên máy yếu. Lưu ý rằng bạn cần tải bộ dữ liệu trước khi chạy và nó phải đúng định dạng yêu cầu Cách chuẩn bị dataset cho huấn luyện C[aA]RNet?
- Tải về bộ dữ liệu đã được vietsub từ Kaggle Flickr30k.
- Giải nén vào thư mục gốc của repo.
- Đổi tên thư mục thành dataset
- Đổi tên thư mục ảnh thành images
Nếu bạn có trường hợp đặc biệt, có thể chỉnh file VARIABLE.py và/hoặc một số tham số tùy chọn trước khi chạy script (Giải thích CLI ).
Mã nguồn sẵn sàng chạy với mọi phiên bản python lớn hơn 3.6. Như bạn sẽ thấy trong mã, một số tiện ích không có ở python <3.9. Các trường hợp này đều có chú thích trong mã, bạn có thể chọn bật/tắt theo ý muốn.
| Thư viện | Phiên bản |
|---|---|
| Torch | 1.3.0+cu100 |
| Torchvision | 0.4.1+cu100 |
| Pillow | 8.4.0 |
| Numpy | 1.19.5 |
| Pandas | 1.1.5 |
| Matplotlib | 3.3.4 |
Trong thư mục gốc có file requirements.txt, bạn có thể cài tất cả các package cần thiết vào môi trường (hoặc v.env.) bằng lệnh sau, chạy trong shell với môi trường đã kích hoạt:
# VN Captioning
39317fbf606aad6a55c26429a30d4b4d1c206329
https://drive.google.com/file/d/1Y9nuHtmO0p0Jd2lvzIF5euiemkJHJ2IU/view?usp=drive_linkpython main.py RNetvI train 0 1024 --dataset_folder ./dataset --device cuda:0 --epochs 150python main.py RNetvH train 1024 1024 --dataset_folder ./dataset --device cuda:0 --epochs 150python main.py RNetvHC train 1024 1024 --dataset_folder ./dataset --device cuda:0 --epochs 150python main.py RNetvHCAttention train 1024 1024 --dataset_folder ./dataset --device cuda:0 --epochs 150 --attention t --attention_dim 1024python eval.py RNetvI eval 5078 1024 --image_path ./33465647.jpgpython eval.py RNetvH eval 1024 1024 --image_path ./33465647.jpgpython eval.py RNetvHC eval 1024 1024 --image_path ./33465647.jpgpython eval.py RNetvHCAttention eval 1024 1024 --attention t --attention_dim 1024 --image_path ./33465647.jpgpython eval.py RNetvHCAttention eval 1024 1024 --attention t --attention_dim 1024 --dataset_folder ./testset --output_csv ./testset/caption_test4.csv📄 File
results.csvsẽ được tạo trong đường dẫn--output_csv, theo định dạng:image_name| comment_number| comment.
python bleu_newest.py ./caption_test.csv ./results.csvSo sánh giữa nhãn thực tế (
caption_test.csv) và dự đoán từ mô hình (results.csv).
📁 Chú ý cấu trúc thư mục:
./dataset/hoặc./testset/images/(thư mục chứa ảnh)results.csv(file chú thích, phân tách bằng dấu|)
<<<<<<< HEAD
Như bạn đã thấy ở phần CLI, mã nguồn hỗ trợ GPU (chỉ NVIDIA hiện tại). Bạn cần cài driver CUDA, để đồng bộ với torch trong requirements.txt và driver, bạn nên cài NVIDIA driver v440 + Cuda 10.2.
Để hiểu rõ hơn về những gì xảy ra trong script, hãy hình dung pipeline dữ liệu như sau:
- Dataset: chứa tất cả các ví dụ (chưa tách train/test/val)
- Vocabulary: mỗi ví dụ có caption, nên cần một từ điển chứa tất cả các từ.
- C[aA]RNet: mạng neural, chưa phân biệt có/không Attention.
Giải thích chi tiết về từng thành phần ở các phần sau.
Hiện tại chỉ cần biết script cần 3 thành phần này để làm việc với dữ liệu.

- T_0: Load dataset
- T_1:
- a) Dataset được chuyển thành Dataloader (lớp của pytorch).
- b) Tạo từ điển từ dataset.
- T_2: Tạo dataloader
- T_3: C[aA]RNet dùng cả dataloader và vocabulary để huấn luyện, khi đánh giá chỉ dùng vocabulary vì dataloader size 1.
Cách định nghĩa Dataset theo cấu trúc của bộ Flickr30k Image Dataset: https://www.kaggle.com/hsankesara/flickr-image-dataset
Cấu trúc filesystem như sau:
dataset/ ├─ images/ │ ├─ pippo_pluto_paperino.jpg ├─ results.csv
Thư mục images chứa các ảnh jpeg, tên không có dấu cách.
pippo_pluto_paperino.jpg
File chứa các caption. Vì caption có thể chứa dấu phẩy (,) , nên ký tự phân tách là dấu gạch đứng (|). Dòng đầu là header, các cột như sau:
| Tham số | Kiểu | Mô tả |
|---|---|---|
image_name |
string |
Tên file ảnh tương ứng |
comment_number |
int |
Chỉ số của caption |
comment* |
string |
Caption |
*Caption nên tách từ bằng dấu cách. Dấu chấm (".") đánh dấu kết thúc caption.
Vì dự án còn phát triển tiếp, nên cần mô tả các output chính:
- Output trong quá trình huấn luyện.
- Output khi đánh giá.
Sinh ra các output sau:
- Mỗi mini-batch của mỗi epoch: lưu loss và accuracy vào Dataframe.
- Mỗi epoch, lưu accuracy trên tập validation vào Dataframe.
- Mỗi epoch, lưu một caption sinh ra từ ảnh cuối cùng của batch cuối cùng trong validation.
- Mỗi khi đạt accuracy tốt nhất trên validation, lưu model vào bộ nhớ.
Dataframe lưu thành file train_results.csv cuối mỗi epoch, cấu trúc:
| Tham số | Kiểu | Mô tả |
|---|---|---|
| Epoch | int |
ID của epoch |
| Batch | int |
ID của batch |
| Loss | float |
Loss của batch |
| Accuracy | float |
Accuracy của batch |
Dataframe lưu thành file validation_results.csv cuối mỗi epoch, cấu trúc:
| Tham số | Kiểu | Mô tả |
|---|---|---|
| Epoch | int |
ID của epoch |
| Accuracy | float |
Accuracy trên validation |
Trích đặc trưng từ ảnh cuối của batch cuối validation, đưa vào net ở chế độ eval. Sinh file caption.png gồm caption sinh ra và ảnh gốc. Nếu có attention, sinh thêm attention.png thể hiện attention cho từng từ.
Mỗi khi đạt accuracy tốt nhất trên validation, lưu model vào bộ nhớ.
Thư mục lưu là .saved ở gốc repo.
Pattern file:
- Encoder: NetName_encoderdim_hiddendim_attentiondim_C,pth
- Decoder: NetName_encoderdim_hiddendim_attentiondim_R,pth
Các tham số này phụ thuộc vào cấu hình khi huấn luyện.
Ảnh được load, tiền xử lý, đưa vào C[aA]RNet. Sinh file caption.png gồm caption sinh ra và ảnh gốc. Nếu có attention, sinh thêm attention.png thể hiện attention cho từng từ.
Cấu trúc dự án tính đến khả năng mở rộng từ cộng đồng hoặc cá nhân.
Sơ đồ dưới đây chỉ mang tính tổng quát, thể hiện các thực thể và quan hệ phụ thuộc.
Mỗi phương thức đều có docstring, hãy dùng làm tài liệu tham khảo.
Cấu trúc filesystem như sau:
C[aA]RNet/
├─ .saved/
├─ dataset/
│ ├─ images/
│ ├─ results.csv
├─ NeuralModels/
│ ├─ Attention/
│ │ ├─ IAttention.py
│ │ ├─ SoftAttention.py
│ ├─ Decoder/
│ │ ├─ IDecoder.py
│ │ ├─ RNetvH.py
│ │ ├─ RNetvHC.py
│ │ ├─ RNetvHCAttention.py
│ │ ├─ RNetvI.py
│ ├─ Encoder/
│ │ ├─ IEncoder.py
│ │ ├─ CResNet50.py
│ │ ├─ CResNet50Attention.py
│ ├─ CaARNet.py
│ ├─ Dataset.py
│ ├─ FactoryModels.py
│ ├─ Metrics.py
│ ├─ Vocabulary.py
├─ VARIABLE.py
├─ main.py
| File | Mô tả |
|---|---|
VARIABLE.py |
Giá trị hằng dùng trong dự án |
main.py |
Điểm vào để chạy net |
IAttention.py |
Interface cho attention mới |
SoftAttention.py |
Hiện thực Soft Attention |
IDecoder.py |
Interface cho decoder mới |
RNetvH.py |
Hiện thực decoder LSTM H-version |
RNetvHC.py |
Hiện thực decoder LSTM HC-version |
RNetvHCAttention.py |
Hiện thực decoder LSTM HC-version với Attention |
IEncoder.py |
Interface cho encoder mới |
CResNet50.py |
ResNet50 làm encoder |
CResNet50Attention.py |
ResNet50 cho attention |
CaRNet.py |
Hiện thực C[aA]RNet |
Dataset.py |
Quản lý dataset |
FactoryModels.py |
Factory Pattern cho các mô hình |
Metrics.py |
Sinh file báo cáo |
Vocabulary.py |
Quản lý từ điển |
Interface dùng để định nghĩa hợp đồng cho ai muốn hiện thực Encoder, Decoder hoặc Attention mới. Tuân thủ interface là bắt buộc, docstring có gợi ý tham số cho từng phương thức.
Hai encoder dựa trên ResNet50 (He et al. 2015, Deep Residual Learning for Image Recognition). Tùy có dùng attention hay không, sẽ bỏ một hoặc nhiều lớp cuối của net gốc.
(Kiến trúc mạng ResNet-50 [56].) Privacy-Constrained Biometric System for Non-Cooperative Users
Bản 1 bỏ lớp cuối của ResNet50, để lộ GlobalAveragePooling. Sau pooling là một lớp tuyến tính kích thước encoder_dim, nhận đầu vào là output của AveragePooling (ResNet50 là 2048).
Bản 2 bỏ 2 lớp cuối của ResNet50 (AveragePooling + FC), để lộ lớp tích chập cuối cho tensor dạng: (Heigth/32, Width/32, 2048). Mỗi vùng là một vector 2048 chiều. Với ảnh RGB vuông (3,224,224) thì tổng số vùng là 49.
Decoder dựa trên RNN, cụ thể là LSTM (Long-Short Term Memory), một loại RNN cập nhật trạng thái ẩn đặc biệt.

Mỗi mô hình xuất phát từ ý tưởng này và thử các cách khác nhau để đưa context ảnh từ encoder vào:
- RNetvI: Context ảnh là input đầu tiên của LSTM tại t_0.
- RNetvH: Context ảnh được đưa vào hidden state tại t_0.
- RNetvHC: Context ảnh đưa vào cả hidden và cell state tại t_0.
- RNetvHCAttention: Context ảnh đưa vào hidden và cell state, mỗi bước t nối thêm vector attention vào input LSTM.
Bản 1 dùng context ảnh làm input đầu tiên của lstm.

Ràng buộc duy nhất là context ảnh phải chiếu vào không gian embedding từ.
RNetvH khởi tạo hidden state tại t_0 bằng context ảnh từ ResNet.

RNetvHC khởi tạo cả hidden và cell state tại t_0 bằng context ảnh từ ResNet

Bản này kết hợp RNetvHC với Attention.

Quy trình huấn luyện gồm tập train và tập validation.
- Tập train được chia thành các mini-batch (tham số) và xáo trộn.
- Với mỗi mini-batch:
- Đưa batch vào encoder để sinh context vector cho từng phần tử.
- Giả sử tensor caption (đã chuyển thành vector id từ vocabulary) của batch ảnh được padding bằng 0 và sắp xếp giảm dần theo độ dài.
- Context vector và caption được đưa vào Decoder.
- Output decoder là input cho pack_padded_sequence, loại bỏ vùng pad của mỗi caption.
- Tính loss, backpropagation và cập nhật trọng số.
- Với mỗi mini-batch:
- Đánh giá accuracy trên tập validation.
- Nếu có model tốt nhất mới, lưu lại model.
Hàm mất mát dùng là CrossEntropyLoss, vì pytorch nội bộ dùng soft-max trên mỗi output t (output lstm có kích thước bằng vocab, ta muốn chọn từ xác suất cao nhất) và NegativeLogLikelihood.
Với p_t:Hàm mất mát theo paper (Vinyals et al. 2014) Show and Tell: A Neural Image Caption Generator
Với attention, thêm một thành phần vào loss: double stochastic regularization.
Điều này khuyến khích model chú ý đều đến mọi phần của ảnh trong quá trình sinh caption.Dưới đây là các lần huấn luyện tôi đã thực hiện, các model pretrained nằm trong thư mục .saved
- (Vinyals et al. 2014) Show and Tell: A Neural Image Caption Generator
- (Xu et al. 2015) Show, Attend and Tell: Neural Image Caption Generation with Visual Attention
- Tài liệu, mã nguồn và bài giảng của Giáo sư Stefano Melacci
eval_app.py là ứng dụng web sử dụng Streamlit để đánh giá mô hình sinh chú thích ảnh tiếng Việt với các mô hình CaRNet. Ứng dụng hỗ trợ hai chế độ:
- Ảnh đơn: Cho phép người dùng tải lên một ảnh, sinh caption và hiển thị kết quả trực tiếp.
- Toàn bộ thư mục: Đánh giá tự động tất cả ảnh trong một thư mục, xuất kết quả ra file CSV.
Các tính năng chính:
- Chọn mô hình CaRNet (vI, vH, vHC, vHCAttention) và giao diện sáng/tối.
- Tùy chọn chế độ đánh giá (ảnh đơn hoặc thư mục).
- Hiển thị logo, tiêu đề, mô tả ứng dụng.
- Tự động tải và cấu hình mô hình phù hợp.
- Tính điểm BLEU cho caption.
- Lưu kết quả đánh giá hàng loạt vào file
eval_results.csv.
Ứng dụng giúp kiểm thử, trình diễn và đánh giá nhanh hiệu quả các mô hình sinh chú thích ảnh trong dự án.
- @Thisorp ======= 💡 Lưu ý thêm:
--attention tdùng để bật chế độ attention cho mô hìnhCaRNetvHCAttention.--attention_dimnên để 1024 (mặc định khuyến nghị).- Nếu không cung cấp
--image_path, chương trình sẽ duyệt toàn bộ thư mụcimages/.




