Ứng dụng mạng EfficientNet vào phân loại hình ảnh.pdf

aicandy 50 views 21 slides Dec 01, 2024
Slide 1
Slide 1 of 21
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21

About This Presentation

Xây dựng một hệ thống nhận diện và phân loại hình ảnh dựa trên mạng neural EfficientNet. Hệ thống này sẽ phân tích bức ảnh đầu vào và xác định đối tượng chính xuất hiện trong ảnh.


Slide Content

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
1

Ứng dụng mạng EfficientNet vào phân
loại hình ảnh
Nội dung
 1. Bài toán
 2. Thực hiện
o 2.1. Cấu trúc chương trình
o 2.2. Dữ liệu
o 2.3. Build model
o 2.4. Chương trình train
o 2.5. Chương trình test
o 2.6. Chương trình chuyển đổi model
 3. Kết quả train
 4. Kết quả test
 5. Source code
1. Bài toán
Xây dựng một hệ thống nhận diện và phân loại hình ảnh dựa trên mạng
neural EfficientNet. Hệ thống này sẽ phân tích bức ảnh đầu vào và xác định
đối tượng chính xuất hiện trong ảnh.

2. Thực hiện
2.1. Cấu trúc chương trình

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
2

Với mục đích dễ quản lý source code, chúng ta có thể đặt chương trình như
sau:
root@aicandy:/aicandy/projects/AIcandy_Efficientnet_ImageClassificat
ion_rlbyvacq# tree.
├── aicandy_efficientnet_convert_onnx_laghxee b.py
├── aicandy_efficientnet_test_gmbpqtln.py
├── aicandy_efficientnet_train_xcprktlu.py
├── aicandy_model_out_vailsuom
└── aicandy_model_src_ybklivqn
└── aicandy_efficientnet_model_mqialtec.py
Trong đó:
– File aicandy_efficientnet_model_mqialtec.py chứa model
– File aicandy_efficientnet_train_xcprktlu.py chứa chương trình train
– File aicandy_efficientnet_test_gmbpqtln.py chứa chương trình để test.
– File aicandy_efficientnet_convert_onnx_laghxeeb.py chứa chương trình
chuyển đổi từ model pytorch sang model onnx phục vụ triển khai model
trên nhiều thiết bị khác nhau.
2.2. Dữ liệu
Dữ liệu phục vụ cho việc train gồm các ảnh đã được phân loại trước và được
lưu trong các folder theo đối tượng, tên của folder là tên của đối tượng. Ví
dụ trong bài này chúng ta có folder ‘dogs’ để chứa tất cả các ảnh có hình ảnh
‘dog’ và folder ‘cats’ để chứa tất cả các hình ảnh có ‘cat’.
Bộ dataset có cấu trúc như sau:
root@aicandy:/aicandy/projects/dataset# ls
cats dogs
root@aicandy:/aicandy/projects/dataset# cd cats/
root@aicandy:/aicandy/projects/dataset/cats# tree | head -n 6

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
3

.
├── cat.0.jpg
├── cat.1000.jpg
├── cat.1002.jpg
├── cat.1003.jpg
├── cat.1004.jpg
root@aicandy:/aicandy/projects/dataset/cats#
root@aicandy:/aicandy/projects/dataset/cats# cd ../dogs/
root@aicandy:/aicandy/projects/dataset/dogs# tree | head -n 6
.
├── dog.1000.jpg
├── dog.1002.jpg
├── dog.1003.jpg
├── dog.1004.jpg
├── dog.1005.jpg
root@aicandy:/aicandy/projects/dataset/dogs#
Bộ dữ liệu sử dụng trong bài gồm bộ aicandy_cats_mkemktch và
bộ aicandy_dogs_lpmdvpox được download miễn phí tại đây
2.3. Build model
Xây dựng mô hình gồm các thành phần chính:
class Swish(nn.Module) :
def forward(self, x) :
return x * torch.sigmoid(x)
Swish là một hàm kích hoạt phi tuyến, được sử dụng phổ biến trong các mô
hình hiện đại nhờ vào khả năng tăng hiệu suất so với các hàm kích hoạt
truyền thống như ReLU. Công thức của Swish là x * sigmoid(x), giúp giữ lại
giá trị đầu vào khi tín hiệu lớn và làm mịn hơn khi tín hiệu nhỏ.

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
4

self.expand = nn.Conv2d(in_channels, in_channels * expansion,
kernel_size=1, bias=False )
self.bn0 = nn.BatchNorm2d(in_channels * expansion)
Tăng số lượng kênh từ in_channels lên in_channels * expansion.
 nn.Conv2d(in_channels, in_channels * expansion, kernel_size=1,
bias=False): Áp dụng một tích chập (convolution) với kích thước
kernel là 1×1, có nghĩa là chỉ thay đổi số lượng kênh mà không thay
đổi kích thước không gian (chiều cao và chiều rộng) của dữ liệu.
 in_channels * expansion: expansion là một hệ số nhân, làm tăng số
