Ứng dụng mạng ResNet-50 vào bài toán phân loại hình ảnh.pdf

aicandy 248 views 19 slides Dec 01, 2024
Slide 1
Slide 1 of 19
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

About This Presentation

Xây dựng một hệ thống phát hiện và nhận diện đối tượng dựa trên mạng neural RetinaNet. Hệ thống này sẽ xác định đối tượng bằng cách khoanh hình chữ nhật bao quanh đối tượng và hiển thị tên của đối tượng, sau đó lưu lại hì...


Slide Content

https://aicandy.vn/ung-dung-mang-resnet-50-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 ResNet-50 vào bài
toán 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 ResNet-50. 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-resnet-50-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_ResNet50_ImageClassification_
ibuyesha# tree
.
├── aicandy_resnet50_convert_onnx_nuuipbl e.py
├── aicandy_resnet50_test_ycmlontg.py
├── aicandy_resnet50_train_exydumnh.py
├── aicandy_model_out_lgqllayc
└── aicandy_model_src_supduior
└── aicandy_resnet50_model_ycrrignm.py
Trong đó:
– File aicandy_resnet50_model_ycrrignm.py chứa model
– File aicandy_resnet50_train_exydumnh.py chứa chương trình train
– File aicandy_resnet50_test_ycmlontg.py chứa chương trình để test.
– File aicandy_resnet50_convert_onnx_nuuipble.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/

https://aicandy.vn/ung-dung-mang-resnet-50-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

root@aicandy:/aicandy/projects/dataset/cats# tree | head -n 6
.
├── 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 BasicBlock(nn.Module):
Đây là khối cơ bản chịu trách nhiệm thực hiện các phép biến đổi trong mô
hình.
self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3,
stride=stride, padding=1, bias=False):
Quá trình này giúp trích xuất các đặc trưng cục bộ từ đầu vào, chẳng hạn
như cạnh, góc, hoặc các mẫu hình khác trong hình ảnh. Thay đổi từ một đầu

https://aicandy.vn/ung-dung-mang-resnet-50-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

vào có in_channels kênh, lớp tích chập này sẽ tạo ra một đầu ra với
out_channels kênh.
stride=stride
Tham số stride=stride quy định khoảng cách mà cửa sổ tích chập sẽ di
chuyển mỗi lần quét qua đầu vào. Nếu stride lớn hơn 1, kích thước không
gian (chiều rộng và chiều cao) của đầu ra sẽ nhỏ hơn so với đầu vào. Điều
này giúp giảm kích thước không gian của dữ liệu khi đi qua mạng, điều quan
trọng để giảm độ phức tạp và tăng tốc độ tính toán.
padding=1
Tham số padding=1 thêm một lớp pixel 0 xung quanh biên của ảnh đầu vào
để giữ nguyên kích thước không gian của đầu ra sau khi áp dụng tích chập.
Điều này đảm bảo rằng đầu ra sau lớp tích chập vẫn có cùng kích thước
không gian với đầu vào, giúp duy trì tính toàn vẹn của dữ liệu.
self.bn1 = nn.BatchNorm2d(out_channels)
Tạo ra một lớp Batch Normalization trong mạng nơ-ron sâu. Đây là một kỹ
thuật phổ biến để ổn định và tăng tốc độ huấn luyện mô hình.
self.relu = nn.ReLU(inplace=True)
 ReLU là một hàm kích hoạt phi tuyến đơn giản nhưng hiệu quả,
chuyển đổi các giá trị âm thành 0 và giữ nguyên các giá trị dương. Điều
này giúp mô hình học các đặc trưng phi tuyến tính và cải thiện hiệu
suất so với các hàm kích hoạt tuyến tính hoặc sigmoid truyền thống.
 inplace=True chỉ ra rằng hàm ReLU sẽ thực hiện thay đổi trực tiếp
trên bộ nhớ đầu vào mà không tạo ra một bản sao mới, giúp tiết kiệm
bộ nhớ và tăng tốc độ xử lý.
def forward(self, x):
Hàm forward này thực hiện quá trình truyền dữ liệu qua khối residual, kết
hợp giữa tích chập, chuẩn hóa, và phép cộng dư (residual connection) để giữ
lại thông tin trong mạng.

https://aicandy.vn/ung-dung-mang-resnet-50-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

