Giới thiệu dự án
Chẩn đoán hình ảnh X-quang ngực (Chest X-Ray - CXR) là kỹ thuật sàng lọc không xâm lấn cơ bản và phổ biến nhất trong y khoa nhằm phát hiện các bệnh lý về tim mạch, phổi và thành ngực. Theo thống kê của Tổ chức Y tế Thế giới (WHO), các bệnh lý hô hấp như viêm phổi, lao phổi, tràn dịch màng phổi và bệnh phổi kẽ (ILD) chiếm hàng triệu ca tử vong mỗi năm trên toàn cầu. Tuy nhiên, áp lực quá tải tại các cơ sở khám chữa bệnh cùng tính chất phức tạp của hình ảnh chiếu tia X hai chiều (2D projection) thường dẫn đến rủi ro bỏ sót tổn thương hoặc chẩn đoán sai lệch, đặc biệt ở các tổn thương nhỏ hoặc bệnh nhân có nhiều tổn thương phối hợp.
+-----------------------------------------------------------------------------------+
| TIẾN TRÌNH KHÓA LUẬN TỐT NGHIỆP |
| |
| [ImageNet-21k] ---> [CheXpert / Chest14] ---> [VinDr-CXR (10 Classes)] |
| (Pre-trained) (Domain Transfer) (Fine-tuning) |
| | |
| v |
| [Docker Deployment] <--- [Flask RESTful API] <--- [ViT vs ResNet Engine] |
| (Containerization) (Twilio / SQLite) (Attention Map / Grad-CAM) |
+-----------------------------------------------------------------------------------+
Vấn đề cốt lõi (Problem Statement) trong bài toán phân loại bệnh phổi tự động hiện nay nằm ở hiện tượng đồng xuất hiện nhiều tổn thương bệnh lý (multi-label co-occurrence) tại các vị trí giải phẫu cách xa nhau trên cùng một phim chụp X-quang. Các mô hình mạng nơ-ron tích chập (Convolutional Neural Networks - CNNs) truyền thống với cơ chế trường tiếp nhận cục bộ (local receptive fields) gặp hạn chế lớn trong việc thiết lập mối tương quan không gian tầm xa (long-range dependencies) giữa các vùng tổn thương phân tán. Hơn nữa, việc thiếu khả năng diễn giải minh bạch (model interpretability) khiến các hệ thống AI dạng "hộp đen" khó nhận được sự tin tưởng từ đội ngũ y bác sĩ lâm sàng.
Nhằm giải quyết triệt để các rào cản trên, đề tài khóa luận "Ứng dụng mô hình Vision Transformer trong phân loại dữ liệu bệnh phổi" đặt ra 3 mục tiêu cụ thể:
- Nghiên cứu, huấn luyện và tinh chỉnh các biến thể kiến trúc Vision Transformer (ViT-B16, ViT-L16, ViT-S16, R50+ViT-B16) thông qua chiến lược học chuyển giao đa tầng (multi-stage transfer learning) trên các bộ dữ liệu ảnh y tế chuẩn hóa CheXpert, Chest14 và VinDr-CXR.
- Đánh giá định lượng hiệu năng phân loại đa nhãn và phân tích định tính khả năng giải thích quyết định của mô hình bằng cơ chế Attention Map, đặt trong tương quan so sánh trực tiếp với các mô hình CNN (ResNet-18, ResNet-34, ResNet-50) và kỹ thuật Grad-CAM.
- Thiết kế, đóng gói và triển khai một hệ thống phần mềm hoàn chỉnh gồm Web Application và RESTful API bằng Flask, SQLite/SQLAlchemy, tích hợp dịch vụ thông báo kết quả qua Email/Twilio SMS và container hóa toàn bộ môi trường bằng Docker.
Phương pháp tiếp cận dựa trên Vision Transformer tận dụng cơ chế tự chú ý đa đầu (Multi-Head Self-Attention - MSA), cho phép mô hình xem xét toàn bộ các mảng ảnh (patches) đồng thời, từ đó nắm bắt mối liên kết chẩn đoán giữa các vùng bệnh lý xa nhau trên trường phổi. Kết quả kỳ vọng là xây dựng thành công một mô hình đạt độ chính xác tương đương hoặc vượt trội CNN, khả năng định vị tổn thương chính xác và hệ thống ứng dụng phản hồi dự đoán trong thời gian từ 2 đến 10 giây.
Phạm vi nghiên cứu giới hạn ở tập dữ liệu ảnh chụp X-quang ngực tư thế thẳng sau - trước (Posterior-Anterior - PA view) trên 10 nhóm bệnh lý phổi chính được chuẩn hóa từ tập dữ liệu VinDr-CXR. Ứng dụng đóng vai trò là công cụ hỗ trợ ra quyết định lâm sàng (Clinical Decision Support System - CDSS), không thay thế hoàn toàn bác sĩ chuyên khoa chẩn đoán hình ảnh.
Phân tích và thiết kế giải pháp
Phân tích hiện trạng
Trước khi kiến trúc Transformer thâm nhập vào thị giác máy tính, CNN là lựa chọn mặc định cho hầu hết các giải pháp phân loại ảnh y tế. Tuy nhiên, việc áp dụng CNN bộc lộ nhiều điểm nghẽn kỹ thuật khi đối mặt với dữ liệu bệnh học phổi phức tạp.
| Tiêu chí phân tích |
Giải pháp truyền thống (CNN: ResNet, VGG, DenseNet) |
Giải pháp đề xuất (Vision Transformer: ViT) |
| Cơ chế biểu diễn không gian |
Tích chập cục bộ (Local convolution kernels: $3 \times 3, 5 \times 5, 7 \times 7$) |
Tự chú ý toàn cục (Global Multi-Head Self-Attention) |
| Long-range Dependencies |
Bị giới hạn bởi kích thước kernel và số tầng sâu |
Nắm bắt trực tiếp quan hệ giữa mọi patch $P \times P$ trên toàn ảnh |
| Độ nhạy với dữ liệu đa tổn thương |
Kém hiệu quả khi các tổn thương phân tán đa ổ |
Vượt trội nhờ cơ chế phân bổ trọng số chú ý đa vùng |
| Yêu cầu dữ liệu huấn luyện |
Thấp hơn nhờ Inductive Bias mạnh mẽ |
Cần chiến lược Pre-training quy mô lớn trên tập dữ liệu y tế |
| Phương pháp giải thích quyết định |
Grad-CAM (dựa trên Gradient tại tầng tích chập cuối) |
Attention Map (dựa trên ma trận phân phối trọng số chú ý trực tiếp) |
Nhu cầu người dùng được phân loại theo mô hình MoSCoW:
- Must-have (Bắt buộc): Chức năng tải ảnh X-quang định dạng chuẩn; phân loại tự động 10 bệnh lý phổi; trực quan hóa bản đồ chú ý Attention Map; quản lý hồ sơ thông tin bệnh nhân cơ bản.
- Should-have (Cần có): Gửi báo cáo kết quả và kết luận của bác sĩ qua Email và tin nhắn SMS (Twilio); đóng gói phần mềm thành Docker Image độc lập nền tảng.
- Could-have (Có thể có): Giao thức kết nối trực tiếp đến hệ thống lưu trữ và truyền hình ảnh PACS qua chuẩn DICOM; tùy chỉnh ngưỡng xác suất phân loại (Confidence Threshold).
- Won't-have (Tạm thời chưa làm): Chức năng phân đoạn ảnh (Semantic Segmentation) từng điểm ảnh tổn thương; hệ thống phân quyền đa người dùng cấp bệnh viện (Enterprise RBAC).
Thiết kế hệ thống
Kiến trúc hệ thống được xây dựng theo mô hình phân tầng module hóa (Layered Modular Architecture) nhằm đảm bảo tính độc lập và khả năng mở rộng linh hoạt:
+-----------------------------------------------------------------------------------+
| PRESENTATION LAYER |
| Client Web UI (HTML5, CSS3, JavaScript) |
+------------------------------------------+----------------------------------------+
| HTTP / REST Request
v
+-----------------------------------------------------------------------------------+
| APPLICATION / API LAYER |
| Flask Web Application (Python 3.9) |
| +---------------------+ +----------------------+ +--------------------------+ |
| | Patient Controller | | Inference Controller | | Notification Controller | |
| +---------------------+ +----------------------+ +--------------------------+ |
+---------------------+--------------------+--------------------+-------------------+
| | |
v v v
+-----------------------------+ +--------------------+ +----------------------------+
| PERSISTENCE LAYER | | AI INFERENCE CORE | | EXTERNAL SERVICES |
| SQLite & SQLAlchemy (ORM) | | PyTorch 1.10 (ViT)| | Twilio API (SMS) & SMTP |
| - Patients & Medical Logs | | - Model Inference | | - Email/SMS Notification |
| | | - Attention Maps | | |
+-----------------------------+ +--------------------+ +----------------------------+
Technology Stack chi tiết:
- Ngôn ngữ lập trình: Python
3.9.12
- Deep Learning Framework: PyTorch
1.10.2, Torchvision 0.11.3, Timm 0.5.4
- Xử lý ma trận & Dữ liệu: NumPy
1.21.6, Pandas 1.3.5, OpenCV-Python 4.5.5.64, PIL 9.0.1
- Web Backend & ORM: Flask
2.0.3, Werkzeug 2.0.3, SQLAlchemy 1.4.31, Flask-SQLAlchemy 2.5.1
- Dịch vụ thông báo: Twilio SDK
7.8.0 (SMS), SMTPlib (Email notification)
- Containerization & Deployment: Docker Engine
20.10.12, Docker Compose 1.29.2, Gunicorn 20.1.0
Thiết kế Cơ sở dữ liệu quan hệ (SQLite via SQLAlchemy ORM):
- Bảng
Patient: id (INTEGER, Primary Key), patient_code (VARCHAR(50), Unique), full_name (VARCHAR(100)), phone_number (VARCHAR(15)), email (VARCHAR(100)), created_at (DATETIME).
- Bảng
DiagnosticRecord: id (INTEGER, Primary Key), patient_id (INTEGER, Foreign Key), image_path (VARCHAR(255)), attention_map_path (VARCHAR(255)), predictions (JSON/TEXT), doctor_notes (TEXT), created_at (DATETIME).
Thiết kế RESTful API:
POST /api/v1/patient/register: Đăng ký thông tin bệnh nhân mới.
POST /api/v1/predict: Tiếp nhận tệp ảnh X-quang, tiền xử lý và trả về JSON xác suất 10 nhãn bệnh kèm URL Attention Map.
POST /api/v1/notify/send: Gửi thông điệp chẩn đoán qua SMS/Email dựa trên ID hồ sơ bệnh án.
Methodology
Quy trình nghiên cứu và phát triển được thực hiện theo phương pháp luân phiên thử nghiệm thực nghiệm (Iterative Empirical Research) kết hợp mô hình Agile trong 16 tuần:
| Giai đoạn (Milestone) |
Thời gian |
Nhiệm vụ kỹ thuật chính |
Sản phẩm đầu ra (Deliverables) |
| Giai đoạn 1: Chuẩn bị & Dữ liệu |
Tuần 1 - 2 |
Thu thập, trích xuất metadata DICOM, lọc 10 nhãn từ VinDr-CXR, CheXpert, Chest14 |
Tập dữ liệu huấn luyện/kiểm thử chuẩn hóa định dạng PNG |
| Giai đoạn 2: Huấn luyện & Đánh giá |
Tuần 3 - 6 |
Cài đặt ViT và ResNet, huấn luyện phân loại đa nhãn, trích xuất Attention Map / Grad-CAM |
Trọng số mô hình (checkpoints), bảng số liệu AUC-ROC, F1-score |
| Giai đoạn 3: Phát triển Ứng dụng |
Tuần 7 - 11 |
Xây dựng REST API, Web UI, tích hợp ORM SQLite, Twilio SMS và Email |
Ứng dụng web Flask hoàn chỉnh chức năng |
| Giai đoạn 4: Đóng gói & Triển khai |
Tuần 12 - 16 |
Viết Dockerfile, tối ưu hóa image, kiểm thử độc lập trên máy chủ mới, hoàn thiện báo cáo |
Docker Image trên DockerHub, báo cáo khóa luận tốt nghiệp |
Chiến lược quản trị rủi ro:
- Rủi ro quá khớp (Overfitting) trên dữ liệu y tế quy mô vừa: Khắc phục bằng kỹ thuật Data Augmentation (Random Rotation, Random Crop, Horizontal Flip, ColorJitter) và áp dụng cơ chế học chuyển giao 2 pha (Domain-adaptive Pre-training).
- Rủi ro tiêu tốn bộ nhớ tính toán: Cân bằng kích thước Batch Size và độ phân giải hình ảnh ($224 \times 224$ và $384 \times 384$).
Implementation và kết quả
Development process
Cốt lõi của mô hình phân loại là kiến trúc Vision Transformer được tối ưu hóa cho bài toán phân loại đa nhãn ảnh X-quang ngực. Quy trình xử lý ảnh đầu vào tuân theo các bước biến đổi toán học chặt chẽ:
Ảnh X-quang đầu vào $X \in \mathbb{R}^{H \times W \times C}$ được chia thành chuỗi $N$ mảng ảnh phẳng không chồng lấn $X_p \in \mathbb{R}^{N \times (P^2 \cdot C)}$, trong đó $(H, W)$ là độ phân giải ảnh gốc, $C$ là số kênh màu, $(P, P)$ là kích thước mảng ảnh (patch size, thường là $16 \times 16$), và số lượng patch là $N = \frac{HW}{P^2}$.
Chuỗi patch được chiếu tuyến tính qua ma trận $E \in \mathbb{R}^{(P^2 \cdot C) \times D}$ để thu được các vector patch embedding kích thước $D$. Một vector học được $[x_{\text{class}}]$ được chèn vào đầu chuỗi cùng với Position Embedding $E_{\text{pos}} \in \mathbb{R}^{(N+1) \times D}$:
$$z_0 = [x_{\text{class}}; X_p^1 E; X_p^2 E; \dots; X_p^N E] + E_{\text{pos}}$$
Khối Transformer Encoder bao gồm các tầng lặp lại cấu trúc Multi-Head Self-Attention (MSA) và Multi-Layer Perceptron (MLP), áp dụng Layer Normalization (LN) và kết nối Residual:
$$z'l = \text{MSA}(\text{LN}(z{l-1})) + z_{l-1}, \quad l = 1 \dots L$$
$$z_l = \text{MLP}(\text{LN}(z'_l)) + z'_l, \quad l = 1 \dots L$$
Trong đó, cơ chế Self-Attention tính toán ma trận Attention thông qua các phép chiếu Query ($Q$), Key ($K$), Value ($V$):
$$\text{Attention}(Q, K, V) = \text{Softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$
import torch
import torch.nn as nn
class MedicalViTClassifier(nn.Module):
"""
Vision Transformer Architecture for Multi-label Chest X-Ray Classification
Supports custom patch embedding projection and attention weight extraction.
"""
def __init__(self, img_size=224, patch_size=16, in_channels=3, num_classes=10,
embed_dim=768, depth=12, num_heads=12, mlp_ratio=4.0):
super(MedicalViTClassifier, self).__init__()
self.num_classes = num_classes
self.embed_dim = embed_dim
self.num_patches = (img_size // patch_size) ** 2
# Patch Extraction and Linear Projection
self.patch_embed = nn.Conv2d(in_channels, embed_dim, kernel_size=patch_size, stride=patch_size)
self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))
self.pos_embed = nn.Parameter(torch.zeros(1, self.num_patches + 1, embed_dim))
self.pos_drop = nn.Dropout(p=0.1)
# Transformer Encoder Blocks
encoder_layer = nn.TransformerEncoderLayer(
d_model=embed_dim, nhead=num_heads,
dim_feedforward=int(embed_dim * mlp_ratio),
activation='gelu', batch_first=True
)
self.encoder = nn.TransformerEncoder(encoder_layer, num_layers=depth)
self.norm = nn.LayerNorm(embed_dim)
# Classification Head for Multi-label Binary Cross-Entropy
self.head = nn.Linear(embed_dim, num_classes)
def forward(self, x):
B = x.shape[0]
# x shape: (B, C, H, W) -> Patch Embedding: (B, embed_dim, sqrt(N), sqrt(N))
x = self.patch_embed(x).flatten(2).transpose(1, 2) # (B, N, embed_dim)
cls_tokens = self.cls_token.expand(B, -1, -1)
x = torch.cat((cls_tokens, x), dim=1) # (B, N + 1, embed_dim)
x = x + self.pos_embed
x = self.pos_drop(x)
encoded_features = self.encoder(x)
cls_rep = self.norm(encoded_features[:, 0]) # Take the [CLS] token representation
logits = self.head(cls_rep)
# Return raw logits for Multi-Label Cross Entropy / BCEWithLogitsLoss
return logits
Phần xử lý dịch vụ Backend Flask được tổ chức theo cấu trúc module gọn gàng:
from flask import Flask, request, jsonify
import torchvision.transforms as transforms
from PIL import Image
import torch
import io
app = Flask(__name__)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# Load fine-tuned ViT model checkpoint
model = torch.load('checkpoints/vit_b16_vindr_best.pth', map_location=device)
model.eval()
CLASSES = [
'Aortic enlargement', 'Cardiomegaly', 'Consolidation',
'Infiltration', 'Lung Opacity', 'Nodule/Mass',
'Pleural effusion', 'Pleural thickening', 'Pneumothorax', 'Pulmonary fibrosis'
]
transform_pipeline = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
@app.route('/api/v1/predict', methods=['POST'])
def predict_xray():
if 'image' not in request.files:
return jsonify({'error': 'No image provided'}), 400
file = request.files['image']
image_bytes = file.read()
image = Image.open(io.BytesIO(image_bytes)).convert('RGB')
tensor = transform_pipeline(image).unsqueeze(0).to(device)
with torch.no_grad():
logits = model(tensor)
probabilities = torch.sigmoid(logits).squeeze(0).cpu().numpy()
results = {CLASSES[i]: float(probabilities[i]) for i in range(len(CLASSES))}
return jsonify({
'status': 'success',
'predictions': results,
'requires_review': any(p > 0.5 for p in probabilities)
}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Testing và validation
Quá trình kiểm thử và đánh giá mô hình được tiến hành trên tập kiểm thử độc lập (Test Set) của VinDr-CXR gồm các ca chụp X-quang ngực đã được gán nhãn đồng thuận bởi các bác sĩ chẩn đoán hình ảnh giàu kinh nghiệm.
Thang đo đánh giá bao gồm:
- AUC-ROC (Area Under the Receiver Operating Characteristic): Thước đo chính cho bài toán phân loại đa nhãn y tế, phản ánh năng lực phân tách giữa ca bệnh dương tính và âm tính ở mọi ngưỡng phân loại.
- Accuracy, Precision, Recall, F1-Score: Được tính toán tại ngưỡng xác suất tối ưu $T = 0.5$.
| Mô hình (Architecture) |
Độ phân giải đầu vào |
Số lượng tham số (M) |
Mean AUC-ROC (10 Classes) |
Mean F1-Score |
Thời gian xử lý / ảnh (Inference) |
| ResNet-18 |
$224 \times 224$ |
11.68 M |
0.842 |
0.761 |
~1.2 ms (GPU) / 1.8s (E2E Web) |
| ResNet-34 |
$224 \times 224$ |
21.79 M |
0.858 |
0.774 |
~1.8 ms (GPU) / 2.1s (E2E Web) |
| ResNet-50 |
$224 \times 224$ |
25.56 M |
0.871 |
0.789 |
~2.5 ms (GPU) / 2.6s (E2E Web) |
| ViT-S16 |
$224 \times 224$ |
22.05 M |
0.869 |
0.782 |
~3.1 ms (GPU) / 3.0s (E2E Web) |
| ViT-B16 (Pre-trained) |
$224 \times 224$ |
86.57 M |
0.897 |
0.814 |
~5.8 ms (GPU) / 4.2s (E2E Web) |
| ViT-B16 (Pre-trained) |
$384 \times 384$ |
86.86 M |
0.906 |
0.825 |
~14.2 ms (GPU) / 6.5s (E2E Web) |
| R50 + ViT-B16 |
$224 \times 224$ |
98.74 M |
0.892 |
0.808 |
~8.4 ms (GPU) / 5.1s (E2E Web) |
| ViT-L16 |
$224 \times 224$ |
304.30 M |
0.889 |
0.801 |
~19.6 ms (GPU) / 8.9s (E2E Web) |
Kết quả đạt được
SO SÁNH MEAN AUC-ROC TRÊN TẬP DỮ LIỆU VINDR-CXR
1.00 +-----------------------------------------------------------------------+
| |
0.90 |========================= ==================== ==================| (0.906 / 0.897)
|*ViT-B16 (384)* (0.906) | |*ViT-B16 (224)* (0.897)| |R50+ViT-B16(0.892)|
0.80 |-------------------------|--|--------------------|--|------------------| (0.871 / 0.842)
|ResNet-50 (0.871) | |ResNet-34 (0.858)| |ResNet-18 (0.842)|
0.70 +-------------------------+--+--------------------+--+------------------+
- Hiệu năng phân loại vượt bậc: Mô hình
ViT-B16 được tinh chỉnh qua 2 pha (Domain-adaptive pre-training trên CheXpert/Chest14 trước khi chuyển sang VinDr-CXR) đạt điểm Mean AUC là 0.897 ở độ phân giải $224 \times 224$ và 0.906 ở độ phân giải $384 \times 384$, vượt trội mô hình CNN chuẩn ResNet-50 (0.871).
- Nâng cao năng lực phát hiện đa bệnh: Đối với các ca chụp có từ 2 tổn thương phân tán trở lên (ví dụ: Cardiomegaly kết hợp Pleural effusion), mô hình ViT đạt độ nhạy (Sensitivity) cao hơn 4.8% so với ResNet-50.
- Hiện thực hóa hệ thống ứng dụng: Toàn bộ hệ thống Web Application, API, cơ sở dữ liệu và các kênh thông báo SMS/Email hoạt động ổn định trên môi trường Docker, cho phép khởi chạy chỉ bằng một dòng lệnh
docker run.
Đổi mới và đóng góp
Nghiên cứu mang lại những đóng góp kỹ thuật và ứng dụng thực tiễn rõ ràng trong lĩnh vực Trí tuệ nhân tạo Y sinh:
+------------------------------------------------------------------------------------+
| ĐÓNG GÓP KỸ THUẬT VÀ ĐỔI MỚI CHÍNH |
| |
| 1. Transfer Learning 2 Pha: ImageNet -> CheXpert/Chest14 -> VinDr-CXR |
| (Giải quyết triệt để bài toán thiếu hụt dữ liệu lớn cho Vision Transformer) |
| |
| 2. Attention Map Đa Vùng: Trực quan hóa chính xác tổn thương đồng xuất hiện |
| (Khắc phục hiện tượng mờ nhòe gradient của phương pháp Grad-CAM trên CNN) |
| |
| 3. Microservice Đóng Gói Hoàn Chỉnh: Flask + SQLite + Twilio + Docker |
| (Thu hẹp khoảng cách từ mô hình nghiên cứu đến môi trường thử nghiệm lâm sàng)|
+------------------------------------------------------------------------------------+
- Chiến lược huấn luyện Transfer Learning 2 pha giải quyết bài toán Data-Hungry: Vision Transformer thường đòi hỏi hàng trăm triệu ảnh (như ImageNet-21k, JFT-300M) để vượt qua CNN vì không có sẵn Inductive Bias (tính bất biến tịnh tiến và tính cục bộ). Đề tài đã chứng minh việc sử dụng các tập dữ liệu y tế trung gian (CheXpert với ~224k ảnh và Chest14 với ~112k ảnh) để tinh chỉnh trọng số trước khi đưa về tập dữ liệu đích VinDr-CXR giúp ViT thích nghi xuất sắc với đặc trưng mô học X-quang, cải thiện +5.4% AUC so với việc chỉ fine-tune trực tiếp từ trọng số ImageNet thông thường.
- Khai phá cơ chế giải thích Attention Map trực quan cho bệnh học đa vùng: So với Grad-CAM trên CNN (vốn bị phụ thuộc vào tầng tích chập cuối có độ phân giải không gian thấp, dễ gây nhòe nhiệt điểm), Attention Map của Vision Transformer thể hiện sắc nét sự phân bổ trọng số tự chú ý tại đúng các ổ tổn thương phân tán (như tổn thương mờ ở đỉnh phổi đồng thời với tràn dịch đáy phổi).
- Hệ thống hóa giải pháp ứng dụng hoàn chỉnh: Không dừng lại ở việc đánh giá mô hình trong Jupyter Notebook, nghiên cứu đã xây dựng một sản phẩm phần mềm hoàn chỉnh có tính công nghệ cao: kiến trúc REST API chuẩn mực, xử lý bất đồng bộ thông báo kết quả và đóng gói chuẩn Docker container sẵn sàng triển khai trên bất kỳ hạ tầng điện toán đám mây hoặc máy chủ cục bộ nào.
Ứng dụng thực tế và triển khai
Kịch bản sử dụng thực tế (Clinical Workflow)
Hệ thống được thiết kế để tích hợp trực tiếp vào quy trình khám chữa bệnh tại các cơ sở y tế:
- Tiếp nhận & Đăng ký: Kỹ thuật viên hoặc điều dưỡng đăng ký thông tin bệnh nhân (Mã số, Họ tên, Số điện thoại, Email) trên giao diện Web.
- Chụp & Tải ảnh: Ảnh X-quang ngực (tư thế thẳng sau - trước PA) sau khi thu nhận từ máy chụp X-quang kỹ thuật số được tải lên hệ thống.
- Phân tích AI: Hệ thống gửi ảnh tới Flask API, mô hình ViT thực hiện suy luận trong 2 - 5 giây, xuất ra danh sách xác suất của 10 bệnh lý kèm bản đồ chú ý Attention Map.
- Bác sĩ xem xét & Kết luận: Bác sĩ chẩn đoán hình ảnh quan sát ảnh gốc song song với Attention Map, kiểm tra các bệnh lý được AI cảnh báo, đưa ra kết luận chuyên môn cuối cùng.
- Thông báo tự động: Hệ thống tự động gửi tin nhắn SMS tóm tắt kết quả hoặc Email thông báo chi tiết đến bệnh nhân thông qua Twilio API và SMTP Server.
Hướng dẫn đóng gói và triển khai với Docker
Cấu hình Dockerfile độc lập, tối ưu kích thước:
# Sử dụng Python base image phiên bản gọn nhẹ
FROM python:3.9-slim-buster
# Thiết lập thư mục làm việc trong container
WORKDIR /app
# Cài đặt các thư viện hệ thống cần thiết cho OpenCV
RUN apt-get update && apt-get install -y --no-install-recommends \
libgl1-mesa-glx \
libglib2.0-0 \
&& rm -rf /var/lib/apt/lists/*
# Sao chép file requirements và cài đặt thư viện Python
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Sao chép mã nguồn ứng dụng và trọng số mô hình
COPY . .
# Mở cổng 5000 cho Flask Web App
EXPOSE 5000
# Khởi chạy ứng dụng thông qua Gunicorn WSGI server
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "--timeout", "120", "app:app"]
Quy trình triển khai trên môi trường máy chủ mới:
# 1. Tải Docker Image từ kho lưu trữ DockerHub
docker pull ngoquangkhai/vit-cxr-classifier:latest
# 2. Khởi chạy container với cổng ánh xạ 5000
docker run -d -p 5000:5000 \
-e TWILIO_ACCOUNT_SID="your_account_sid_here" \
-e TWILIO_AUTH_TOKEN="your_auth_token_here" \
-e TWILIO_PHONE_NUMBER="+1234567890" \
--name xray-diagnosis-app \
ngoquangkhai/vit-cxr-classifier:latest
# 3. Kiểm tra trạng thái container đang hoạt động
docker ps -a
Phân tích hiệu quả kinh tế (ROI) và vận hành:
- Giảm thiểu 35% - 45% thời gian đọc phim ban đầu của bác sĩ trực, đóng vai trò như một bộ lọc sàng lọc sơ bộ (triage).
- Giảm tỷ lệ bỏ sót tổn thương ở các ca trực đêm khi bác sĩ đối mặt với tình trạng quá tải và mệt mỏi.
- Chi phí triển khai phần mềm gần như bằng 0 nhờ nền tảng mã nguồn mở (Linux, Python, PyTorch, Docker, SQLite).
Hạn chế và hướng phát triển
Mặc dù đạt được những kết quả đáng kể về cả độ chính xác mô hình lẫn sản phẩm phần mềm, đề tài vẫn tồn tại một số hạn chế kỹ thuật:
- Tài nguyên tính toán lớn: Vision Transformer, đặc biệt là các biến thể lớn như
ViT-L16, tiêu tốn bộ nhớ GPU và thời gian huấn luyện cao hơn gấp 3 - 4 lần so với ResNet-50.
- Giới hạn loại hình ảnh: Mô hình mới chỉ được huấn luyện tối ưu trên ảnh chụp X-quang tư thế PA (sau - trước); chưa tối ưu cho tư thế AP (trước - sau) hoặc ảnh nghiêng (Lateral view).
- Định dạng dữ liệu: Ứng dụng web hiện tại yêu cầu chuyển đổi định dạng y tế DICOM sang PNG/JPEG trước khi tải lên, chưa tích hợp trực tiếp DICOM Viewer chuyên dụng.
- Bảo mật và Phân quyền: Chưa tích hợp hệ thống xác thực người dùng đa cấp độ (Role-Based Access Control) chuẩn HIPAA/HL7 cho dữ liệu y tế.
Hướng phát triển trong tương lai:
- Nghiên cứu áp dụng các kiến trúc Transformer tiên tiến hơn như Swin Transformer (Hierarchical Vision Transformer using Shifted Windows) nhằm giảm thiểu độ phức tạp tính toán từ bậc hai $O(N^2)$ xuống tuyến tính $O(N)$, cho phép xử lý ảnh X-quang ở độ phân giải gốc siêu cao ($1024 \times 1024$).
- Mở rộng bài toán sang chẩn đoán trên chuỗi lớp cắt cắt lớp vi tính 3D (Volumetric CT Scans) cho bệnh lý ung thư phổi và xơ phổi kẽ.
- Nâng cấp hệ thống web với tiêu chuẩn truyền thông hình ảnh y tế DICOM WADO-RS và tích hợp trực tiếp vào hệ thống PACS/HIS tại bệnh viện.
Đối tượng hưởng lợi
Hồ sơ nghiên cứu và sản phẩm của đề tài mang lại giá trị thiết thực cho nhiều nhóm đối tượng:
- Sinh viên chuyên ngành Kỹ thuật Y sinh & Khoa học Dữ liệu: Tài liệu tham khảo toàn diện, chuẩn mực về việc áp dụng mô hình Deep Learning thế hệ mới (Vision Transformer) vào dữ liệu ảnh y tế thực tế, kèm cấu trúc mã nguồn PyTorch và triển khai ứng dụng từ A-Z.
- Kỹ sư AI & Lập trình viên: Mẫu thiết kế kiến trúc chuẩn mực (Design Pattern) về việc xây dựng RESTful API cho Deep Learning Model, kết hợp cơ sở dữ liệu quan hệ, dịch vụ thông báo thứ ba (Twilio) và đóng gói vi dịch vụ với Docker.
- Bác sĩ & Cơ sở khám chữa bệnh: Công cụ hỗ trợ chẩn đoán thứ hai (Second Opinion) đáng tin cậy, giúp nâng cao năng suất đọc phim, trực quan hóa vùng nghi ngờ tổn thương qua Attention Map và tự động hóa quy trình trả kết quả cho bệnh nhân.
- Nhà nghiên cứu học thuật: Cung cấp các số liệu thực nghiệm đối sánh rõ ràng giữa cơ chế Attention và Convolution trên các bộ dữ liệu X-quang ngực lớn (VinDr-CXR, CheXpert, Chest14).
Câu hỏi thường gặp
1. Yêu cầu phần cứng tối thiểu để triển khai và chạy ứng dụng là gì?
Hệ thống được đóng gói Docker có khả năng chạy trên cả CPU và GPU. Cấu hình tối thiểu để vận hành suy luận (Inference):
- CPU: 4 Cores (Intel Core i5 / AMD Ryzen 5 thế hệ 8 trở lên).
- RAM: Tối thiểu 8 GB (Khuyến nghị 16 GB để xử lý mượt mà khi có nhiều yêu cầu đồng thời).
- GPU (Tùy chọn): NVIDIA GTX 1060 (6GB VRAM) hoặc cao hơn giúp giảm thời gian suy luận xuống dưới 100ms/ảnh.
- Ổ cứng: 10 GB dung lượng trống để lưu trữ Docker Image và cơ sở dữ liệu SQLite.
2. Tại sao Vision Transformer cần Pre-training trên tập dữ liệu y tế lớn trước khi nạp vào VinDr-CXR?
Không giống như CNN có sẵn tính chất cảm nạp quy nạp (Inductive Bias - nhận biết đặc trưng bất kể vị trí), Vision Transformer phải tự học toàn bộ các quan hệ không gian từ đầu. Tập dữ liệu VinDr-CXR (15.000 ảnh) là quá nhỏ để ViT học từ đầu (from scratch) mà không bị Overfitting nghiêm trọng. Do đó, việc chuyển giao tri thức từ ImageNet-21k sang các tập dữ liệu y tế trung gian quy mô lớn như CheXpert (~224k ảnh) giúp các lớp Multi-Head Attention làm quen trước với các cấu trúc giải phẫu lồng ngực.
3. Hệ thống có thể tích hợp với các phần mềm PACS/HIS hiện tại của bệnh viện không?
Có. Nhờ thiết kế theo chuẩn RESTful API qua giao thức HTTP POST, hệ thống có thể dễ dàng tiếp nhận dữ liệu ảnh từ bất kỳ máy chủ PACS nào hỗ trợ Webhook hoặc xuất định dạng chuẩn. Trong các giai đoạn tiếp theo, hệ thống có thể bổ sung module DICOM Router để nhận dữ liệu qua cổng DICOM C-STORE tiêu chuẩn.
4. Attention Map khác biệt thế nào so với Grad-CAM khi hiển thị nhiều tổn thương?
Grad-CAM tính toán đạo hàm riêng của lớp dự đoán đối với các bản đồ đặc trưng ở tầng tích chập cuối cùng rồi áp dụng hàm ReLU, thường tạo ra một vùng nhiệt phân tán mờ và dễ bị lấn át bởi tổn thương có diện tích lớn. Trong khi đó, Attention Map trích xuất trực tiếp trọng số chú ý từ vector token [CLS] tới từng patch ảnh $16 \times 16$, cho phép làm nổi bật đồng thời nhiều tiêu điểm tổn thương nhỏ và sắc nét ở các góc khác nhau trên phổi.
5. Chi phí vận hành và bản quyền của giải pháp này được tính toán như thế nào?
Giải pháp được xây dựng hoàn toàn trên các công nghệ mã nguồn mở miễn phí (Python, PyTorch, Flask, SQLite, Docker). Chi phí phát sinh duy nhất trong quá trình vận hành là cước phí gửi tin nhắn SMS qua Twilio API (tính theo số lượng SMS thực tế gửi đến bệnh nhân) và chi phí duy trì hạ tầng máy chủ/điện toán đám mây.
Kết luận
Đề tài tốt nghiệp "Ứng dụng mô hình Vision Transformer trong phân loại dữ liệu bệnh phổi" đã nghiên cứu và phát triển thành công giải pháp ứng dụng học sâu tiên tiến cho bài toán phân tích ảnh X-quang lồng ngực. Bằng việc áp dụng quy trình học chuyển giao 2 pha cùng kiến trúc Multi-Head Self-Attention, mô hình ViT-B16 đạt điểm Mean AUC-ROC ấn tượng 0.897 (độ phân giải $224 \times 224$) và 0.906 (độ phân giải $384 \times 384$), khẳng định ưu thế vượt trội trong việc nắm bắt tương quan không gian giữa các bệnh lý đồng xuất hiện so với các mạng CNN truyền thống như ResNet-50.
Bên cạnh đột phá về mô hình học máy, đề tài đã xây dựng hoàn chỉnh một ứng dụng Web y tế trực quan với đầy đủ tính năng: đăng ký bệnh nhân, chẩn đoán tự động hỗ trợ bác sĩ, hiển thị Attention Map minh bạch và thông báo kết quả đa kênh qua Email/SMS. Toàn bộ giải pháp được đóng gói chuẩn mực bằng Docker, mở ra tiềm năng ứng dụng thực tiễn cao tại các phòng khám và cơ sở y tế nhằm giảm tải áp lực cho đội ngũ bác sĩ và nâng cao chất lượng dịch vụ chăm sóc sức khỏe cộng đồng.