lượng kênh của đầu vào.
 bias=False: Không sử dụng bias trong phép tích chập.
 nn.BatchNorm2d(in_channels * expansion): Áp dụng chuẩn hóa theo
batch (batch normalization) sau khi mở rộng số lượng kênh, giúp ổn
định và tăng tốc độ huấn luyện.
self.depthwise = nn.Conv2d(in_channels * expansion, in_channels *
expansion, kernel_size=3, stride=stride, padding=1, groups=in_channels
* expansion, bias=False )
self.bn1 = nn.BatchNorm2d(in_channels * expansion)
Thực hiện tích chập từng kênh (depthwise convolution) để trích xuất đặc
trưng mà không làm tăng số lượng tham số quá nhiều.
 nn.Conv2d(in_channels * expansion, in_channels * expansion,
kernel_size=3, stride=stride, padding=1, groups=in_channels *
expansion, bias=False): Đây là một lớp tích chập có kernel size là 3×3
với stride và padding tương ứng.
 groups=in_channels * expansion: Tùy chọn groups bằng số lượng
kênh của đầu vào, điều này có nghĩa là mỗi kênh sẽ được tích chập độc
lập (depthwise convolution).
 stride=stride: Điều chỉnh bước đi của kernel trong ảnh.
 padding=1: Giữ nguyên kích thước không gian của đầu vào sau khi
tích chập.
 nn.BatchNorm2d(in_channels * expansion): Áp dụng chuẩn hóa theo
batch sau lớp depthwise convolution.

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
5