identity = self.downsample(x)
Đảm bảo rằng kích thước của đầu vào (identity) và kích thước của đầu ra của
khối chính là cùng kích thước trước khi thực hiện phép cộng residual (nối
kết). Trong các khối residual, đầu vào x sẽ được cộng với đầu ra của các phép
toán chính sau khi kích thước đã được điều chỉnh.
class ResNet(nn.Module):
Khởi tạo một lớp ResNet, một loại mạng nơ-ron sâu, với các tham số để cấu
hình loại khối được sử dụng, số lượng khối trong mỗi lớp, và số lớp đầu ra.
Việc kế thừa từ nn.Module đảm bảo rằng lớp này có thể tích hợp đầy đủ vào
hệ sinh thái của PyTorch.
self.in_channels = 64
Số lượng kênh đầu vào được chọn là 64 vì nó là một giá trị hợp lý đã được
chuẩn hóa trong các kiến trúc ResNet, cân bằng tốt giữa độ phức tạp và khả
năng học đặc trưng từ dữ liệu đầu vào.
self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
Khởi tạo một lớp max pooling 2D trong PyTorch. Đây là một lớp thường
được sử dụng trong các mạng nơ-ron tích chập (CNNs) để giảm kích thước
của đầu vào và giữ lại các đặc trưng quan trọng.
self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
Khởi tạo một lớp Adaptive Average Pooling 2D trong PyTorch. Lớp này
thực hiện phép pooling với kích thước đầu ra được xác định trước, bất kể
kích thước đầu vào.
self.fc = nn.Linear(512 * block.expansion, num_classes)
Khởi tạo một lớp fully connected (FC) trong PyTorch. Đây là lớp cuối cùng
của mô hình, nơi nó chuyển đổi đầu ra từ các lớp trước đó thành số lượng
lớp phân loại mong muốn. Lớp nn.Linear sẽ áp dụng phép nhân ma trận và

https://aicandy.vn/ung-dung-mang-resnet-50-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

thêm bias để ánh xạ đầu ra từ các lớp trước đó thành đầu ra của số lớp phân
loại.
def ResNet50(num_clas ses=2):
return ResNet(BasicBlock, [3, 4, 6, 3], num_classes)
ResNet-50 bao gồm tổng cộng 50 lớp, không tính các lớp lớp tích chập
(convolutional layers) và lớp pooling, được chia làm 4 giai đoạn, mỗi giai
đoạn sử dụng số khối residual được cấu hình trong mảng [3, 4, 6, 3].
2.4. Chương trình train
Bước 1: Thư viện
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, random_split,
train_test_split, Dataloader).
import o s
import torc h
import torch.nn as n n
import torch.optim as opti m
from torchvision import datasets, transform s
from torch.utils.data import DataLoader, random_spli t
from aicandy_model_src_supduior.aicandy_resnet50_model_ycrrignm
import resnet50
Bước 2: Nâng cao hiệu năng với GPU
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
Tăng cường dữ liệu bằng sử dụng transforms, chia ra transforms cho tập
‘train’ và transforms cho tập ‘val’ với mục đích:

https://aicandy.vn/ung-dung-mang-resnet-50-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

transforms cho tập ‘train’
Mục tiêu chính của tập huấn luyện là giúp mô hình học được các đặc trưng
hữu ích và tổng quát. Data augmentation giúp làm phong phú tập dữ liệu
bằng cách tạo ra nhiều biến thể của các hình ảnh gốc. Điều này làm cho mô
hình bớt nhạy cảm với các thay đổi nhỏ và học được các đặc trưng mạnh mẽ
hơn.
transforms cho tập ‘val’
Trong quá trình kiểm tra/đánh giá, mục tiêu là đánh giá mô hình trên các
dữ liệu chưa được nhìn thấy (unseen data) mà không thay đổi bản chất của
hình ảnh. Vì vậy, các phép biến đổi cần bảo toàn hình ảnh nguyên gốc để kết
quả đánh giá được chính xác và phản ánh đúng khả năng của mô hình.
transforms.RandomResizedCrop(224)
Thực hiện việc cắt (crop) ngẫu nhiên một vùng từ ảnh gốc, sau đó thay đổi
kích thước vùng cắt đó về kích thước 224×224 pixel.
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.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-resnet-50-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

