DINOv2 Segmentation – Thử Nghiệm Fine-Tuning và Transfer Learning
Huấn luyện tự giám sát (SSL) của DINOv2 giúp nó học được những đặc trưng hình ảnh cực kỳ mạnh mẽ. Chúng ta có thể sử dụng backbone đã được huấn luyện này cho nhiều tác vụ hạ nguồn khác nhau, chẳng hạn như: phân loại ảnh, phân vùng ảnh, khớp đặc trưng và phát hiện đối tượng. Trong bài viết này, chúng ta sẽ thử nghiệm với DINOv2 segmentation bằng cách sử dụng fine-tuning (tinh chỉnh) và transfer learning (học chuyển giao).
Nhảy đến phần Tải Code
![So sánh các bản đồ phân vùng]([Đường dẫn hình ảnh])
Hình 1. So sánh giữa các bản đồ phân vùng với trọng số tốt nhất thu được thông qua các thử nghiệm huấn luyện fine-tuning và transfer learning DINOv2 Segmentation.
Những gì chúng ta sẽ đề cập trong các thử nghiệm segmentation, fine-tuning và transfer learning DINOv2?
Chúng ta sẽ trả lời các câu hỏi chính sau:
- Những đóng góp của bài viết này là gì?
- Làm thế nào để xây dựng một mô hình và quy trình huấn luyện đơn giản?
- Làm thế nào để thiết lập các thử nghiệm huấn luyện?
- Chúng ta nhận được kết quả gì trong mỗi thử nghiệm?
Lưu ý: Bài viết này là phần tiếp theo của bài viết trước, nơi chúng ta bắt đầu với các thử nghiệm phân vùng ngữ nghĩa DINOv2. Đây sẽ là một bài viết ngắn tập trung vào code mô hình và kết quả thử nghiệm.
Những đóng góp của bài viết này là gì?
Trong bài viết trước, chúng ta đã huấn luyện mô hình DINOv2 cho phân vùng ngữ nghĩa.
Chúng ta đã loại bỏ yêu cầu MMSegmentation khỏi quy trình mô hình hóa mà các tác giả ban đầu sử dụng. Hơn nữa, chúng ta đã xây dựng mô hình với pixel classification head (đầu phân loại pixel) như hiện tại trong codebase DINOv2 gốc cùng với các tham số mô hình được hardcode.
Điều này làm cho toàn bộ quy trình mô hình hóa trở nên phức tạp. Trong bài viết này, chúng ta sẽ giảm thiểu một số vấn đề. Để đạt được điều này, bài viết này có hai đóng góp chính:
- Đơn giản hóa quy trình mô hình hóa với một custom segmentation head (đầu phân vùng tùy chỉnh).
- Chạy các thử nghiệm fine-tuning và transfer learning cho DINOv2 Segmentation.
Như đã thảo luận trong bài viết trước, đây là một phần của một dự án lớn hơn và các thử nghiệm vẫn đang trong giai đoạn đầu. Do đó, chúng ta vẫn sẽ hardcode một số siêu tham số mô hình trong khi xây dựng nó.
Bộ Dữ Liệu Phân Vùng Người
Chúng ta sẽ sử dụng cùng một bộ dữ liệu phân vùng người như chúng ta đã làm trong bài viết trước. Vui lòng tham khảo nó để biết thêm chi tiết về bộ dữ liệu.
![Hình ảnh ground truth từ bộ dữ liệu Penn-Fudan Pedestrian segmentation.]([Đường dẫn hình ảnh])
Hình 2. Hình ảnh ground truth từ bộ dữ liệu Penn-Fudan Pedestrian segmentation.
Bạn có thể tải xuống bộ dữ liệu từ [đây]([Đường dẫn đến Kaggle]) trên Kaggle.
Cấu Trúc Thư Mục Dự Án
Hãy xem cấu trúc thư mục dự án trước khi chạy các thử nghiệm.
├── input
│ ├── inference_data
│ └── PennFudanPed
├── notebooks
│ └── visualize.ipynb
├── outputs
│ ├── fine_tuning
│ ├── transfer_learning
│ └── transfer_learning_schd
├── config.py
├── datasets.py
├── engine.py
├── infer_image.py
├── infer_video.py
├── metrics.py
├── model_config.py
├── model.py
├── requirements.txt
├── train.py
└── utils.py
content_copy download Use code with caution.
Chúng ta tuân theo gần như cùng một cấu trúc như bài viết trước.
- Thư mục inputs chứa bộ dữ liệu.
- Thư mục outputs chứa kết quả huấn luyện.
- Cuối cùng, thư mục dự án mẹ chứa các file Python.
Tất cả các file code Python, mô hình được huấn luyện tốt nhất từ mỗi thử nghiệm huấn luyện và dữ liệu suy luận đều có sẵn thông qua phần tải xuống.
Tải Code
[Tải xuống Source Code cho Hướng Dẫn này]([Đường dẫn tải xuống])
Tất cả các thư viện cần thiết có thể được cài đặt bằng file requirements.txt.
pip install -r requirements.txt
content_copy download Use code with caution.
Chạy Các Thử Nghiệm Transfer Learning và Fine Tuning Segmentation bằng DINOv2 Backbone
Trong phần này, chúng ta sẽ chủ yếu thảo luận về tất cả các phần code quan trọng cần thiết cho các thử nghiệm.
Mô Hình DINOv2 Segmentation Đã Sửa Đổi
Chúng ta sẽ thảo luận về những thay đổi cần thiết đã được thực hiện đối với mô hình phân vùng ngữ nghĩa DINOv2. Chúng ta đã đơn giản hóa phần mô hình hóa khá nhiều. Code sau đây có trong file model.py.
Hãy bắt đầu với tất cả các câu lệnh import.
# model.py
import torch
import torch.nn as nn
from functools import partial
from collections import OrderedDict
from torchinfo import summary
from model_config import model as model_dict
content_copy download Use code with caution.Python
Trong số các import cần thiết, chúng ta có model_dict từ model_config.
Trong bài viết trước, chúng ta đã tải xuống cấu hình mô hình ban đầu được sử dụng như một phần của các thử nghiệm MMSegmentation bởi các tác giả. Các file cấu hình này xác định backbone mô hình và model head cùng với các tham số huấn luyện. Tuy nhiên, trong bài viết này, chúng ta đã sử dụng nội dung từ các file đã tải xuống đó và lưu trữ chúng trong model_config.py. Chúng ta chỉ cần thông tin model_dict từ cấu hình. Trên thực tế, trong tương lai, chúng ta có thể có một file cấu hình riêng biệt xác định các siêu tham số của tất cả các mô hình.
Hàm Để Tải DINOv2 Backbone
Tiếp theo, chúng ta định nghĩa hàm load_backbone để tải DINOv2 Small backbone.
# model.py
def load_backbone():
BACKBONE_SIZE = "small" # in ("small", "base", "large" or "giant")
backbone_archs = {
"small": "vits14",
"base": "vitb14",
"large": "vitl14",
"giant": "vitg14",
}
backbone_arch = backbone_archs[BACKBONE_SIZE]
backbone_name = f"dinov2_{backbone_arch}"
backbone_model = torch.hub.load(repo_or_dir="facebookresearch/dinov2", model=backbone_name)
backbone_model.cuda()
backbone_model.forward = partial(
backbone_model.get_intermediate_layers,
n=model_dict['backbone']['out_indices'],
reshape=True,
)
return backbone_model
content_copy download Use code with caution.Python
Chúng ta định nghĩa các kiến trúc backbone và kiến trúc mà chúng ta muốn sử dụng. Chúng ta sử dụng TorchHub để tải backbone và chuyển nó sang thiết bị CUDA. Sau đó, chúng ta sử dụng cùng một chiến lược như trong bài viết trước để định nghĩa một phương thức partial sẽ trả về các đặc trưng từ 4 lớp khác nhau trong quá trình forward pass.
Linear Pixel Classifier
Nếu bạn đã đọc qua bài đăng trên blog trước, bạn có thể nhận ra rằng segmentation head rất phức tạp. Ở đây, chúng ta sẽ đơn giản hóa nó bằng cách sử dụng một số code như đã thảo luận trong [GitHub issue]([Đường dẫn đến issue]).
# model.py
class LinearClassifierToken(torch.nn.Module):
def __init__(self, in_channels, nc=1, tokenW=32, tokenH=32):
super(LinearClassifierToken, self).__init__()
self.in_channels = in_channels
self.W = tokenW
self.H = tokenH
self.nc = nc
self.conv = torch.nn.Conv2d(in_channels, nc, (1, 1))
def forward(self,x):
outputs = self.conv(
x.reshape(-1, self.in_channels, self.H, self.W)
)
return outputs
content_copy download Use code with caution.Python
Chúng ta định nghĩa lớp LinearClassifierToken chấp nhận các tham số sau:
- in_channels: Các kênh đầu vào cho lớp Convolutional phân loại pixel cuối cùng. Điều này phải có cùng kích thước với đầu ra từ DINOv2 backbone.
- nc: Số lượng lớp trong bộ dữ liệu.
- tokenW và tokenH: Chúng ta đang sử dụng mô hình DINOv2 Small Patch-14, tạo ra các patch có kích thước 14×14. Điều này có nghĩa là một hình ảnh đầu vào có kích thước 644×644 sẽ chứa 46 patch trên cả chiều rộng và chiều cao. Đây là các token có số lượng cần thiết để định hình lại đầu ra cuối cùng. Mặc dù giá trị mặc định là 32, chúng ta sẽ truyền giá trị chính xác trong quá trình khởi tạo. Đối với độ phân giải đầu vào là 644×644, đầu ra sẽ có hình dạng [batch_size, in_channels, 46, 46].
Mô Hình DINOv2 Segmentation Cuối Cùng
Cuối cùng, chúng ta kết hợp backbone và segmentation head bằng cách sử dụng một từ điển Ordered Sequential.
# model.py
class Dinov2Segmentation(nn.Module):
def __init__(self, fine_tune=False):
super(Dinov2Segmentation, self).__init__()
self.backbone_model = load_backbone()
print(fine_tune)
if fine_tune:
for name, param in self.backbone_model.named_parameters():
param.requires_grad = True
else:
for name, param in self.backbone_model.named_parameters():
param.requires_grad = False
self.decode_head = LinearClassifierToken(in_channels=1536, nc=2, tokenW=46, tokenH=46)
self.model = nn.Sequential(OrderedDict([
('backbone', self.backbone_model),
('decode_head', self.decode_head)
]))
def forward(self, x):
features = self.model.backbone(x)
# `features` is a tuple.
concatenated_features = torch.cat(features, 1)
classifier_out = self.decode_head(concatenated_features)
return classifier_out
content_copy download Use code with caution.Python
Lưu ý rằng backbone trả về một tuple các đặc trưng từ 4 lớp khác nhau. Chúng ta nối chúng trong forward pass để có kết quả tốt nhất. Các đặc trưng này sau đó được chuyển đến decode_head của mô hình.
Hơn nữa, vì chúng ta sẽ thực hiện cả thử nghiệm transfer learning và fine-tuning, lớp mô hình chấp nhận một tham số fine_tune mà chúng ta sử dụng để kiểm soát các tham số có thể huấn luyện trong backbone.
Điều này đưa chúng ta đến cuối phần xây dựng mô hình DINOv2 segmentation cho các thử nghiệm fine-tuning và transfer learning.
Phần còn lại của việc triển khai, chẳng hạn như chuẩn bị bộ dữ liệu, transforms và augmentations, vẫn hoàn toàn giống như bài viết trước.
Thử Nghiệm Transfer Learning cho DINOv2 Segmentation
Tất cả các thử nghiệm đã được chạy trên một hệ thống với GPU RTX 3080 10GB, RAM 32GB và CPU i7 thế hệ thứ 10.
Hãy bắt đầu với thử nghiệm transfer learning. Chúng ta có thể thực thi lệnh sau trong terminal bên trong thư mục dự án mẹ.
python train.py --lr 0.0005 --batch 2 --imgsz 640 640 --epochs 65 --out-dir transfer_learning
content_copy download Use code with caution.
Sau đây là các đối số dòng lệnh mà chúng ta đang sử dụng:
- –lr: Learning rate cơ bản cho optimizer. Đối với transfer learning, chúng ta sử dụng learning rate là 0.0005.
- –batch: Xác định batch size và chúng ta sử dụng giá trị là 2. Chúng ta sử dụng batch size nhỏ hơn vì trong quá trình fine-tuning, chúng ta sẽ huấn luyện tất cả các tham số và GPU 10GB chỉ có thể cấp phát batch size là 2. Để giữ cho kết quả thử nghiệm có thể so sánh được, chúng ta cũng sử dụng cùng batch size cho transfer learning.
- –imgsz: Độ phân giải mà hình ảnh và mask sẽ được thay đổi kích thước. Tất cả các mẫu sẽ được thay đổi kích thước thành độ phân giải 640×640 trước và sau đó được đệm với 4 pixel để tạo độ phân giải cuối cùng là 644×644.
- –epochs: Số lượng epoch mà mô hình được huấn luyện.
- –out-dir: Tên thư mục con bên trong thư mục outputs. Chúng ta duy trì một thư mục khác nhau cho mỗi thử nghiệm.
Sau đây là các đầu ra bị cắt ngắn từ terminal.
=============================================================================================================================
Layer (type (var_name)) Input Shape Output Shape Param #
=============================================================================================================================
Dinov2Segmentation (Dinov2Segmentation) [1, 3, 644, 644] [1, 2, 46, 46] --
├─Sequential (model) -- -- --
│ └─DinoVisionTransformer (backbone) [1, 3, 644, 644] [1, 384, 46, 46] 526,848
│ │ └─PatchEmbed (patch_embed) [1, 3, 644, 644] [1, 2116, 384] (226,176)
│ │ └─ModuleList (blocks) -- -- (21,302,784)
│ │ └─LayerNorm (norm) [1, 2117, 384] [1, 2117, 384] (768)
│ │ └─LayerNorm (norm) [1, 2117, 384] [1, 2117, 384] (recursive)
│ │ └─LayerNorm (norm) [1, 2117, 384] [1, 2117, 384] (recursive)
│ │ └─LayerNorm (norm) [1, 3, 644, 644] [1, 2117, 384] (recursive)
│ └─LinearClassifierToken (decode_head) [1, 1536, 46, 46] [1, 2, 46, 46] 3,074
│ │ └─Conv2d (conv) [1, 1536, 46, 46] [1, 2, 46, 46] 3,074
=============================================================================================================================
Total params: 22,062,724
Trainable params: 6,148
Non-trainable params: 22,056,576
Total mult-adds (Units.MEGABYTES): 506.39
=============================================================================================================================
Input size (MB): 4.98
Forward/backward pass size (MB): 1047.08
Params size (MB): 86.13
Estimated Total Size (MB): 1138.19
=============================================================================================================================
EPOCH: 1
Training
100%|████████████████████| 73/73 [00:05<00:00, 13.93it/s]
Validating
100%|████████████████████| 12/12 [00:01<00:00, 10.91it/s]
Best validation loss: 0.10560639388859272
Saving best model for epoch: 1
Best validation IoU: 0.7998962055528813
Saving best model for epoch: 1
Train Epoch Loss: 0.2430, Train Epoch PixAcc: 0.8928, Train Epoch mIOU: 0.725339
Valid Epoch Loss: 0.1056, Valid Epoch PixAcc: 0.8853 Valid Epoch mIOU: 0.799896
LR for next epoch: [0.0005]
--------------------------------------------------
EPOCH: 2
Training
100%|████████████████████| 73/73 [00:04<00:00, 14.67it/s]
Validating
100%|████████████████████| 12/12 [00:01<00:00, 11.02it/s]
Best validation loss: 0.0952610798800985
Saving best model for epoch: 2
Best validation IoU: 0.8058518124519641
Saving best model for epoch: 2
Train Epoch Loss: 0.2067, Train Epoch PixAcc: 0.9144, Train Epoch mIOU: 0.777027
Valid Epoch Loss: 0.0953, Valid Epoch PixAcc: 0.8876 Valid Epoch mIOU: 0.805852
LR for next epoch: [0.0005]
--------------------------------------------------
EPOCH: 3
Training
100%|████████████████████| 73/73 [00:05<00:00, 13.75it/s]
Validating
100%|████████████████████| 12/12 [00:01<00:00, 10.91it/s]
Best validation loss: 0.08329576129714648
Saving best model for epoch: 3
Best validation IoU: 0.8209524461889638
Saving best model for epoch: 3
Train Epoch Loss: 0.2058, Train Epoch PixAcc: 0.9150, Train Epoch mIOU: 0.779935
Valid Epoch Loss: 0.0833, Valid Epoch PixAcc: 0.8926 Valid Epoch mIOU: 0.820952
LR for next epoch: [0.0005]
--------------------------------------------------
.
.
.
EPOCH: 41
Training
100%|████████████████████| 73/73 [00:06<00:00, 12.16it/s]
Validating
100%|████████████████████| 12/12 [00:01<00:00, 10.49it/s]
Best validation loss: 0.06764321448281407
Saving best model for epoch: 41
Best validation IoU: 0.8373048613831366
Saving best model for epoch: 41
Train Epoch Loss: 0.1349, Train Epoch PixAcc: 0.9311, Train Epoch mIOU: 0.807703
Valid Epoch Loss: 0.0676, Valid Epoch PixAcc: 0.8978 Valid Epoch mIOU: 0.837305
LR for next epoch: [0.0005]
--------------------------------------------------
.
.
.
EPOCH: 65
Training
100%|████████████████████| 73/73 [00:05<00:00, 13.81it/s]
Validating
100%|████████████████████| 12/12 [00:01<00:00, 11.06it/s]
Best validation loss: 0.06727483573680122
Saving best model for epoch: 65
Train Epoch Loss: 0.1856, Train Epoch PixAcc: 0.9277, Train Epoch mIOU: 0.806646
Valid Epoch Loss: 0.0673, Valid Epoch PixAcc: 0.8975 Valid Epoch mIOU: 0.836716
LR for next epoch: [0.0005]
--------------------------------------------------
TRAINING COMPLETE
content_copy download Use code with caution.
Mô hình đạt mean IoU tốt nhất là 83.7% ở epoch 41. Để phân tích tốt hơn, hãy xem xét các đồ thị loss, accuracy và mean IoU.
![Đồ thị Loss sau khi thực hiện transfer learning]([Đường dẫn hình ảnh])
Hình 3. Đồ thị Loss sau khi thực hiện transfer learning bằng DINOv2 backbone và custom segmentation head.
![Đồ thị Pixel accuracy sau khi thực hiện transfer learning]([Đường dẫn hình ảnh])
Hình 4. Đồ thị Pixel accuracy sau khi thực hiện transfer learning bằng DINOv2 backbone và custom segmentation head.
![Đồ thị Mean IoU sau khi thực hiện transfer learning]([Đường dẫn hình ảnh])
Hình 5. Đồ thị Mean IoU sau khi thực hiện transfer learning bằng DINOv2 backbone và custom segmentation head.
Chúng ta có thể thấy rằng quá trình huấn luyện hơi không ổn định. Giải thích có khả năng nhất là chúng ta có thể bắt đầu với learning rate thấp hơn. Điều đó có thể làm cho quá trình học ổn định hơn, tuy nhiên, có một cơ hội tối thiểu là nó sẽ dẫn đến IoU cao hơn.
Một điểm thú vị khác cần lưu ý ở đây là mean IoU đạt hơn 82% vào cuối epoch 3. Điều này cho thấy rằng DINOv2 backbone đã học được các đặc trưng mạnh mẽ, dẫn đến quá trình huấn luyện segmentation head nhanh hơn.
Thử Nghiệm Fine-Tuning cho DINOv2 Segmentation
Bây giờ, hãy thực hiện thử nghiệm fine-tuning, nơi chúng ta sẽ huấn luyện cả backbone và segmentation head.
python train.py --lr 0.00001 --batch 2 --imgsz 640 640 --epochs 65 --out-dir fine_tuning --fine-tune --scheduler --scheduler-epochs 45
content_copy download Use code with caution.
Ở đây, chúng ta có một số đối số dòng lệnh bổ sung.
- –fine-tune: Đây là một đối số boolean cho biết rằng chúng ta sẽ fine-tune toàn bộ mô hình. Chúng ta đã bỏ qua điều này trong thử nghiệm trước.
- –scheduler và –scheduler-epochs: Cái trước là một đối số boolean cho biết script huấn luyện khởi tạo MultiStepLR scheduler và cái sau xác định số epoch sau đó áp dụng scheduling.
Chúng ta bắt đầu với learning rate cơ bản thấp hơn nhiều là 0.00001.
Chúng ta huấn luyện trong tổng số 65 epoch và áp dụng scheduler sau 45 epoch, điều này làm giảm learning rate theo hệ số 10.
Sau đây là đầu ra từ terminal.
=============================================================================================================================
Layer (type (var_name)) Input Shape Output Shape Param #
=============================================================================================================================
Dinov2Segmentation (Dinov2Segmentation) [1, 3, 644, 644] [1, 2, 46, 46] --
├─Sequential (model) -- -- --
│ └─DinoVisionTransformer (backbone) [1, 3, 644, 644] [1, 384, 46, 46] 526,848
│ │ └─PatchEmbed (patch_embed) [1, 3, 644, 644] [1, 2116, 384] 226,176
│ │ └─ModuleList (blocks) -- -- 21,302,784
│ │ └─LayerNorm (norm) [1, 2117, 384] [1, 2117, 384] 768
│ │ └─LayerNorm (norm) [1, 2117, 384] [1, 2117, 384] (recursive)
│ │ └─LayerNorm (norm) [1, 2117, 384] [1, 2117, 384] (recursive)
│ │ └─LayerNorm (norm) [1, 2117, 384] [1, 2117, 384] (recursive)
│ └─LinearClassifierToken (decode_head) [1, 1536, 46, 46] [1, 2, 46, 46] 3,074
│ │ └─Conv2d (conv) [1, 1536, 46, 46] [1, 2, 46, 46] 3,074
=============================================================================================================================
Total params: 22,062,724
Trainable params: 22,062,724
Non-trainable params: 0
Total mult-adds (Units.MEGABYTES): 506.39
=============================================================================================================================
Input size (MB): 4.98
Forward/backward pass size (MB): 1047.08
Params size (MB): 86.13
Estimated Total Size (MB): 1138.19
=============================================================================================================================
EPOCH: 1
Training
100%|████████████████████| 73/73 [00:12<00:00, 5.89it/s]
Validating
100%|████████████████████| 12/12 [00:01<00:00, 10.89it/s]
Best validation loss: 0.09553089396407206
Saving best model for epoch: 1
Best validation IoU: 0.8019417302315641
Saving best model for epoch: 1
Train Epoch Loss: 0.3374, Train Epoch PixAcc: 0.8561, Train Epoch mIOU: 0.628556
Valid Epoch Loss: 0.0955, Valid Epoch PixAcc: 0.8867 Valid Epoch mIOU: 0.801942
LR for next epoch: [1e-05]
--------------------------------------------------
EPOCH: 2
Training
100%|████████████████████| 73/73 [00:11<00:00, 6.12it/s]
Validating
100%|████████████████████| 12/12 [00:01<00:00, 11.20it/s]
Best validation loss: 0.0802614043156306
Saving best model for epoch: 2
Best validation IoU: 0.8219888134531727
Saving best model for epoch: 2
Train Epoch Loss: 0.2549, Train Epoch PixAcc: 0.8844, Train Epoch mIOU: 0.694859
Valid Epoch Loss: 0.0803, Valid Epoch PixAcc: 0.8928 Valid Epoch mIOU: 0.821989
LR for next epoch: [1e-05]
--------------------------------------------------
EPOCH: 3
Training
100%|████████████████████| 73/73 [00:11<00:00, 6.17it/s]
Validating
100%|████████████████████| 12/12 [00:01<00:00, 11.17it/s]
Best validation loss: 0.07315881767620643
Saving best model for epoch: 3
Best validation IoU: 0.8304570835899336
Saving best model for epoch: 3
Train Epoch Loss: 0.2036, Train Epoch PixAcc: 0.8996, Train Epoch mIOU: 0.710187
Valid Epoch Loss: 0.0732, Valid Epoch PixAcc: 0.8955 Valid Epoch mIOU: 0.830457
LR for next epoch: [1e-05]
--------------------------------------------------
EPOCH: 4
Training
100%|████████████████████| 73/73 [00:11<00:00, 6.18it/s]
Validating
100%|████████████████████| 12/12 [00:01<00:00, 11.30it/s]
Best validation loss: 0.07273002838095029
Saving best model for epoch: 4
Train Epoch Loss: 0.2310, Train Epoch PixAcc: 0.8953, Train Epoch mIOU: 0.718966
Valid Epoch Loss: 0.0727, Valid Epoch PixAcc: 0.8953 Valid Epoch mIOU: 0.830397
LR for next epoch: [1e-05]
--------------------------------------------------
.
.
.
EPOCH: 41
Training
100%|████████████████████| 73/73 [00:11<00:00, 6.16it/s]
Validating
100%|████████████████████| 12/12 [00:01<00:00, 11.26it/s]
Best validation loss: 0.05582220898941159
Saving best model for epoch: 41
Best validation IoU: 0.8613330583165073
Saving best model for epoch: 41
Train Epoch Loss: 0.1608, Train Epoch PixAcc: 0.9157, Train Epoch mIOU: 0.758984
Valid Epoch Loss: 0.0558, Valid Epoch PixAcc: 0.9056 Valid Epoch mIOU: 0.861333
LR for next epoch: [1e-05]
--------------------------------------------------
EPOCH: 42
Training
100%|████████████████████| 73/73 [00:11<00:00, 6.17it/s]
Validating
100%|████████████████████| 12/12 [00:01<00:00, 11.30it/s]
Train Epoch Loss: 0.1470, Train Epoch PixAcc: 0.9238, Train Epoch mIOU: 0.776518
Valid Epoch Loss: 0.0587, Valid Epoch PixAcc: 0.9054 Valid Epoch mIOU: 0.860913
LR for next epoch: [1e-05]
--------------------------------------------------
.
.
.
EPOCH: 65
Training
100%|████████████████████| 73/73 [00:12<00:00, 5.92it/s]
Validating
100%|████████████████████| 12/12 [00:01<00:00, 11.04it/s]
Train Epoch Loss: 0.1439, Train Epoch PixAcc: 0.9265, Train Epoch mIOU: 0.774243
Valid Epoch Loss: 0.0641, Valid Epoch PixAcc: 0.9048 Valid Epoch mIOU: 0.858523
LR for next epoch: [1.0000000000000002e-06]
--------------------------------------------------
TRAINING COMPLETE
content_copy download Use code with caution.
Mô hình đạt mean IoU cao nhất là 86.1% và validation loss thấp nhất là 0.0558 ở epoch 41.
![Đồ thị Loss sau fine