self.se_reduce = nn.Conv2d(in_channels * expansion, in_channels *
expansion // 4, kernel_size=1 )
self.se_expand = nn.Conv2d(in_channels * expansion // 4, in_channels *
expansion, kernel_size=1)
Học cách trọng số cho mỗi kênh thông qua cơ chế “Squeeze and Excitation”,
giúp mô hình chú trọng vào các kênh quan trọng hơn.
 self.se_reduce: Giảm số lượng kênh của đầu vào bằng một lớp tích
chập 1×1, xuống 1/4 số lượng kênh ban đầu (in_channels * expansion
// 4).
 self.se_expand: Tăng số lượng kênh trở lại kích thước ban đầu
(in_channels * expansion) bằng một lớp tích chập 1×1.
self.project = nn.Conv2d(in_channels * expansion, out_channels,
kernel_size=1, bias=False )
self.bn2 = nn.BatchNorm2d(out_channels)
 nn.Conv2d(in_channels * expansion, out_channels, kernel_size=1,
bias=False): Sử dụng lớp tích chập 1×1 để giảm số lượng kênh từ
in_channels * expansion xuống out_channels.
 nn.BatchNorm2d(out_channels): Áp dụng chuẩn hóa theo batch trên
đầu ra để cải thiện độ ổn định của mô hình.
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=2, padding=1,
bias=False)
 3: Đây là số lượng kênh của đầu vào (input channels). Trong trường
hợp này, nó là 3, vì đầu vào là hình ảnh màu (RGB) với 3 kênh (Red,
Green, Blue).
 32: Đây là số lượng kênh của đầu ra (output channels), tức là số lượng
bộ lọc (filters) mà lớp tích chập này sử dụng. Mỗi bộ lọc sẽ tạo ra một
kênh đặc trưng riêng biệt, do đó đầu ra của lớp này sẽ có 32 kênh.
 kernel_size=3: Kích thước của kernel (bộ lọc) là 3×3. Kernel là một ma
trận nhỏ được trượt qua toàn bộ ảnh để thực hiện phép tích chập.
Kernel 3×3 là một trong những kích thước phổ biến nhất, cho phép mô
hình trích xuất đặc trưng từ các vùng lân cận nhỏ của ảnh.

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
6

 stride=2: Stride là bước nhảy của kernel khi nó trượt qua ảnh. Stride =
2 có nghĩa là kernel sẽ di chuyển 2 pixel một lần, làm giảm kích thước
không gian của đầu ra (giảm một nửa chiều rộng và chiều cao của ảnh).
 padding=1: Padding thêm các pixel giá trị 0 xung quanh viền của ảnh
trước khi áp dụng tích chập. Padding = 1 có nghĩa là thêm một lớp
pixel 0 xung quanh viền ảnh, giúp giữ nguyên kích thước không gian
của đầu ra so với đầu vào khi sử dụng kernel 3×3.
 bias=False: bias là một tham số tùy chọn trong phép tích chập. Khi
bias=False, lớp tích chập sẽ không thêm bất kỳ giá trị bias nào vào đầu
ra. Điều này có thể giúp giảm số lượng tham số của mô hình và có thể
được sử dụng khi kết hợp với batch normalization.
self.blocks = nn.Sequential (
EfficientNetBlock(32, 16, expansion=1, stride=1) ,
EfficientNetBlock(16, 24, expansion=6, stride=2) ,
EfficientNetBlock(24, 40, expansion=6, stride=2) ,
EfficientNetBlock(40, 80, expansion=6, stride=2) ,
EfficientNetBlock(80, 112, expansion=6, stride=1) ,
EfficientNetBlock(112, 192, expansion=6, stride=2) ,
EfficientNetBlock(192, 320, expansion=6, stride=1),
)
Mỗi dòng trong nn.Sequential tạo ra một khối EfficientNetBlock, với các
tham số cụ thể cho mỗi khối. Mỗi khối EfficientNetBlock bao gồm các thành
phần như expand, depthwise, SE block, và project đã được giải thích trước
đó.
Các tham số của mỗi khối:
in_channels và out_channels:

o
 in_channels: Số lượng kênh của đầu vào cho khối.
 out_channels: Số lượng kênh của đầu ra từ khối.
 Ví dụ: Khối đầu tiên có in_channels=32 và
out_channels=16, tức là đầu vào của khối này có 32 kênh
và đầu ra có 16 kênh.

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
7

expansion: Hệ số nhân để mở rộng số lượng kênh trong bước mở rộng
(expand).

o
 expansion=1: Không mở rộng số lượng kênh (số lượng
kênh giữ nguyên).
 expansion=6: Mở rộng số lượng kênh lên 6 lần trước khi áp
dụng các bước tiếp theo trong khối.
stride: Bước nhảy của kernel trong bước depthwise convolution.

o
 stride=1: Giữ nguyên kích thước không gian của đầu vào.
 stride=2: Giảm kích thước không gian của đầu vào xuống
một nửa.
self.fc = nn.Linear(1280, num_classes)
Lớp Linear này thực hiện một phép biến đổi tuyến tính trên các đặc trưng
đầu vào từ CNN để tạo ra một vector với kích thước là num_classes. Vector
này sẽ chứa các giá trị điểm số (logits) cho mỗi lớp.
2.4. Chương trình train
Bước 1: import một số thư viện để xử lý các tác vụ liên quan tới tệp và
đường dẫn (os, sys), thư viện xây dựng và tối ưu hóa mô hình (torch,
torch.optim, torch.nn), các thư viện xử lý hình ảnh (datasets, transform,
train_test_split, Dataloader).
import torc h
import torch.optim as opti m
import torch.nn as n n
import torchvision.transforms as transform s
import torchvision.datasets as dataset s
from torch.utils.data import DataLoade r
from torch.utils.data import DataLoader, Subse t

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
8

from sklearn.model_selection import train_test_spli t
from aicandy_model_src_ybklivqn.aicandy_efficientnet_model_mqialtec
import CustomEfficientNe t
import os
Bước 2: lựa chọn sử dụng CPU hay GPU để train, chúng ta sử dụng câu lệnh:
device = torch.device(“cuda” if torch.cuda.is_available() else “cpu”)
Bước 3: tăng cường dữ liệu bằng sử dụng transforms với:
– transforms.Resize((224, 224)): Thay đổi kích thước hình ảnh thành kích
thước cố định (224×224) pixel. Đảm bảo rằng tất cả các hình ảnh đầu vào đều
có cùng kích thước, phù hợp với yêu cầu của mạng nơ-ron.
– transforms.RandomHorizontalFlip(): Lật ngẫu nhiên hình ảnh theo chiều
ngang. Tăng cường dữ liệu bằng cách tạo ra các phiên bản lật của hình ảnh,
giúp mô hình học được các đặc điểm của hình ảnh bất kể hướng của chúng.
– transforms.RandomRotation(10): Xoay ngẫu nhiên hình ảnh một góc từ -
10 đến +10 độ. Giúp mô hình trở nên mạnh mẽ hơn trước các biến thể xoay
của đối tượng trong hình ảnh.
– transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2,
hue=0.2): Điều chỉnh ngẫu nhiên độ sáng, độ tương phản, độ bão hòa và tông
màu của hình ảnh. Tăng cường dữ liệu bằng cách tạo ra các biến thể màu sắc
khác nhau của hình ảnh, giúp mô hình học được các đặc điểm hình ảnh dưới
các điều kiện ánh sáng và màu sắc khác nhau.
– transforms.ToTensor(): Chuyển đổi hình ảnh từ dạng PIL hoặc NumPy
array thành một tensor PyTorch. Tensor là định dạng dữ liệu mà PyTorch
yêu cầu để xử lý dữ liệu trong quá trình huấn luyện.
– transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224,
0.225]): Chuẩn hóa các giá trị pixel của hình ảnh. Đưa các giá trị pixel về
phạm vi có giá trị trung bình là 0 và độ lệch chuẩn là 1 cho từng kênh màu
(RGB). Điều này giúp mô hình huấn luyện hiệu quả hơn vì các giá trị đầu
vào được chuẩn hóa.

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
9

Bước 4: Load data và phân chia thành 2 tập train và val để đánh giá model
dataset = datasets.ImageFolder(root=train_dir, transform=transform)
 datasets.ImageFolder: Đây là một tiện ích của PyTorch để tải ảnh từ