Bước 4: Load data và phân chia thành 2 tập train và val để đánh giá model
train_dataset, val_dataset = random_split(dataset, [train_size, val_size])
Chia một tập dữ liệu (dataset) thành hai tập con: một tập dùng để huấn luyện
(train_dataset) và một tập dùng để kiểm tra hoặc xác thực (val_dataset).
Thông thường tập train chiếm 80% và tập val chiếm 20% tổng mẫu.
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)
Sử dụng DataLoader để tải dữ liệu từ một đối tượng Dataset.
 batch_size=batch_size: Xác định số lượng mẫu trong mỗi lô. Giá trị
batch_size được xác định trước đó trong mã của bạn. thông thường
hay chọnbatch_size là 16 hoặc 32.
 shuffle=True: Tùy chọn shuffle=True sẽ xáo trộn dữ liệu mỗi lần trước
khi tạo ra các lô mới trong quá trình huấn luyện. Điều này giúp giảm
thiểu khả năng mô hình nhớ vị trí của các mẫu và dẫn đến overfitting
(quá khớp). Xáo trộn dữ liệu trong quá trình huấn luyện là một thực
hành tốt giúp mô hình học được các đặc trưng một cách tổng quát hơn.
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 enumerate(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 = resnet50(num_classes=num_classes).to(device)
Khởi tạo mô hình resnet50 với các tham số cụ thể và chuyển nó sang thiết bị
(GPU hoặc CPU) để thực thi.

https://aicandy.vn/ung-dung-mang-resnet-50-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

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):
 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 DenseNet mà bạn đã 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.

https://aicandy.vn/ung-dung-mang-resnet-50-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

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
_, 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.
corrects += (predicted == labels).sum().item()
Tổng hợp số lượng dự đoán chính xác từ tất cả các lô dữ liệu trong quá trình
đánh giá.
Bước 8: Hiện thị thông tin kết quả train và lưu model
val_acc = 100 * corrects/ total
val_loss = val_loss / len(val_dataset)
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.
2.5. Chương trình test

https://aicandy.vn/ung-dung-mang-resnet-50-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

Bước 1: Cần import một số thư viện và cấu trúc model
import torc h
import torch.nn as n n
from torchvision import transform s
from PIL import Imag e
from aicandy_model_src_supduior.aicandy_resnet50_model_ycrrignm
import resnet50
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 = resnet50(num_classes=num_classes).to(device )
model.load_state_dict(torch.load(model_path))
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))
 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 đó.
