Mạng nơ-ron phân đoạn ngữ nghĩa (semantic segmentation neural networks)

Semantic Segmentation là một kỹ thuật trong thị giác máy tính nhằm phân loại từng pixel trong một hình ảnh thành một lớp cụ thể. Thay vì chỉ xác định các đối tượng trong hình ảnh (như nhận diện đối tượng), phân đoạn ngữ nghĩa cung cấp thông tin chính xác hơn bằng cách phân loại mỗi pixel của hình ảnh vào một lớp tương ứng, chẳng hạn như "xe", "người", "cây", "đường", v.v.
Ảnh 0‑16: Ví dụ về một hình ảnh cây ớt chuông (a) và kết quả của mạng nơ-phân đoạn ngữ nghĩa (b). Trong hình (b), màu xanh lá cây, màu hồng và màu tím đại diện cho lá cây, cuống lá và thân cây.
Cấu trúc thường thấy của một mạng nơ-ron phân đoạn ngữ nghĩa gồm các thành phần:
Encoder (Bộ mã hóa): Trích xuất các đặc trưng từ hình ảnh đầu vào.
Decoder (Bộ giải mã): Chuyển đổi các đặc trưng đã mã hóa thành một hình ảnh với độ phân giải đầy đủ, trong đó mỗi pixel được gán một nhãn.
Skip Connections: Kết nối trực tiếp các đặc trưng từ các tầng sâu của Encoder đến các tầng tương ứng của Decoder để bảo toàn thông tin chi tiết hơn.
Hình 4.10 cho thấy cấu trúc của mạng nơ-ron UNET, một mạng nơ-ron phân đoạn nghĩa nổi tiếng ra đời năm 2015. Mạng gồm 1 phần Encoder , Decoder và Skip connections. Trong phần Encoder, dữ liệu đầu vào là các ma trận dữ liệu biễu diễn hình ảnh, qua các phép toán tích chập sẽ tăng số lượng kênh (channels) và giảm kích thước của ma trận, hay độ phân giải của ảnh. Đến một độ sâu hợp lý, các dữ liệu này được phục hồi lại kích thước ban đầu. Kết quả của phần này sẽ là 1 ma trận hình ảnh có kích thước bằng kích thước đầu vào, nhưng mỗi giá trị trong ma trận chỉ ra vị trí pixel đó thuộc đối tượng dự đoán nào. Để giảm quá trình mất mát dữ liệu và lưu giữ các đặc trưng trích xuất tại mỗi tầng, Skip Connections giúp kết nối kết quả tại mỗi tầng trong Encoder và Decoder để cho ra kết quả tốt hơn.
Ảnh 0‑17: Cấu trúc của mạng nơ-ron phân đoạn ngữ nghĩa UNET
Python hiện là ngôn ngữ phổ lập trình phổ biến hiện xây dưng các mạng nơ-ron. Các thư viện nổi tiếng như Tensor Flow, PyTorch cung cấp nhiều công cụ hỗ trợ việc khai báo cũng như huấn luyện mạng nơ-ron. Để cài đặt PyTorch với cpu sử dụng câu lệnh sau:
pip3 install torch torchvision torchaudio
Nếu sử dụng GPU, tùy vào phiên bản CUDA thì sử dụng phiên bản phù hợp. Trong trường hợp sử dụng CUDA 12.4 thì sử dụng câu lệnh sau:
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
Có thể tham khảo thêm tại website: https://pytorch.org/ .
Trong ví dụ tiếp theo chúng ta sử dụng PyTorch xây dựng mạng nơ-ron ngữ nghĩa có 2 phần encoder và decoder, với số chanel tối đa là 32 và kích thước ảnh giảm xuống 8 lần. Cấu trúc mạng như sau:
Ảnh 0‑18: Cấu trúc mạng nơ-ron phân đoạn ngữ nghĩa 32 chanels tự định nghĩa
Trong mạng nơ-ron này, chúng ta chỉ dụng phép tích chập truyền thống. Sau phép toán tích chập, hàm normalize và hàm kích hoạt Relu. Dưới đây là lệnh xây dựng một tầng trong mạng nơ-ron với đầu vào là số lượng chanel đầu vào và đầu ra.
Dưới đây là định nghĩa đầy đủ của mạng nơ-ron.
Một số mạng nơ-ron phân đoạn ngữ nghĩa nổi tiếng: U-Net, SegNet, DeepLab. Ngoài ra một số mạng nơ-ron có thể chạy trên thời gian thực hoặc các thiết bị di động như MobileNet V2, MobileNet V3.
Huấn luyện mạng nơ-ron phân đoạn ngữ nghĩa
Quá trình rèn luyện mạng nơ-ron phân đoạn ngữ nghĩa (semantic segmentation) là một quá trình phức tạp bao gồm nhiều bước, từ chuẩn bị dữ liệu, lựa chọn mô hình, thiết lập hàm mất mát, tối ưu hóa, đến đánh giá và tinh chỉnh. Phân đoạn ngữ nghĩa là một nhiệm vụ quan trọng trong thị giác máy tính, trong đó mục tiêu là phân loại từng pixel của ảnh thành các lớp khác nhau.
Chuẩn bị dữ liệu
Chúng ta cần thu thập ảnh để thực hiện huấn luyện, cũng như dán nhãn ảnh huấn luyện. Ảnh gốc sẽ là đầu vào của việc huấn luyện, và ảnh mask (là kết quả của việc dán nhãn) sẽ là output của việc huấn luyện. Mask thường là ảnh có một kênh, trong đó giá trị tại mỗi pixel đại diện cho lớp mà pixel đó thuộc về.
Ảnh 0‑19: (a) là hình ảnh mask đã được tô màu để nhận diện. (b) là giá trí của ảnh mask với giá trị pixel là các đối tượng dự đoán
Có nhiều công cụ để thực hiện dán nhãn hiện nay. Trong ví dụ của bài giảng, chúng ta dùng roboflow.com để thực hiện việc dán nhãn.
Ảnh 0‑20: Sử dụng robotflow.com để dán nhãn
Sau khi dán nhãn, dữ liệu được điều chỉnh về kích thước 256x256 pixel và áp dụng các phương thức tăng cường để tăng số lượng của ảnh. Một số biện pháp tăng cường phổ biến như chuyển xám, xoay, làm mờ, làm sắc nét, thêm nhiễu … Việc áp dụng các biện pháp tăng cường này mang lại hiệu quả cao trong quá trình rèn luyện mô hình.
Ảnh 0‑21: Ví dụ về áp dụng một số biện pháp tăng cường tạo ra hình ảnh mới trong bộ dữ liệu
Dữ liệu sau khi trích xuất từ robotflow và tải lên google drive có hình thức như hình dưới đây. Các ảnh mask có tên giống tên ảnh màu thêm phần mask phía sau. Ảnh mask là ảnh có phần mở rộng .png trong khi đó ảnh màu có phần mở rộng là jpg. Từ đặc tính này ta có thể xây dựng hàm đọc dữ liệu ảnh đầu vào và ảnh kết quả cho quá trình huấn luyện.
Ảnh 0‑22: Cấu trúc của thư mục ảnh tải về từ robotflow.com
Trong quá trình huấn luyện ở PyTorch, ta cần định nghĩa một lớp giúp chung ta đọc dữ liệu, và cung cấp dữ liệu cho mỗi vòng lặp huấn luyện và quá trình đánh giá.
Ta phải chuyển ảnh gốc sang dạng tensor để thực hiện huấn luyện, và để nhanh chóng hội tụ, ta cũng chuyển các giá trị màu từ 0 đến 255 sang giá trị từ 0 tới 1 bằng cách sử dụng normalize. Dưới đây là 1 ví dụ xây dựng transformer cho ảnh gốc.
Vòng lặp huấn luyện
Trong huấn luyện mạng nơ-ron là quá trình lặp đi lặp lại các bước huấn luyện nhằm tối ưu hóa mô hình dựa trên dữ liệu đầu vào và nhãn (labels). Training loop thường gồm ba bước chính: forward pass (lan truyền xuôi), backward pass (lan truyền ngược), và cập nhật trọng số.
Forward Pass (Lan truyền xuôi): Mô hình nhận dữ liệu đầu vào, thực hiện các phép tính để tạo ra đầu ra dự đoán (predictions). Dự đoán này sau đó sẽ được so sánh với giá trị thực tế (labels) để tính toán hàm mất mát (loss).
Loss Calculation (Tính toán hàm mất mát): Hàm mất mát đo lường sự khác biệt giữa dự đoán của mô hình và nhãn thực tế. Một số hàm mất mát phổ biến là CrossEntropyLoss (cho phân loại) và MSELoss (cho hồi quy).
Backward Pass (Lan truyền ngược): Từ hàm mất mát, quá trình lan truyền ngược sẽ tính toán gradient của hàm mất mát đối với các trọng số của mô hình thông qua phương pháp backpropagation. Gradients là những thay đổi mà chúng ta cần thực hiện trên trọng số để giảm giá trị hàm mất mát.
Update Weights (Cập nhật trọng số): Sử dụng optimizer (ví dụ: Adam, SGD), các trọng số của mô hình sẽ được cập nhật dựa trên giá trị gradient vừa tính được trong backward pass. Optimizer sẽ điều chỉnh các trọng số theo hướng giảm dần giá trị của hàm mất mát.
Các yếu tố khác trong Training Loop:
Learning Rate Scheduler: Đôi khi, chúng ta cần điều chỉnh learning rate trong quá trình huấn luyện. Điều này có thể được thực hiện bằng cách sử dụng lr_scheduler từ PyTorch, để giảm dần learning rate khi hàm mất mát không còn giảm nhiều sau một số epochs.
Early Stopping: Một kỹ thuật để dừng quá trình huấn luyện khi mô hình đạt được hiệu suất tốt nhất trên tập validation, giúp tránh overfitting.
Checkpoint: Lưu lại trạng thái của mô hình sau một số epochs để đảm bảo rằng bạn không mất tất cả quá trình huấn luyện nếu có sự cố xảy ra.
Dưới đây là code của hàm huấn luyện:
Với thiết lập 30 epoch, chúng ta có kết quả quá trình huấn luyện như sau:
Ảnh 0‑23: Kết quả của quá trình huấn luyện
Dự Đoán
Sau khi huấn luyện, bộ trọng số của mô hình sẽ được lưu lại. Quá trình dự đoán được thực hiện qua 3 bước:
Chuẩn bị hình ảnh: Hình ảnh được đọc lên và qua bước tiền xử lý transformer. Chú ý cần sử dụng transformer giống trong quá trình huấn luyện.
Chuẩn bị mô hình mạng nơ-ron: Tạo một mô hình từ mạng nơ-ron đã sử dụng trong quá trình huấn luyện, đọc trọng số và đưa vào mô hình. Lúc này mô hình được chuyển đổi sang chế đố dự đoán.
Tiến hành dự đoán: Sử dụng mô hình để lấy kết quả dự đoán là một ma trận hình ảnh mask, mà các giá trí là số thứ tự của các lớp dự đoán. Tô màu cho các lớp này và hiển thị dưới dạng ảnh màu
Dưới đây là code dự đoán:
Kết quả của dự đoán:
Ảnh 0‑24: kết quả dự đoán của mô hình mạng nơ-ron phân đoạn ngữ nghĩa
Mạng nơ-ron được định nghĩa ở trên có cấu trúc đơn giản nên kết quả còn nhiều hạn chế. Nếu thêm số lượng đối tượng cần dự đoán, hoặc các ảnh phức tạp hơn thì kết quả sẽ không đạt yêu cầu. PyTorch cung cấp cho người dùng một số mạng nơ-ron phân đoạn ngữ nghĩa phổ dụng như DeepLap. Để khai báo một mô hình thuộc mạng nơ-ron DeepLap ta dùng lệnh sau:

Bình luận