một thư mục. Thư mục này cần được tổ chức theo cấu trúc, mỗi thư
mục con đại diện cho một lớp (class) khác nhau.
 root=train_dir: train_dir là đường dẫn tới thư mục chứa các ảnh huấn
luyện.
 transform=transform: transform là các phép biến đổi (ví dụ: thay đổi
kích thước, chuẩn hóa, tăng cường dữ liệu) được áp dụng lên các ảnh
khi chúng được tải lên.
train_idx, val_idx = train_test_split(list(range(len(dataset))), test_size=0.2,
random_state=42)
 train_test_split: Hàm này từ thư viện sklearn.model_selection chia dữ
liệu thành hai phần: huấn luyện và kiểm tra (validation).
 list(range(len(dataset))): Tạo một danh sách các chỉ số tương ứng với
tất cả các ảnh trong tập dữ liệu.
 test_size=0.2: 20% dữ liệu được dành cho tập kiểm tra.
 random_state=42: Seed cho bộ sinh số ngẫu nhiên để đảm bảo việc
chia dữ liệu có thể tái lập.
train_dataset = Subset(dataset, train_idx )
val_dataset = Subset(dataset, val_idx)
 Subset: Một tiện ích của PyTorch để tạo tập con từ tập dữ liệu gốc dựa
trên các chỉ số đã chỉ định.
 train_dataset: Chứa dữ liệu huấn luyện.
 val_dataset: Chứa dữ liệu kiểm tra.
train_loader = DataLoader(train_dataset, batch_size=batch_size,
shuffle=True, num_workers=4 )
val_loader = DataLoader(val_dataset, batch_size=batch _size,
shuffle=False, num_workers=4)

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
10

 DataLoader: Một tiện ích của PyTorch để tải dữ liệu theo từng batch,
cung cấp một iterator (bộ lặp) qua tập dữ liệu.
 train_loader: Dùng để tải dữ liệu huấn luyện theo từng batch.
o batch_size=batch_size: Xác định số lượng mẫu trong mỗi batch.
o shuffle=True: Trộn ngẫu nhiên dữ liệu vào đầu mỗi epoch để
ngăn mô hình học theo thứ tự của dữ liệu.
 val_loader: Dùng để tải dữ liệu kiểm tra theo từng batch.
o shuffle=False: Không trộn dữ liệu kiểm tra, giữ nguyên thứ tự
của các mẫu.
 num_workers=4: Xác định số lượng luồng con (subprocesses) để tải