transform = transforms.Compose( [
transforms.Resize((224, 224)) ,
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

https://aicandy.vn/ung-dung-mang-resnet-50-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

Đ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 đó:

o 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).
o [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.
o [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.
o 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.
 Đ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).

https://aicandy.vn/ung-dung-mang-resnet-50-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

 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 = resnet50(num_classes=num_classes )
state_dict = torch.load(model_path, map_location=’cpu’ )
model.load_state_dict(state_dict)
model.eval()
Tạo cấu trúc model khi test giống như cấu trúc model khi train.
 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.

https://aicandy.vn/ung-dung-mang-resnet-50-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

Bước 2: Convert model
torch.onnx.export(model, # mô hình đang ch ạy
dummy_input, # input tenso r
onnx_path, # nơi lưu file onnx
opset_version=11, # phiên bản ONNX
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.
 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 50, độ chính xác là 80.48%, đạt được ở epoch 48.
Đây là chương trình mẫu, để tăng độ chính xác, chúng ta cũng cần điều chỉnh
thêm một số tham số, tăng epoch cũng như tăng số lượng mẫu. Dưới đây là
log train:

https://aicandy.vn/ung-dung-mang-resnet-50-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

Epoch [1/50], Train Loss: 0.8015, Train Accuracy: 56.91%, Val Loss:
0.6611, Val Accuracy: 61.83%
Model saved with accuracy: 61.83%
Epoch [2/50], Train Loss: 0.6715, Train Accuracy: 59.85%, Val Loss:
0.6625, Val Accuracy: 62.33%
Model saved with accuracy: 62.33%
Epoch [3/50], Train Loss: 0.6649, Train Accuracy: 60.23%, Val Loss:
0.6817, Val Accuracy: 59.45%
Epoch [4/50], Train Loss: 0.6390, Train Accuracy: 63.64%, Val Loss:
0.7617, Val Accuracy: 60.20%
Epoch [5/50], Train Loss: 0.6327, Train Accuracy: 64.74%, Val Loss:
0.6189, Val Accuracy: 66.83%
Model saved with accuracy: 66.83%
Epoch [6/50], Train Loss: 0.6102, Train Accuracy: 66.58%, Val Loss:
0.6517, Val Accuracy: 61.33%
Epoch [7/50], Train Loss: 0.5969, Train Accuracy: 67.77%, Val Loss:
0.6019, Val Accuracy: 66.96%
Model saved with accuracy: 66.96%
Epoch [8/50], Train Loss: 0.5912, Train Accuracy: 69.15%, Val Loss:
0.7201, Val Accuracy: 66.83%
Epoch [9/50], Train Loss: 0.5816, Train Accuracy: 70.47%, Val Loss:
0.5809, Val Accuracy: 67.33%
Model saved with accuracy: 67.33%
Epoch [10/50], Train Loss: 0.5493, Train Accuracy: 72.88%, Val Loss:
0.5614, Val Accuracy: 70.71%
Model saved with accuracy: 70.71%
Epoch [11/50], Train Loss: 0.5448, Train Accuracy: 72.60%, Val Loss:
0.5325, Val Accuracy: 73.84%
Model saved with accuracy: 73.84%
Epoch [12/50], Train Loss: 0.5086, Train Accuracy: 74.54%, Val Loss:
0.5538, Val Accuracy: 73.34%
Epoch [13/50], Train Loss: 0.5021, Train Accuracy: 75.98%, Val Loss:
0.5740, Val Accuracy: 70.34%
Epoch [14/50], Train Loss: 0.4961, Train Accuracy: 76.23%, Val Loss:
0.4879, Val Accuracy: 77.60%

https://aicandy.vn/ung-dung-mang-resnet-50-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

Model saved with accuracy: 77.60%
Epoch [15/50], Train Loss: 0.4647, Train Accuracy: 77.83%, Val Loss:
0.6168, Val Accuracy: 71.71%
Epoch [16/50], Train Loss: 0.4649, Train Accuracy: 78.70%, Val Loss:
0.8707, Val Accuracy: 69.09%
Epoch [17/50], Train Loss: 0.4510, Train Accuracy: 78.80%, Val Loss:
0.4944, Val Accuracy: 76.22%
Epoch [18/50], Train Loss: 0.4192, Train Accuracy: 80.18%, Val Loss:
0.4886, Val Accuracy: 76.85%
Epoch [19/50], Train Loss: 0.4131, Train Accuracy: 80.65%, Val Loss:
0.5199, Val Accuracy: 75.22%
Epoch [20/50], Train Loss: 0.3736, Train Accuracy: 82.96%, Val Loss:
0.5196, Val Accuracy: 75.84%
Epoch [21/50], Train Loss: 0.3683, Train Accuracy: 82.84%, Val Loss:
0.4740, Val Accuracy: 78.35%
Model saved with accuracy: 78.35%
Epoch [22/50], Train Loss: 0.3602, Train Accuracy: 83.96%, Val Loss:
0.6655, Val Accuracy: 71.71%
Epoch [23/50], Train Loss: 0.3299, Train Accuracy: 85.16%, Val Loss:
0.4520, Val Accuracy: 78.72%
Model saved with accuracy: 78.72%
Epoch [24/50], Train Loss: 0.3060, Train Accuracy: 87.47%, Val Loss:
0.5303, Val Accuracy: 77.35%
Epoch [25/50], Train Loss: 0.2630, Train Accuracy: 88.82%, Val Loss:
0.6766, Val Accuracy: 74.09%
Epoch [26/50], Train Loss: 0.2522, Train Accuracy: 89.60%, Val Loss:
0.6619, Val Accuracy: 76.22%
Epoch [27/50], Train Loss: 0.2499, Train Accuracy: 89.85%, Val Loss:
0.5494, Val Accuracy: 79.22%
Model saved with accuracy: 79.22%
Epoch [28/50], Train Loss: 0.1948, Train Accuracy: 92.20%, Val Loss:
0.6128, Val Accuracy: 76.72%
Epoch [29/50], Train Loss: 0.1703, Train Accuracy: 93.61%, Val Loss:
0.6567, Val Accuracy: 77.60%

https://aicandy.vn/ung-dung-mang-resnet-50-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

Epoch [30/50], Train Loss: 0.1493, Train Accuracy: 94.21%, Val Loss:
0.6480, Val Accuracy: 78.35%
Epoch [31/50], Train Loss: 0.1189, Train Accuracy: 96.15%, Val Loss:
0.9286, Val Accuracy: 73.59%
Epoch [32/50], Train Loss: 0.1188, Train Accuracy: 95.24%, Val Loss:
0.9500, Val Accuracy: 77.60%
Epoch [33/50], Train Loss: 0.1088, Train Accuracy: 95.62%, Val Loss:
0.8101, Val Accuracy: 77.10%
Epoch [34/50], Train Loss: 0.0809, Train Accuracy: 97.15%, Val Loss:
0.6892, Val Accuracy: 78.72%
Epoch [35/50], Train Loss: 0.0914, Train Accuracy: 96.62%, Val Loss:
0.8397, Val Accuracy: 77.10%
Epoch [36/50], Train Loss: 0.0729, Train Accuracy: 97.31%, Val Loss:
0.8193, Val Accuracy: 78.47%
Epoch [37/50], Train Loss: 0.0656, Train Accuracy: 97.84%, Val Loss:
0.8204, Val Accuracy: 77.72%
Epoch [38/50], Train Loss: 0.0645, Train Accuracy: 97.68%, Val Loss:
0.9117, Val Accuracy: 78.72%
Epoch [39/50], Train Loss: 0.0497, Train Accuracy: 98.31%, Val Loss:
0.9843, Val Accuracy: 77.10%
Epoch [40/50], Train Loss: 0.0303, Train Accuracy: 98.94%, Val Loss:
0.9070, Val Accuracy: 79.10%
Epoch [41/50], Train Loss: 0.0173, Train Accuracy: 98.50%, Val Loss:
1.0944, Val Accuracy: 79.85%
Model saved with accuracy: 79.85%
Epoch [42/50], Train Loss: 0.0547, Train Accuracy: 97.71%, Val Loss:
0.9461, Val Accuracy: 76.72%
Epoch [43/50], Train Loss: 0.0370, Train Accuracy: 98.65%, Val Loss:
0.9059, Val Accuracy: 78.35%
Epoch [44/50], Train Loss: 0.0485, Train Accuracy: 98.25%, Val Loss:
1.1661, Val Accuracy: 77.22%
Epoch [45/50], Train Loss: 0.0595, Train Accuracy: 98.06%, Val Loss:
1.3920, Val Accuracy: 73.72%
Epoch [46/50], Train Loss: 0.0391, Train Accuracy: 98.50%, Val Loss:
1.1306, Val Accuracy: 78.10%

https://aicandy.vn/ung-dung-mang-resnet-50-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 [47/50], Train Loss: 0.0214, Train Accuracy: 99.22%, Val Loss:
1.4119, Val Accuracy: 76.35%
Epoch [48/50], Train Loss: 0.0290, Train Accuracy: 99.06%, Val Loss:
1.0699, Val Accuracy: 80.48%
Model saved with accuracy: 80.48%
Epoch [49/50], Train Loss: 0.0200, Train Accuracy: 99.34%, Val Loss:
1.1179, Val Accuracy: 79.97%
Epoch [50/50], Train Loss: 0.0416, Train Accuracy: 98.65%, Val Loss:
0.9517, Val Accuracy: 78.85%
Model đ ược l ưu t ại:
aicandy_model_out_lgqllayc/aicandy_model_pth_ydvnemld.pth
root@aicandy:/aicandy/projects/AIcandy_ResNet50_ImageClassification_
ibuyesha# ls aicandy_model_out_lgqllayc
aicandy_model_pth_ydvnemld.pth
root@aicandy:/aicandy/projects/AIcandy_ResNet50_ImageClassification_
ibuyesha#
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.

root@aicandy:/aicandy/projects/AIcandy_ResNet50_ImageClassification_
ibuyesha# python aicandy_resnet50_test_ycmlontg.py --image_path

https://aicandy.vn/ung-dung-mang-resnet-50-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

../aicandy_true_dog.jpg --model_path
aicandy_model_out_lgqllayc/aicandy_model_pth_ydvnemld.pt h
labels: {0: 'cats', 1: 'dogs'}
Predicted class: dogs
root@aicandy:/aicandy/projects/AIcandy_ResNet50_ImageClassification_
ibuyesha#
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