dữ liệu. Số lượng luồng con cao hơn có thể tăng tốc độ tải dữ liệu.
Bước 5: Lưu thông tin các đối tượng có trong dataset
with open(‘label.txt’, ‘w’) as f :
for idx, class_name in enumerat e(dataset.classes):
f.write(f'{idx}: {class_name}\n’)
Chương trình sẽ lưu id và tên của đối tượng vào file label.txt.
Bước 6: Tạo model, tối ưu và tạo hàm mất mát
model =
CustomEfficientNet(num_classes=len(dataset.classes)).to(device)
criterion = nn.C rossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
Khởi tạo mô hình CustomEfficientNet với tham số là số classes và chuyển
nó sang thiết bị (GPU hoặc CPU) để thực thi.
criterion = nn.CrossEntropyLoss():
Hàm mất mát này đo lường độ sai lệch giữa phân phối xác suất dự đoán của
mô hình và phân phối nhãn thật. Giá trị mất mát này càng nhỏ thì mô hình
dự đoán càng chính xác.
optimizer = optim.Adam(model.parameters(), lr=0.001):

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
11

 optim.Adam:
o Adam là một thuật toán tối ưu hóa rất phổ biến trong huấn luyện
mô hình học sâu, kết hợp giữa phương pháp tối ưu hóa theo
momentum và phương pháp tối ưu hóa theo hàm điều chỉnh
AdaGrad.
o Adam tự động điều chỉnh tốc độ học (learning rate) cho từng
tham số dựa trên các biến động trong quá trình huấn luyện, giúp
tăng tốc độ hội tụ và thường cho kết quả tốt hơn so với các bộ tối
ưu hóa khác như SGD.
 model.parameters():
o Tham số này lấy tất cả các tham số có thể huấn luyện được của
mô hình EfficientNet đã tạo trước đó. Bộ tối ưu hóa sẽ cập nhật
những tham số này trong quá trình huấn luyện.
 lr=0.001:
o lr là tốc độ học (learning rate), một tham số quan trọng quyết
định mức độ thay đổi của các tham số mô hình sau mỗi bước cập
nhật. Ở đây, tốc độ học được đặt là 0.001, một giá trị thường dùng
để khởi tạo trong nhiều bài toán học sâu.
optimizer.zero_grad():
Trước khi thực hiện tính toán gradients, cần đặt lại các gradients cũ (nếu có)
bằng zero_grad(). Điều này đảm bảo rằng gradients không bị cộng dồn từ
các vòng lặp trước đó.
loss = criterion(outputs, labels):
Hàm mất mát (criterion) so sánh đầu ra dự đoán (outputs) với nhãn thực tế
(labels) và tính toán giá trị mất mát (loss), biểu thị độ sai lệch của mô hình.
loss.backward():
backward() tính toán gradients của hàm mất mát đối với các tham số của mô
hình. Đây là bước đầu tiên trong quá trình cập nhật các tham số dựa trên
gradients.
Bước 7: Dự đoán nhãn và tính toán độ chính xác

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
12

_, preds = torch.max(outputs, 1):
torch.max(outputs, 1) lấy giá trị lớn nhất (có xác suất cao nhất) và chỉ số
tương ứng từ outputs dọc theo chiều thứ nhất (class dimension). preds là dự
đoán của mô hình về lớp đầu ra.
correct += (predicted == labels).sum().item()
Tính toán số lượng dự đoán chính xác trong mô hình.
predicted == labels so sánh từng phần tử trong predicted với từng phần tử
trong labels, tạo ra một tensor boolean cùng kích thước với predicted và
labels, với giá trị True nếu dự đoán đúng và False nếu không đúng.
Bước 8: Hiện thị thông tin kết quả train và lưu model
val_acc = 100 * val_correct / val_total
val_loss /= len(val_loader)
print(f’Epoch [{epoch+1}/{num_epochs}], Train Loss: {train_loss:.4f}, Train
Accuracy: {train_acc:.2f}%, Val Loss: {val_loss:.4f}, Val Accuracy:
{val_acc:.2f}%’)
 val_acc: Tính toán và lưu trữ độ chính xác của mô hình trên tập kiểm
tra.
 val_loss: Tính toán và lưu trữ mất mát trung bình của mô hình trên tập
kiểm tra.
 print(…): Hiển thị kết quả của epoch bao gồm: mất mát và độ chính
xác trên cả tập huấn luyện và tập kiểm tra. Điều này giúp bạn theo dõi
quá trình huấn luyện và kiểm tra mô hình, xác định xem mô hình có
cải thiện hay không qua các epoch.
if val_acc > best_acc :
best_acc = val_ac c
torch.save(model.state_dict(), model_path )
print(f’Saved best model with accuracy: {best_acc:.2f}%’)

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
13

Sau mỗi epoch train, kiểm tra tính chính xác, nếu độ chính xác tốt lên thì sẽ
lưu model với bộ trọng số này.
2.5. Chương trình test
Bước 1: Cần import một số thư viện và cấu trúc model
import t orch
import torchvision.transforms as transform s
from PIL import Imag e
from aicandy_model_src_ybklivqn.aicandy_efficientnet_model_mqialtec
import CustomEfficientNet
Bước 2: Xác định tên đối tượng có trong model
with open(label_path, ‘r’) as f :
labels = {int(line.split(“: “)[0]): line.split(“: “)[1].strip() for line in f}
Đoạn trên sẽ trả về cho labels một từ điển với cặp key-value, trong đó:
 key là ID của nhãn (dạng số nguyên).
 value là tên của nhãn (dạng chuỗi).
Bước 3: Load model
model = CustomEffici entNet(num_classes=len(labels))
model.load_state_dict(torch.load(model_path))
model.to(device)
model.eval()
Tạo cấu trúc model khi test giống như cấu trúc model khi train.
model.load_state_dict(torch.load(model_path, map_location=device))
 Tải trọng số của mô hình từ tệp model_path. Trọng số này là kết quả
của quá trình huấn luyện trước đó.
 map_location=device: Đảm bảo rằng trọng số được tải lên thiết bị
(device) cụ thể (CPU hoặc GPU), giúp tránh lỗi khi sử dụng mô hình
trên một thiết bị khác so với thiết bị đã huấn luyện.

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
14

model.eval()
Chuyển mô hình sang chế độ đánh giá (evaluation mode). Trong chế độ này,
các lớp như Dropout và BatchNorm sẽ hoạt động khác so với khi ở chế độ
huấn luyện.
transform = transforms.Compose( [
transforms.Resize((224, 224)) ,
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
Đoạn mã này định nghĩa một chuỗi các bước tiền xử lý (preprocessing) được
áp dụng cho các hình ảnh trước khi chúng được đưa vào mô hình học sâu.
Các bước tiền xử lý này giúp chuẩn hóa dữ liệu đầu vào và chuyển đổi hình
ảnh sang định dạng phù hợp cho mô hình. Trong đó:
 Normalize là bước chuẩn hóa từng kênh màu của hình ảnh (R, G, B)
bằng cách trừ đi giá trị trung bình (mean) và chia cho độ lệch chuẩn
(std).
 [0.485, 0.456, 0.406]: Đây là các giá trị trung bình của các kênh màu (R,
G, B) dựa trên bộ dữ liệu ImageNet, một bộ dữ liệu lớn phổ biến được
dùng để huấn luyện các mô hình học sâu.
 [0.229, 0.224, 0.225]: Đây là các giá trị độ lệch chuẩn tương ứng của các
kênh màu (R, G, B), cũng dựa trên bộ dữ liệu ImageNet.
 Chuẩn hóa này giúp đảm bảo rằng dữ liệu đầu vào có phân phối ổn
định, giúp mô hình học tốt hơn và tăng tốc độ hội tụ.
Bước 4: Dự đoán kết quả
with torch.no_grad() :
outputs = model(image )
_, predicted = torch.max(outputs, 1 )
with torch.no_grad():
 Đây là một ngữ cảnh (context) trong PyTorch, trong đó các phép tính
bên trong sẽ không yêu cầu lưu trữ thông tin về gradient.

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
15

 Điều này giúp tiết kiệm bộ nhớ và tăng tốc độ tính toán khi thực hiện
dự đoán, vì không cần tính toán và lưu trữ gradient như khi huấn
luyện mô hình.
 Chế độ này thường được sử dụng trong quá trình dự đoán (inference)
hoặc đánh giá mô hình.
torch.max(outputs, 1):
 Hàm torch.max tìm giá trị lớn nhất trong tensor outputs dọc theo
chiều thứ nhất (dim=1).
 Trong ngữ cảnh phân loại, mỗi giá trị trong outputs đại diện cho xác
suất hoặc độ tin cậy rằng ảnh thuộc về một lớp cụ thể.
 Kết quả trả về là một tuple với hai phần tử:
o Phần tử đầu tiên (_) là giá trị lớn nhất (có thể bỏ qua ở đây).
o Phần tử thứ hai (predicted) là chỉ số (index) của giá trị lớn nhất,
tương ứng với lớp mà mô hình dự đoán.
predicted_class = predicted.item()
predicted.item():
 Phương thức item() chuyển đổi một tensor có kích thước 1 (một giá trị
duy nhất) thành một giá trị số Python thông thường (integer).
2.6. Chương trình chuyển đổi model
Bước 1: Load model
model = CustomEfficientNet(num_classes=num_classes )
model.load_state_dict(torch.load(model_path))
model.to(device)
model.eval()
Tạo cấu trúc model khi test giống như cấu trúc model khi train.
model.load_state_dict(torch.load(model_path, map_location=device))

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
16

 Tải trọng số của mô hình từ tệp model_path. Trọng số này là kết quả
của quá trình huấn luyện trước đó.
 map_location=device: Đảm bảo rằng trọng số được tải lên thiết bị
(device) cụ thể (CPU hoặc GPU), giúp tránh lỗi khi sử dụng mô hình
trên một thiết bị khác so với thiết bị đã huấn luyện.
model.eval()
Chuyển mô hình sang chế độ đánh giá (evaluation mode). Trong chế độ này,
các lớp như Dropout và BatchNorm sẽ hoạt động khác so với khi ở chế độ
huấn luyện.
Bước 2: Convert model
dummy_input = torch.randn(1, 3, 224, 224, device=device):
torch.randn tạo ra một tensor với các giá trị ngẫu nhiên tuân theo phân phối
chuẩn (mean=0, std=1). Kích thước của tensor này là (1, 3, 224, 224)
torch.onnx.export(model, # mô hình đang ch ạy
dummy_input, # input tenso r
onnx_path, # n ơi lưu file onn x
export_params=True, # lưu các trọng số đã training
opset_version=11, # phiên b ản O NNX
do_constant_folding=True, # tối ưu hoá mô hình
input_names = [‘input’], # tên c ủa input
output_names = [‘output’], # tên c ủa output
dynamic_axes={‘input’ : {0 : ‘batch_size’}, # kích thước batch có thể thay
đổi
‘output’ : {0 : ‘batch_size’}})
 torch.onnx.export:
o Đây là hàm dùng để xuất mô hình PyTorch sang định dạng
ONNX.
 dummy_input:
o Đây là đầu vào giả lập mà mô hình sẽ sử dụng để theo dõi các
phép toán và xây dựng biểu đồ tính toán trong định dạng
ONNX.

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
17

 onnx_path:
o Đường dẫn đến file mà mô hình ONNX sẽ được lưu (file có phần
mở rộng là .onnx).
 input_names=[‘input’]:
o Tên của các đầu vào trong mô hình ONNX. Ở đây, đầu vào của
mô hình sẽ được đặt tên là “input”.
 output_names=[‘output’]:
o Tên của các đầu ra trong mô hình ONNX. Ở đây, đầu ra của mô
hình sẽ được đặt tên là “output”.
3. Kết quả train
Thực hiện train với epoch 100, độ chính xác là 90.24%, đạt được ở epoch 83.
Độ chính xác sẽ tăng lên khi epoch tăng thêm, số lượng mẫu trong dataset
tăng lên. Dưới đây là log train ở 50 epoch cuối:
Epoch [50/100], Train Loss: 0.1136, Train Accuracy: 95.36%, Val
Loss: 0.3742, Val Accuracy: 87.86%
Saved best model with accuracy: 87.86%
Epoch [51/100], Train Loss: 0.1349, Train Accuracy: 94.67%, Val
Loss: 0.3785, Val Accuracy: 86.23%
Epoch [52/100], Train Loss: 0.1171, Train Accuracy: 95.39%, Val
Loss: 0.3768, Val Accuracy: 85.98%
Epoch [53/100], Train Loss: 0.1266, Train Accuracy: 95.08%, Val
Loss: 0.3834, Val Accuracy: 88.11%
Saved best model with accuracy: 88.11%
Epoch [54/100], Train Loss: 0.1247, Train Accuracy: 95.05%, Val
Loss: 0.3814, Val Accuracy: 86.86%
Epoch [55/100], Train Loss: 0.1206, Train Accuracy: 95.30%, Val
Loss: 0.4882, Val Accuracy: 85.61%
Epoch [56/100], Train Loss: 0.1098, Train Accuracy: 95.90%, Val
Loss: 0.4696, Val Accuracy: 86.48%
Epoch [57/100], Train Loss: 0.1112, Train Accuracy: 95.74%, Val
Loss: 0.4220, Val Accuracy: 88.49%
Saved best model with accuracy: 88.49%

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
18

Epoch [58/100], Train Loss: 0.1014, Train Accuracy: 95.86%, Val
Loss: 0.4420, Val Accuracy: 86.98%
Epoch [59/100], Train Loss: 0.0969, Train Accuracy: 96.40%, Val
Loss: 0.3980, Val Accuracy: 85.73%
Epoch [60/100], Train Loss: 0.1032, Train Accuracy: 96.33%, Val
Loss: 0.3945, Val Accuracy: 86.48%
Epoch [61/100], Train Loss: 0.0969, Train Accuracy: 96.08%, Val
Loss: 0.3519, Val Accuracy: 88.86%
Saved best model with accuracy: 88.86%
Epoch [62/100], Train Loss: 0.0801, Train Accuracy: 97.06%, Val
Loss: 0.4664, Val Accuracy: 86.11%
Epoch [63/100], Train Loss: 0.1022, Train Accuracy: 96.15%, Val
Loss: 0.4272, Val Accuracy: 86.98%
Epoch [64/100], Train Loss: 0.0955, Train Accuracy: 96.15%, Val
Loss: 0.3885, Val Accuracy: 87.73%
Epoch [65/100], Train Loss: 0.0809, Train Accuracy: 96.59%, Val
Loss: 0.4389, Val Accuracy: 87.36%
Epoch [66/100], Train Loss: 0.0886, Train Accuracy: 96.68%, Val
Loss: 0.3716, Val Accuracy: 87.11%
Epoch [67/100], Train Loss: 0.0942, Train Accuracy: 96.71%, Val
Loss: 0.3541, Val Accuracy: 89.74%
Saved best model with accuracy: 89.74%
Epoch [68/100], Train Loss: 0.0900, Train Accuracy: 96.62%, Val
Loss: 0.4122, Val Accuracy: 87.36%
Epoch [69/100], Train Loss: 0.0697, Train Accuracy: 97.34%, Val
Loss: 0.4365, Val Accuracy: 84.61%
Epoch [70/100], Train Loss: 0.0737, Train Accuracy: 96.99%, Val
Loss: 0.4590, Val Accuracy: 88.99%
Epoch [71/100], Train Loss: 0.0830, Train Accuracy: 96.87%, Val
Loss: 0.3986, Val Accuracy: 86.48%
Epoch [72/100], Train Loss: 0.0884, Train Accuracy: 96.74%, Val
Loss: 0.3729, Val Accuracy: 87.36%
Epoch [73/100], Train Loss: 0.0662, Train Accuracy: 97.53%, Val
Loss: 0.4258, Val Accuracy: 86.61%
Epoch [74/100], Train Loss: 0.0648, Train Accuracy: 97.78%, Val
Loss: 0.3752, Val Accuracy: 87.48%

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
19

Epoch [75/100], Train Loss: 0.0740, Train Accuracy: 97.02%, Val
Loss: 0.3809, Val Accuracy: 88.61%
Epoch [76/100], Train Loss: 0.0775, Train Accuracy: 96.99%, Val
Loss: 0.3957, Val Accuracy: 87.11%
Epoch [77/100], Train Loss: 0.0628, Train Accuracy: 97.74%, Val
Loss: 0.4272, Val Accuracy: 87.73%
Epoch [78/100], Train Loss: 0.0875, Train Accuracy: 96.65%, Val
Loss: 0.3273, Val Accuracy: 88.99%
Epoch [79/100], Train Loss: 0.0738, Train Accuracy: 96.99%, Val
Loss: 0.4264, Val Accuracy: 88.11%
Epoch [80/100], Train Loss: 0.0528, Train Accuracy: 97.96%, Val
Loss: 0.4234, Val Accuracy: 89.86%
Saved best model with accuracy: 89.86%
Epoch [81/100], Train Loss: 0.0625, Train Accuracy: 97.49%, Val
Loss: 0.3307, Val Accuracy: 90.11%
Saved best model with accuracy: 90.11%
Epoch [82/100], Train Loss: 0.0642, Train Accuracy: 97.56%, Val
Loss: 0.3881, Val Accuracy: 89.49%
Epoch [83/100], Train Loss: 0.0641, Train Accuracy: 97.59%, Val
Loss: 0.3951, Val Accuracy: 90.24%
Saved best model with accuracy: 90.24%
Epoch [84/100], Train Loss: 0.0552, Train Accuracy: 97.78%, Val
Loss: 0.3671, Val Accuracy: 86.73%
Epoch [85/100], Train Loss: 0.0608, Train Accuracy: 97.93%, Val
Loss: 0.4316, Val Accuracy: 87.98%
Epoch [86/100], Train Loss: 0.0551, Train Accuracy: 98.15%, Val
Loss: 0.4410, Val Accuracy: 87.73%
Epoch [87/100], Train Loss: 0.0469, Train Accuracy: 98.40%, Val
Loss: 0.4497, Val Accuracy: 88.24%
Epoch [88/100], Train Loss: 0.0654, Train Accuracy: 97.68%, Val
Loss: 0.3706, Val Accuracy: 89.74%
Epoch [89/100], Train Loss: 0.0555, Train Accuracy: 97.90%, Val
Loss: 0.3796, Val Accuracy: 87.86%
Epoch [90/100], Train Loss: 0.0479, Train Accuracy: 98.46%, Val
Loss: 0.3689, Val Accuracy: 89.24%

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
20

Epoch [91/100], Train Loss: 0.0595, Train Accuracy: 97.71%, Val
Loss: 0.3745, Val Accuracy: 89.11%
Epoch [92/100], Train Loss: 0.0493, Train Accuracy: 98.34%, Val
Loss: 0.4593, Val Accuracy: 87.36%
Epoch [93/100], Train Loss: 0.0456, Train Accuracy: 98.43%, Val
Loss: 0.4451, Val Accuracy: 88.61%
Epoch [94/100], Train Loss: 0.0543, Train Accuracy: 98.09%, Val
Loss: 0.4896, Val Accuracy: 87.23%
Epoch [95/100], Train Loss: 0.0655, Train Accuracy: 97.78%, Val
Loss: 0.4442, Val Accuracy: 86.23%
Epoch [96/100], Train Loss: 0.0486, Train Accuracy: 98.37%, Val
Loss: 0.4353, Val Accuracy: 87.48%
Epoch [97/100], Train Loss: 0.0497, Train Accuracy: 98.09%, Val
Loss: 0.4545, Val Accuracy: 87.11%
Epoch [98/100], Train Loss: 0.0478, Train Accuracy: 98.21%, Val
Loss: 0.4523, Val Accuracy: 89.24%
Epoch [99/100], Train Loss: 0.0418, Train Accuracy: 98.50%, Val
Loss: 0.4245, Val Accuracy: 87.86%
Epoch [100/100], Train Loss: 0.0355, Train Accuracy: 98.62%, Val
Loss: 0.4966, Val Accuracy: 86.61%
root@aicandy:/aicandy/projects/AIcandy_Efficientnet_ImageClassificat
ion_rlbyvacq#
Model đ ược l ưu t ại:
aicandy_model_out_vailsuom/aicandy_model_pth_ppxascdt.pth
root@aicandy:/aicandy/projects/AIcandy_Efficientnet_ImageClassificat
ion_rlbyvacq# ls aicandy_model_out_vailsuom
aicandy_model_pth_ppxascdt.pth
root@aicandy:/aicandy/projects/AIcandy_Efficientnet_ImageClassificat
ion_rlbyvacq#
4. Kết quả test
Thử nghiệm test với hình ảnh có ‘dog’, chương trình nhận dạng đúng.

https://aicandy.vn/ung-dung-mang-efficientnet-vao-phan-loai-hinh-anh/
Bản quyền thuộc về: https://aicandy.vn


Học tập toàn diện: Kết nối lý thuyết, thực hành và dữ liệu thực tế
https://aicandy.vn
21


root@aicandy:/aicandy/projects/AIcandy_Efficientnet_ImageClassificat
ion_rlbyvacq# python aicandy_efficientnet_test_gmbpqtln.py --
image_path ../aicandy_true_dog.jpg --model_path
aicandy_model_out_vailsuom/aicandy_model_pth_ppxascdt.pth --
label_path label.txt
labels: {0: 'cats', 1: 'dogs'}
Predicted class: dogs
root@aicandy:/aicandy/projects/AIcandy_Efficientnet_ImageClassificat
ion_rlbyvacq#
5. Source code
Toàn bộ source code được public miễn phí tại đây
Bài trước
Danh mục
Bài sau
Chúc bạn thành công trong hành trình khám phá và ứng dụng trí tuệ nhân tạo
vào học tập và công việc. Đừng quên truy cập thường xuyên để cập nhật thêm
kiến thức mới tại AIcandy