Step-by-Step: Vision Transformer

Tác giả: Yen-Linh Vu (AIO2024), Dinh-Thang Duong (TA), Phuc-Thinh Nguyen (AIO2024, CM), Quang-Vinh Dinh (Lecturer)

Keywords: vision transformer, ViT, học deep learning online

Dẫn nhập

Recurrent Neural Networks (RNNs) là một kiểu mạng deep learning được thiết kế đặc biệt để xử lý và học từ dữ liệu tuần tự (sequential), ví dụ như văn bản (text), chuỗi thời gian (time-series), hay âm thanh (audio). Các mạng RNN nổi bật với khả năng lưu giữ thông tin từ các bước trước đó trong chuỗi, giúp chúng đặc biệt hữu ích trong các bài toán như phân tích ngôn ngữ tự nhiên và dự đoán chuỗi thời gian. Tuy nhiên, một hạn chế lớn của RNN là việc xử lý tuần tự: mô hình phải xử lý từng bước trong chuỗi theo thứ tự, dẫn đến thời gian huấn luyện chậm và khó khăn khi phải nắm bắt các mối quan hệ xa trong chuỗi dài.

Kiến trúc tổng quan của ViT. Nguồn: Link. Hình 1: Kiến trúc tổng quan của ViT. Nguồn: Link.

Để khắc phục các hạn chế của RNN, Transformer đã được giới thiệu vào năm 2017, mang lại một bước tiến đột phá trong xử lý dữ liệu tuần tự. Điểm nổi bật của Transformer là cơ chế "self-attention", cho phép mô hình tập trung vào toàn bộ chuỗi dữ liệu đồng thời, thay vì xử lý tuần tự như RNN. Với self-attention, Transformer có thể tính toán mối liên hệ giữa các phần trong chuỗi một cách trực tiếp và song song, từ đó cải thiện hiệu suất và khả năng học các mối quan hệ dài hạn.

Kiến trúc mạng tổng quan của Transformer. Nguồn: Link. Hình 2: Kiến trúc mạng tổng quan của Transformer. Nguồn: Link.

Transformer hoạt động dựa trên kiến trúc encoder-decoder, trong đó:

  • Encoder (bên trái Hình 2): Nhận dữ liệu đầu vào, biểu diễn nó dưới dạng vector embedding, và áp dụng self-attention để tìm mối liên hệ giữa các phần tử trong chuỗi dữ liệu.

  • Decoder (bên phải Hình 2): Sử dụng kết quả từ encoder, kết hợp với cơ chế attention để tạo ra đầu ra, chẳng hạn như câu dịch hoặc văn bản tóm tắt.

Cơ chế self-attention là trung tâm của Transformer. Thay vì chỉ tập trung vào phần dữ liệu ngay trước hoặc sau phần tử hiện tại (như trong RNN), self-attention cho phép mô hình "nhìn" toàn bộ chuỗi và quyết định mức độ quan trọng của từng phần tử trong việc dự đoán kết quả. Điều này giúp Transformer dễ dàng học được mối quan hệ giữa các phần tử cách xa nhau trong chuỗi.

Một ưu điểm lớn khác của Transformer là khả năng xử lý song song, nhờ không phụ thuộc vào tính tuần tự như RNN. Điều này giúp giảm đáng kể thời gian huấn luyện khi làm việc với dữ liệu lớn. Chính nhờ những ưu điểm này, Transformer đã nhanh chóng trở thành tiêu chuẩn trong các bài toán xử lý ngôn ngữ tự nhiên, như dịch máy, tóm tắt văn bản, và trả lời câu hỏi. Tuy vậy, mặc dù Transformer là một kiến trúc cực kỳ mạnh mẽ và tiềm năng, song thời điểm nghiên cứu ban đầu chỉ thực hiện trên dữ liệu văn bản. Điều này đã thôi thúc các nhà nghiên cứu tìm cách áp dụng Transformer cho các kiểu dữ liệu khác, đặc biệt là dữ liệu hình ảnh. Trong số các công trình đã được thực hiện, Vision Transformer (ViT) là một điểm nổi bật.

Ý tưởng cốt lõi của ViT là chuyển đổi hình ảnh thành một chuỗi các vùng ảnh nhỏ, gọi là "patch", tương tự như cách một câu được chia thành các từ trong ngôn ngữ. Sau khi chia hình ảnh thành các patch, mỗi patch được chuyển đổi tuyến tính (linear projection) thành một vector biểu diễn (embedding), tương tự như cách các token embedding được sử dụng trong Transformer gốc. Các vector này sau đó được kết hợp với thông tin vị trí (positional encoding) để tạo thành một chuỗi các embedding, đóng vai trò là đầu vào cho Transformer.

Khi đã có chuỗi các vector embedding này, ViT áp dụng gần như tương tự các bước tính toán như trong encoder của Transformer. Cụ thể, ViT sử dụng cơ chế self-attention để tính toán mối liên hệ giữa các patch trong toàn bộ bức ảnh, cho phép mô hình hiểu được các đặc trưng không gian và mối quan hệ giữa các vùng khác nhau trong hình ảnh. Quá trình này giúp ViT tận dụng sức mạnh tính toán song song và khả năng học các mối quan hệ dài hạn của Transformer, đồng thời thích ứng hoàn hảo với dữ liệu hình ảnh. Với cách tiếp cận này, ViT không chỉ kế thừa sức mạnh từ Transformer mà còn mở ra một hướng đi mới trong xử lý hình ảnh, nơi dữ liệu hình ảnh được biểu diễn và phân tích theo cách giống như dữ liệu ngôn ngữ. Đây chính là bước tiến quan trọng, đặt nền móng cho việc ứng dụng Transformer vào các lĩnh vực thị giác máy tính.

Kỹ thuật patching hướng đến việc chia ảnh thành các Hình 3: Kỹ thuật patching hướng đến việc chia ảnh thành các "patch", là các vùng ảnh có kích thước bằng nhau.

Để hiểu rõ cách hoạt động của ViT, chúng ta sẽ tìm hiểu từng bước xử lý mà ViT cần thực hiện trong một lần forward dữ liệu đầu vào để lấy kết quả dự đoán. Theo đó, với pipeline xử lý tổng quát của ViT, như được minh họa trong (Hình 1), chúng ta sẽ khám phá cách xử lý dữ liệu cho một ảnh và một batch ảnh.

Trong bước đầu tiên của pipeline Vision Transformer (ViT), chúng ta cần định nghĩa rõ cấu trúc của ảnh đầu vào và cách chia ảnh thành các patch nhỏ. Một ảnh đơn sẽ được biểu diễn dưới dạng tensor với kích thước H×W×CH \times W \times C, trong đó H,W,CH, W, C lần lượt là chiều cao, chiều rộng và số kênh (channel).

Đối với batch ảnh, tensor sẽ có kích thước B×H×W×CB \times H \times W \times C, với BB là số lượng ảnh trong batch. Kích thước patch được quy định là P×PP \times P, và tổng số lượng patch NN trên mỗi ảnh được tính theo công thức:

N=HWP2.N = \frac{H \cdot W}{P^2}.

Như vậy, bước đầu tiên sẽ nhận đầu vào (input) là một ảnh hoặc một batch ảnh. Với đầu vào là một ảnh đơn, ảnh được biểu diễn dưới dạng tensor IRH×W×C\mathbf{I} \in \mathbb{R}^{H \times W \times C}, trong đó HH, WW, và CC lần lượt là chiều cao, chiều rộng và số kênh (channel) của ảnh. Đối với batch ảnh, đầu vào được biểu diễn dưới dạng tensor IbatchRB×H×W×C\mathbf{I}_{\text{batch}} \in \mathbb{R}^{B \times H \times W \times C}, với BB là số lượng ảnh trong batch.

Kết quả đầu ra (output) của bước này là ảnh hoặc batch ảnh đã được xử lý, chia thành các patch nhỏ ở bước tiếp theo.

Bước 2 tiếp tục với việc chia tensor đầu vào I\mathbf{I} thành NN patch nhỏ. Mỗi patch có kích thước P×P×CP \times P \times C, và sau đó được làm phẳng (flatten) để chuyển thành một vector với chiều dài P2CP^2C. Quá trình này giúp tổ chức lại thông tin từ ảnh gốc dưới dạng các vector nhỏ hơn, chuẩn bị cho các bước xử lý tiếp theo. Đầu ra cho một ảnh được biểu diễn như sau:

XpatchRN×(P2C).\mathbf{X}_{\text{patch}} \in \mathbb{R}^{N \times (P^2C)}.

Đối với batch ảnh Ibatch\mathbf{I}_{\text{batch}}, quá trình này được áp dụng cho từng ảnh trong batch. Sau khi chia, batch ảnh được sắp xếp lại thành một tensor với kích thước:

Xpatch_batchRB×N×(P2C),\mathbf{X}_{\text{patch\_batch}} \in \mathbb{R}^{B \times N \times (P^2C)},

Bước 3 liên quan đến quá trình Patch Embedding, trong đó các patch được ánh xạ từ không gian RP2C\mathbb{R}^{P^2C} sang không gian RD\mathbb{R}^{D} bằng cách sử dụng một tầng tuyến tính (Linear Layer). Quá trình này được thực hiện thông qua công thức chính, với WER(P2C)×DW_E \in \mathbb{R}^{(P^2C) \times D} là trọng số và bERDb_E \in \mathbb{R}^{D} là bias của tầng embedding:

E=XpatchWE+bE,\mathbf{E} = \mathbf{X}_{\text{patch}} \cdot W_E + b_E,

Đối với batch ảnh, công thức trên được áp dụng cho toàn bộ batch, cụ thể:

Ebatch=Xpatch_batchWE+bE.\mathbf{E}_{\text{batch}} = \mathbf{X}_{\text{patch\_batch}} \cdot W_E + b_E.

Đầu vào của bước này bao gồm tensor XpatchRN×(P2C)\mathbf{X}_{\text{patch}} \in \mathbb{R}^{N \times (P^2C)} đối với một ảnh và tensor Xpatch_batchRB×N×(P2C)\mathbf{X}_{\text{patch\_batch}} \in \mathbb{R}^{B \times N \times (P^2C)} đối với batch ảnh. Kết quả đầu ra là tensor ERN×D\mathbf{E} \in \mathbb{R}^{N \times D} cho một ảnh và tensor EbatchRB×N×D\mathbf{E}_{\text{batch}} \in \mathbb{R}^{B \times N \times D} cho batch ảnh. Quá trình này đảm bảo rằng các patch đã được ánh xạ sang không gian mới để phù hợp với các bước tiếp theo trong pipeline Vision Transformer.

Biểu diễn Positional Encoding trên không gian vị trí và chiều sâu. Nguồn: Link. Hình 4: Biểu diễn Positional Encoding trên không gian vị trí và chiều sâu. Nguồn: Link.

Bước 4 tiếp tục bằng việc thêm thông tin về vị trí vào từng patch. Điều này được thực hiện bằng cách cộng thêm một vector mã hóa vị trí EposE_{\text{pos}} vào tensor đầu vào E\mathbf{E}. Quá trình này được biểu diễn qua công thức:

Z0=E+Epos,\mathbf{Z}_0 = \mathbf{E} + E_{\text{pos}},

trong đó ERN×D\mathbf{E} \in \mathbb{R}^{N \times D} là tensor đại diện cho các patch sau bước embedding, và EposRN×DE_{\text{pos}} \in \mathbb{R}^{N \times D} là vector mã hóa vị trí có cùng kích thước.

Đối với batch ảnh, cách làm tương tự được áp dụng trên toàn bộ batch. Công thức tổng quát cho batch ảnh được viết như sau:

Z0_batch=Ebatch+Epos,\mathbf{Z}_{0\_\text{batch}} = \mathbf{E}_{\text{batch}} + E_{\text{pos}},

với EbatchRB×N×D\mathbf{E}_{\text{batch}} \in \mathbb{R}^{B \times N \times D} là tensor đại diện cho các patch trong batch và EposRN×DE_{\text{pos}} \in \mathbb{R}^{N \times D} là vector mã hóa vị trí được áp dụng cho từng ảnh trong batch.

Bước 5 xử lý qua Transformer Encoder, bắt đầu bằng việc áp dụng Layer Normalization (LayerNorm) lên đầu vào. Với dữ liệu đầu vào Z0\mathbf{Z}_0 cho một ảnh và Z0_batch\mathbf{Z}_{0\_\text{batch}} cho batch ảnh, kết quả sau LayerNorm được tính như sau:

Z0=LN(Z0),Z0_batch=LN(Z0_batch).\mathbf{Z'}_0 = \text{LN}(\mathbf{Z}_0), \quad \mathbf{Z'}_{0\_\text{batch}} = \text{LN}(\mathbf{Z}_{0\_\text{batch}}).

Sau bước LayerNorm, Multi-Head Self-Attention (MSA) được thực hiện. Quá trình này bắt đầu bằng việc tính toán các tensor Query (QQ), Key (KK), và Value (VV) cho từng head. Cụ thể, với một ảnh, chúng được tính như sau:

Q=Z0WQ,K=Z0WK,V=Z0WV,\mathbf{Q} = \mathbf{Z'}_0 \cdot W_Q, \quad \mathbf{K} = \mathbf{Z'}_0 \cdot W_K, \quad \mathbf{V} = \mathbf{Z'}_0 \cdot W_V,

và với batch ảnh:

Qbatch=Z0_batchWQ,Kbatch=Z0_batchWK,Vbatch=Z0_batchWV.\mathbf{Q}_{\text{batch}} = \mathbf{Z'}_{0\_\text{batch}} \cdot W_Q, \quad \mathbf{K}_{\text{batch}} = \mathbf{Z'}_{0\_\text{batch}} \cdot W_K, \quad \mathbf{V}_{\text{batch}} = \mathbf{Z'}_{0\_\text{batch}} \cdot W_V.

Tiếp theo, Attention được tính dựa trên công thức:

Attention(Q,K,V)=Softmax(QKD)V,\text{Attention}(\mathbf{Q}, \mathbf{K}, \mathbf{V}) = \text{Softmax}\left(\frac{\mathbf{Q} \mathbf{K}^\top}{\sqrt{D}}\right) \mathbf{V},

trong đó DD là kích thước của vector Key.

Sau khi tính Attention, đầu ra của MSA được kết hợp với đầu vào ban đầu qua Residual Connection và LayerNorm lần nữa. Kết quả được tính như sau:

Z1=Z0+MSA_Output,Z1_batch=Z0_batch+MSA_Output.\mathbf{Z}_1 = \mathbf{Z}_0 + \text{MSA\_Output}, \quad \mathbf{Z}_{1\_\text{batch}} = \mathbf{Z}_{0\_\text{batch}} + \text{MSA\_Output}.

Tiếp đó, LayerNorm được áp dụng:

Z1=LN(Z1),Z1_batch=LN(Z1_batch).\mathbf{Z'}_1 = \text{LN}(\mathbf{Z}_1), \quad \mathbf{Z'}_{1\_\text{batch}} = \text{LN}(\mathbf{Z}_{1\_\text{batch}}).
Minh họa về Layer Normalization. Nguồn: Link Hình 5: Minh họa về Layer Normalization. Nguồn: Link.

Cuối cùng, cho từng patch vector sau Multi-Head Self-Attention (MSA) đã được norm vào Multi-layer Perceptron (MLP). MLP trong cài đặt ở bài này sẽ bao gồm hai tầng tuyến tính (Linear Layers) được kết nối với nhau bởi hàm kích hoạt GELU. Kết quả sau khi qua MLP được cộng thêm residual từ đầu vào để tạo ra đầu ra cuối cùng. Công thức tổng quát cho một ảnh được viết như sau:

H=GELU(Z1W1+b1),\mathbf{H} = \text{GELU}(\mathbf{Z'}_1 \cdot W_1 + b_1), Z2=HW2+b2+Z1.\mathbf{Z}_2 = \mathbf{H} \cdot W_2 + b_2 + \mathbf{Z}_1.

Đối với batch ảnh, quá trình này được thực hiện tương tự với công thức tổng quát là:

Hbatch=GELU(Z1_batchW1+b1),\mathbf{H}_{\text{batch}} = \text{GELU}(\mathbf{Z'}_{1\_\text{batch}} \cdot W_1 + b_1), Z2_batch=HbatchW2+b2+Z1_batch.\mathbf{Z}_{2\_\text{batch}} = \mathbf{H}_{\text{batch}} \cdot W_2 + b_2 + \mathbf{Z}_{1\_\text{batch}}.

Trong các công thức trên:

  • Z1\mathbf{Z'}_1 là đầu ra đã chuẩn hóa từ bước MSA. Z1_batchRB×N×D\mathbf{Z'}_{1\_\text{batch}} \in \mathbb{R}^{B \times N \times D} cho batch ảnh

  • W1W_1W2W_2 là ma trận trọng số của hai tầng tuyến tính.

  • b1b_1b2b_2 là bias của hai tầng tuyến tính.

  • GELU là hàm kích hoạt Gaussian Error Linear Unit.

Kết quả đầu ra lần lượt là tensor Z2RN×D\mathbf{Z}_2 \in \mathbb{R}^{N \times D} cho một ảnh và Z2_batchRB×N×D\mathbf{Z}_{2\_\text{batch}} \in \mathbb{R}^{B \times N \times D} cho batch ảnh. Quá trình này đảm bảo rằng mỗi patch vector được xử lý qua một mạng tuyến tính để tăng cường thông tin trước khi tiếp tục đến bước tiếp theo trong pipeline.

Về lý thuyết, Transformer Encoder với LayerNorm, Self-Attention, Residual Connection và MLP sẽ giúp đảm bảo thông tin trong các patch được xử lý hiệu quả, giữ lại các mối quan hệ quan trọng trong dữ liệu đầu vào. Ở cài đặt thực tế, ta có thể cài đặt sử dụng nhiều Encoder Block một cách tuần tự. Song trong bài này, ta sẽ chỉ quan tâm một Encoder Block.

Bước 6 tập trung vào việc trích xuất token đặc biệt [CLS] từ chuỗi các patch vector đã được xử lý trước đó. Token đặc biệt [CLS] được định nghĩa là hàng đầu tiên của ma trận đầu ra Z2Z_2. Đây là vector duy nhất đại diện cho toàn bộ thông tin từ các patch của hình ảnh và thường được sử dụng làm đầu vào cho các nhiệm vụ phân loại hoặc các bước xử lý tiếp theo trong pipeline. Công thức trích xuất như sau:

ZCLS=row1(Z2),\mathbf{Z}_{\text{CLS}} = \text{row}_1(\mathbf{Z}_2),

trong đó:

  • Z2RN×D\mathbf{Z}_2 \in \mathbb{R}^{N \times D} là ma trận đầu ra sau khi đi qua Multi-Layer Perceptron (MLP).

  • ZCLSRD\mathbf{Z}_{\text{CLS}} \in \mathbb{R}^{D} là vector đại diện duy nhất của token [CLS].

  • row1(Z2)\text{row}_1(\mathbf{Z}_2) biểu diễn hàng đầu tiên của ma trận Z2\mathbf{Z}_2.

Đối với batch ảnh, quy trình này được áp dụng cho toàn bộ các ảnh trong batch, token [CLS] được lấy từ hàng đầu tiên của mỗi tensor trong batch Z2,batch\mathbf{Z}_{2, \text{batch}}. Công thức được biểu diễn như sau:

ZCLS, batch=slice(Z2,batch,axis=1,index=1),\mathbf{Z}_{\text{CLS, batch}} = \text{slice}(\mathbf{Z}_{2, \text{batch}}, \text{axis}=1, \text{index}=1),

trong đó:

  • Z2,batchRB×N×D\mathbf{Z}_{2, \text{batch}} \in \mathbb{R}^{B \times N \times D} là tensor đầu ra của batch ảnh, với BB là số lượng ảnh trong batch.

  • ZCLS, batchRB×D\mathbf{Z}_{\text{CLS, batch}} \in \mathbb{R}^{B \times D} là ma trận chứa token [CLS] của từng ảnh trong batch.

  • Hàm slice trích xuất hàng đầu tiên của mỗi tensor trong batch.

Kết quả của bước này là token [CLS] dưới dạng tensor ZCLSRD\mathbf{Z}_{\text{CLS}} \in \mathbb{R}^{D} đối với một ảnh và ZCLS, batchRB×D\mathbf{Z}_{\text{CLS, batch}} \in \mathbb{R}^{B \times D} đối với batch ảnh. Những token này được thiết kế để nắm giữ thông tin tổng quát nhất của ảnh hoặc batch ảnh, chuẩn bị cho các nhiệm vụ phân loại hoặc các bước xử lý tiếp theo trong pipeline.

So sánh giữa việc sử dụng kỹ thuật average pooling với token [CLS] (màu vàng). Hình 6: So sánh giữa việc sử dụng kỹ thuật average pooling với token [CLS] (màu vàng).

Bước cuối cùng của pipeline là Classification Head, trong đó một MLP (Multi-Layer Perceptron) được sử dụng để ánh xạ token [CLS] thành các lớp phân loại. MLP bao gồm một hoặc nhiều tầng tuyến tính, cùng với hàm kích hoạt GELU, và kết thúc bằng việc áp dụng hàm Softmax để tính xác suất cho từng lớp.

Đầu tiên, token [CLS] được đưa vào tầng ẩn (Hidden Layer), với quá trình tính toán được biểu diễn như sau:

Hhidden=GELU(ZCLSWhidden+bhidden),\mathbf{H}_{\text{hidden}} = \text{GELU}(\mathbf{Z}_{\text{CLS}} \cdot W_{\text{hidden}} + b_{\text{hidden}}),

với ZCLSRD\mathbf{Z}_{\text{CLS}} \in \mathbb{R}^{D} là token đầu vào, WhiddenW_{\text{hidden}}bhiddenb_{\text{hidden}} lần lượt là trọng số và bias của tầng ẩn. Đối với batch ảnh, công thức tương ứng là:

Hhidden_batch=GELU(ZCLS_batchWhidden+bhidden).\mathbf{H}_{\text{hidden\_batch}} = \text{GELU}(\mathbf{Z}_{\text{CLS\_batch}} \cdot W_{\text{hidden}} + b_{\text{hidden}}).

Tiếp theo, đầu ra từ tầng ẩn được đưa vào tầng đầu ra (Output Layer) để tính các logits:

Logits=HhiddenWout+bout\text{Logits} = \mathbf{H}_{\text{hidden}} \cdot W_{\text{out}} + b_{\text{out}}, Logitsbatch=Hhidden_batchWout+bout\text{Logits}_{\text{batch}} = \mathbf{H}_{\text{hidden\_batch}} \cdot W_{\text{out}} + b_{\text{out}},

với WoutW_{\text{out}}boutb_{\text{out}} là trọng số và bias của tầng đầu ra.

Cuối cùng, hàm Softmax được áp dụng lên các logits để chuyển đổi chúng thành xác suất cho từng lớp. Công thức tính xác suất được viết như sau:

Probabilities=Softmax(Logits),\text{Probabilities} = \text{Softmax}(\text{Logits}), Probabilitiesbatch=Softmax(Logitsbatch).\text{Probabilities}_{\text{batch}} = \text{Softmax}(\text{Logits}_{\text{batch}}).

Đầu ra cuối cùng của pipeline là các xác suất ProbabilitiesRC\text{Probabilities} \in \mathbb{R}^{C} cho một ảnh và ProbabilitiesbatchRB×C\text{Probabilities}_{\text{batch}} \in \mathbb{R}^{B \times C} cho batch ảnh, trong đó CC là số lớp phân loại. Kết quả này đại diện cho dự đoán của mô hình, hoàn thiện quá trình xử lý từ đầu vào đến đầu ra của Vision Transformer.


Thực hành

Dựa theo các công thức tổng quan đã đề cập phía trên trong quá trình forward của Vision Transformer (ViT), chúng ta sẽ thực hành chạy tay các bước trên sử dụng một ma trận nhỏ và đơn giản làm ảnh đầu vào ví dụ. Theo đó, ta sẽ định nghĩa một bức ảnh đầu vào dạng grayscale kích thước 4×44 \times 4. Để áp dụng kiến trúc ViT, chúng ta cần phải đi qua một quá trình bao gồm 8 bước chính như trên pipeline, bao gồm: từ việc chuẩn bị dữ liệu đầu vào đến đầu ra cuối cùng qua đầu mạng (classification head). Sau đây, ta sẽ cùng đi qua tính toán cụ thể từng bước:

Minh họa quá trình chuyển đổi từ ảnh đầu vào thành các vector embedding trong Vision Transformer. Hình 7: Minh họa quá trình chuyển đổi từ ảnh đầu vào thành các vector embedding trong Vision Transformer.

Định nghĩa ảnh đầu vào và kích thước patch

Giả sử bức ảnh đầu vào là một ma trận I\mathbf{I} có kích thước 4×44 \times 4, IRH×W×C\mathbf{I} \in \mathbb{R}^{H \times W \times C}, với HH, WW, và CC lần lượt là chiều cao, chiều rộng, và số kênh của ảnh.

I=[12345678910111213141516]\bm{I} = \begin{bmatrix} 1 & 2 & 3 & 4 \\ 5 & 6 & 7 & 8 \\ 9 & 10 & 11 & 12 \\ 13 & 14 & 15 & 16 \end{bmatrix}

Chia ảnh thành các patch

Để xử lý ảnh đầu vào trong ViT, chúng ta cần chia ảnh thành các patch nhỏ hơn. Mỗi patch sẽ đóng vai trò là một token cho các bước xử lý tiếp theo. Kích thước mỗi patch có dạng P×PP \times P. Chọn kích thước P=2P=2. Khi đó, số lượng patch sẽ được tính như sau:

N=H×WP2=4×42×2=4N = \frac{H \times W}{P^2} = \frac{4 \times 4}{2 \times 2} = 4

Như vậy, ảnh đầu vào được chuyển đổi thành một chuỗi gồm 4 patch, mỗi patch được biểu diễn dưới dạng một vector trong không gian features. Cụ thể ta có patch 1 là [1, 2, 5, 6], patch 2 là [3, 4, 7, 8], patch 3 là [9, 10, 13, 14], patch 4 là [11, 12, 15, 16].

Sau khi reshape và làm phẳng từng patch, ma trận đầu ra XpatchRN×(P2C)\mathbf{X}_{\text{patch}} \in \mathbb{R}^{N \times (P^2 \cdot C)} chứa tất cả các patch có dạng là:

Xpatch=[12563478910131411121516],XpatchR4×4.\bm{X_{\text{patch}}} = \begin{bmatrix} 1 & 2 & 5 & 6 \\ 3 & 4 & 7 & 8 \\ 9 & 10 & 13 & 14 \\ 11 & 12 & 15 & 16 \end{bmatrix}, \quad \bm{X_{\text{patch}}} \in \mathbb{R}^{4 \times 4}.

Patch Embedding

Để chuyển đổi các patch thành vector embedding, ta sử dụng ma trận embedding weight WEW_E và bias bEb_E:

WE=[0.10.20.30.40.50.60.70.80.91.01.11.2],bE=[0.1,0.2,0.3].\bm{W_E} = \begin{bmatrix} 0.1 & 0.2 & 0.3 \\ 0.4 & 0.5 & 0.6 \\ 0.7 & 0.8 & 0.9 \\ 1.0 & 1.1 & 1.2 \end{bmatrix}, \quad b_E = [0.1, 0.2, 0.3].

Tính được vector embedding:

E=XpatchWE+bE=[10.512.013.514.917.219.528.132.837.532.538.043.5],ER4×3.\bm{E} = \bm{X_{\text{patch}}} \cdot \bm{W_E} + b_E = \begin{bmatrix} 10.5 & 12.0 & 13.5 \\ 14.9 & 17.2 & 19.5 \\ 28.1 & 32.8 & 37.5 \\ 32.5 & 38.0 & 43.5 \end{bmatrix},\quad \bm{E} \in \mathbb{R}^{4 \times 3}.

Thêm Positional Encoding

Để giữ thông tin vị trí của các patch, sử dụng ma trận Positional Encoding EposR4×3\mathbf{E}_{\text{pos}} \in \mathbb{R}^{4 \times 3} đã được định nghĩa trước:

Epos=[0.10.20.30.40.50.60.70.80.91.01.11.2].\bm{E_{\text{pos}}} = \begin{bmatrix} 0.1 & 0.2 & 0.3 \\ 0.4 & 0.5 & 0.6 \\ 0.7 & 0.8 & 0.9 \\ 1.0 & 1.1 & 1.2 \end{bmatrix}. Z0=ZE+Epos=[10.612.213.815.317.720.128.833.638.433.539.144.7],Z0R4×3.\bm{Z_0} = \bm{Z_E} + \bm{E_{\text{pos}}} = \begin{bmatrix} 10.6 & 12.2 & 13.8 \\ 15.3 & 17.7 & 20.1 \\ 28.8 & 33.6 & 38.4 \\ 33.5 & 39.1 & 44.7 \end{bmatrix}, \quad \bm{Z_0} \in \mathbb{R}^{4 \times 3}.

Ma trận Z0Z_0 đại diện cho embedding của các patch, sau khi đã được bổ sung thông tin về vị trí của từng patch. Ma trận này sẽ được sử dụng làm đầu vào cho bước tính toán Self-Attention.

Ảnh minh họa về phép Positional Encoding. Hình 8: Ảnh minh họa về phép Positional Encoding.

Transformer Encoder

Bước này thực hiện các phép tính trong một khối Transformer Encoder, gồm ba phần chính. Đầu tiên là Layer Normalization trước Multi-Head Self-Attention (MSA), bao gồm tính toán Query, Key, Value, Attention Scores, và Output. Tiếp theo ta sử dụng Residual ConnectionLayer Normalization sau Attention và cuối cùng là thành phần Multi-layer Perceptron (MLP) để đưa ra dự đoán cuối cùng

Tính norm trước Multi-Head Self-Attention (MSA):

Input:

Z0=[10.612.213.815.317.720.128.833.638.433.539.144.7].\bm{Z_0} = \begin{bmatrix} 10.6 & 12.2 & 13.8 \\ 15.3 & 17.7 & 20.1 \\ 28.8 & 33.6 & 38.4 \\ 33.5 & 39.1 & 44.7 \end{bmatrix}.

Áp dụng công thức tính LayerNorm:

Z0[i,j]=Z0[i,j]μiσi,\bm{Z'_0[i, j]} = \frac{\bm{Z_0[i, j]} - \mu_i}{\sigma_i},

với:

μi=1Dj=1DZ0[i,j],σi=1Dj=1D(Z0[i,j]μi)2.\mu_i = \frac{1}{D} \sum_{j=1}^D \bm{Z_0[i, j]}, \quad \sigma_i = \sqrt{\frac{1}{D} \sum_{j=1}^D (\bm{Z_0[i, j]} - \mu_i)^2}.
  • Với hàng 1: μ1=10.6+12.2+13.83=12.2,\mu_1 = \frac{10.6 + 12.2 + 13.8}{3} = 12.2, σ1=(10.612.2)2+(12.212.2)2+(13.812.2)231.2247.\quad \sigma_1 = \sqrt{\frac{(10.6-12.2)^2 + (12.2-12.2)^2 + (13.8-12.2)^2}{3}} \approx 1.2247. Chuẩn hóa: Z0[1,:]=Z0[1,:]μ1σ1=[1.2247,0,1.2247].\bm{Z'_0[1, :]} = \frac{\bm{Z_0[1, :]} - \mu_1}{\sigma_1} = [-1.2247, 0, 1.2247].
  • Tính tương tự cho các hàng còn lại, ta được kết quả chuẩn hóa toàn bộ.
Z0=[1.224701.22471.224701.22471.224701.22471.224701.2247],Z0R4×3.\bm{Z'_0} = \begin{bmatrix} -1.2247 & 0 & 1.2247 \\ -1.2247 & 0 & 1.2247 \\ -1.2247 & 0 & 1.2247 \\ -1.2247 & 0 & 1.2247 \end{bmatrix}, \quad \bm{Z'_0} \in \mathbb{R}^{4 \times 3}.

Multi-Head Self-Attention:

  1. Xác định ma trận trọng số cho Q, K, V:

    Trong bước này, chúng ta tính các ma trận Query (Q\mathbf{Q}), Key (K\mathbf{K}), và Value (V\mathbf{V}) cho hai đầu Attention (Two Heads).

    Input:

    Z0=[1.224701.22471.224701.22471.224701.22471.224701.2247],Z0R4×3.\bm{Z'_0} = \begin{bmatrix} -1.2247 & 0 & 1.2247 \\ -1.2247 & 0 & 1.2247 \\ -1.2247 & 0 & 1.2247 \\ -1.2247 & 0 & 1.2247 \end{bmatrix}, \quad \bm{Z'_0} \in \mathbb{R}^{4 \times 3}.

    Các ma trận trọng số WQ\mathbf{W_Q}, WK\mathbf{W_K}, WV\mathbf{W_V} cho mỗi đầu Attention:

    Head 1:

    WQ(1)=[0.20.10.20.30.40.30.40.50.6],WK(1)=[0.10.20.30.40.50.60.70.80.9],WV(1)=[0.10.20.30.40.50.60.70.80.9].\bm{W_Q^{(1)}} = \begin{bmatrix} 0.2 & 0.1 & 0.2 \\ 0.3 & 0.4 & 0.3 \\ 0.4 & 0.5 & 0.6 \end{bmatrix}, \quad \bm{W_K^{(1)}} = \begin{bmatrix} 0.1 & 0.2 & 0.3 \\ 0.4 & 0.5 & 0.6 \\ 0.7 & 0.8 & 0.9 \end{bmatrix}, \quad \bm{W_V^{(1)}} = \begin{bmatrix} 0.1 & 0.2 & 0.3 \\ 0.4 & 0.5 & 0.6 \\ 0.7 & 0.8 & 0.9 \end{bmatrix}.

    Head 2:

    WQ(2)=[0.20.30.10.40.50.30.60.70.9],WK(2)=[0.10.20.30.40.50.60.70.80.9],WV(2)=[0.80.70.60.50.40.30.20.10.9].\bm{W_Q^{(2)}} = \begin{bmatrix} 0.2 & 0.3 & 0.1 \\ 0.4 & 0.5 & 0.3 \\ 0.6 & 0.7 & 0.9 \end{bmatrix}, \quad \bm{W_K^{(2)}} = \begin{bmatrix} 0.1 & 0.2 & 0.3 \\ 0.4 & 0.5 & 0.6 \\ 0.7 & 0.8 & 0.9 \end{bmatrix}, \quad \bm{W_V^{(2)}} = \begin{bmatrix} 0.8 & 0.7 & 0.6 \\ 0.5 & 0.4 & 0.3 \\ 0.2 & 0.1 & 0.9 \end{bmatrix}.

    Ta dùng công thức dưới đây để tính các ma trận (Q\mathbf{Q}), (K\mathbf{K}), (V\mathbf{V}) cho cho Head 1: Q(1)=Z0WQ(1),K(1)=Z0WK(1),V(1)=Z0WV(1)\mathbf{Q}^{(1)} = \mathbf{Z'}_0 \cdot \mathbf{W_Q}^{(1)}, \quad \mathbf{K}^{(1)} = \mathbf{Z'}_0 \cdot \mathbf{W_K}^{(1)}, \quad \mathbf{V}^{(1)} = \mathbf{Z'}_0 \cdot \mathbf{W_V}^{(1)}. Tương tự cho Head 2: Q(2)=Z0WQ(2),K(2)=Z0WK(2),V(2)=Z0WV(2)\mathbf{Q}^{(2)} = \mathbf{Z'}_0 \cdot \mathbf{W_Q}^{(2)}, \quad \mathbf{K}^{(2)} = \mathbf{Z'}_0 \cdot \mathbf{W_K}^{(2)}, \quad \mathbf{V}^{(2)} = \mathbf{Z'}_0 \cdot \mathbf{W_V}^{(2)}.

    Head 1:

    Q(1)=[0.24490.24490.24490.24490.24490.24490.24490.24490.24490.24490.24490.2449],K(1)=Q(1),V(1)=Q(1).\bm{Q^{(1)}} = \begin{bmatrix} 0.2449 & 0.2449 & 0.2449 \\ 0.2449 & 0.2449 & 0.2449 \\ 0.2449 & 0.2449 & 0.2449 \\ 0.2449 & 0.2449 & 0.2449 \end{bmatrix}, \quad \bm{K^{(1)}} = \bm{Q^{(1)}}, \quad \bm{V^{(1)}} = \bm{Q^{(1)}}.

    Head 2:

    Q(2)=[0.24490.24490.24490.24490.24490.24490.24490.24490.24490.24490.24490.2449],K(2)=Q(2),V(2)=Q(2).\bm{Q^{(2)}} = \begin{bmatrix} 0.2449 & 0.2449 & 0.2449 \\ 0.2449 & 0.2449 & 0.2449 \\ 0.2449 & 0.2449 & 0.2449 \\ 0.2449 & 0.2449 & 0.2449 \end{bmatrix}, \quad \bm{K^{(2)}} = \bm{Q^{(2)}}, \quad \bm{V^{(2)}} = \bm{Q^{(2)}}.

    Q1=K1=V1Q_1 = K_1 = V_1Q2=K2=V2Q_2 = K_2 = V_2 có giá trị giống nhau nguyên nhân là do dữ liệu đầu vào Z0\mathbf{Z'}_0 (sau chuẩn hóa) đồng nhất và trong các ma trận WQ\mathbf{W_Q}, WK\mathbf{W_K}, WV\mathbf{W_V} không khác biệt đủ để tạo ra sự biến đổi đáng kể. Tuy nhiên đây chỉ là bài toán kiểm thử (toy example) nên không gây ra vấn đề lớn. Cần lưu ý là trong thực tế, khi dữ liệu và trọng số được học từ quá trình huấn luyện, Q,K,VQ, K, V sẽ khác nhau, giúp đảm bảo tính hiệu quả của Multi-Head Attention.

  2. Tính Attention Scores và Outputs:

    Ta có công thức tính Attention:

    Attention(Q,K,V)=Softmax(QKDk)V.\text{Attention}(\bm{Q, K, V}) = \text{Softmax}\left(\frac{\bm{Q} \cdot \bm{K}^\top}{\sqrt{D_k}}\right) \cdot \bm{V}.

    Với Dk=3,Dk=1.732D_k = 3, \sqrt{D_k} = 1.732.

    Ta tính Attention Score cho Head 1:

    S(1)=Q(1)(K(1))Dk=[0.10390.10390.10390.10390.10390.10390.10390.10390.10390.10390.10390.10390.10390.10390.10390.1039].\bm{S^{(1)}} = \frac{\bm{Q^{(1)}} \cdot (\bm{K^{(1)}})^\top}{\sqrt{D_k}} = \begin{bmatrix} 0.1039 & 0.1039 & 0.1039 & 0.1039 \\ 0.1039 & 0.1039 & 0.1039 & 0.1039 \\ 0.1039 & 0.1039 & 0.1039 & 0.1039 \\ 0.1039 & 0.1039 & 0.1039 & 0.1039 \end{bmatrix}.

    Attention Distribution với Softmax:

    P(1)=Softmax(S(1))=[0.250.250.250.250.250.250.250.250.250.250.250.250.250.250.250.25].\bm{P^{(1)}} = \text{Softmax}(\bm{S^{(1)}}) = \begin{bmatrix} 0.25 & 0.25 & 0.25 & 0.25 \\ 0.25 & 0.25 & 0.25 & 0.25 \\ 0.25 & 0.25 & 0.25 & 0.25 \\ 0.25 & 0.25 & 0.25 & 0.25 \end{bmatrix}.

    Attention Output:

    A(1)=P(1)V(1)=[0.24490.24490.24490.24490.24490.24490.24490.24490.24490.24490.24490.2449].\bm{A^{(1)}} = \bm{P^{(1)}} \cdot \bm{V^{(1)}} = \begin{bmatrix} 0.2449 & 0.2449 & 0.2449 \\ 0.2449 & 0.2449 & 0.2449 \\ 0.2449 & 0.2449 & 0.2449 \\ 0.2449 & 0.2449 & 0.2449 \end{bmatrix}.

    Tương tự cho Head 2.

    Kết quả Multi-Head Output:

    MultiHead Output=[0.24490.24490.24490.24490.24490.24490.24490.24490.24490.24490.24490.2449].\text{MultiHead Output} = \begin{bmatrix} 0.2449 & 0.2449 & 0.2449 \\ 0.2449 & 0.2449 & 0.2449 \\ 0.2449 & 0.2449 & 0.2449 \\ 0.2449 & 0.2449 & 0.2449 \end{bmatrix}.

    Projection:

    O=MultiHead OutputWO=[10.612.213.815.317.720.128.833.638.433.539.144.7].\bm{O} = \text{MultiHead Output} \cdot \bm{W_O} = \begin{bmatrix} 10.6 & 12.2 & 13.8 \\ 15.3 & 17.7 & 20.1 \\ 28.8 & 33.6 & 38.4 \\ 33.5 & 39.1 & 44.7 \end{bmatrix}.

Residual Connection và Norm sau Attention:

  1. Residual Connection:

    Z1=Z0+O\mathbf{Z}_1 = \mathbf{Z}_0 + \mathbf{O}.

    Z1=Z0+O=[10.612.213.815.317.720.128.833.638.433.539.144.7]+[0.6290.9230.8930.6290.9230.8930.6290.9230.8930.6290.9230.893]=[11.22913.12314.69315.92918.62320.99329.42934.52339.29334.12940.02345.593].\bm{Z_1} = \bm{Z_0} + \bm{O} = \begin{bmatrix} 10.6 & 12.2 & 13.8 \\ 15.3 & 17.7 & 20.1 \\ 28.8 & 33.6 & 38.4 \\ 33.5 & 39.1 & 44.7 \end{bmatrix} + \begin{bmatrix} 0.629 & 0.923 & 0.893 \\ 0.629 & 0.923 & 0.893 \\ 0.629 & 0.923 & 0.893 \\ 0.629 & 0.923 & 0.893 \end{bmatrix} = \begin{bmatrix} 11.229 & 13.123 & 14.693 \\ 15.929 & 18.623 & 20.993 \\ 29.429 & 34.523 & 39.293 \\ 34.129 & 40.023 & 45.593 \end{bmatrix}.
  2. Layer Normalization:

    • Tính trung bình (μi\mu_i) và độ lệch chuẩn (σi\sigma_i) của từng hàng: μ1=11.229+13.123+14.6933=13.015,\mu_1 = \frac{11.229 + 13.123 + 14.693}{3} = 13.015 , σ1=(11.22913.015)2+(13.12313.015)2+(14.69313.015)231.416.\sigma_1 = \sqrt{\frac{(11.229 - 13.015)^2 + (13.123 - 13.015)^2 + (14.693 - 13.015)^2}{3}} \approx 1.416. Tính tương tự cho các hàng khác: μ2=18.515,σ22.069;μ3=34.415,σ34.027;μ4=39.915,σ44.681\mu_2 = 18.515, \sigma_2 \approx 2.069; \quad \mu_3 = 34.415, \sigma_3 \approx 4.027; \quad \mu_4 = 39.915, \sigma_4 \approx 4.681.
    • Chuẩn hóa từng hàng: Z1[1,:]=Z1[1,:]μ1σ1=[11.22913.12314.693]13.0151.416=[1.2610.0761.185].\bm{Z'_1[1, :]} = \frac{\bm{Z_1[1, :]} - \mu_1}{\sigma_1} = \frac{\begin{bmatrix} 11.229 & 13.123 & 14.693 \end{bmatrix} - 13.015}{1.416} = \begin{bmatrix} -1.261 & 0.076 & 1.185 \end{bmatrix}. Tương tự cho Z1[2,:],Z1[3,:],Z1[4,:]\mathbf{Z'}_1[2, :], \mathbf{Z'}_1[3, :], \mathbf{Z'}_1[4, :], ta được kết quả cuối cùng của Z1\mathbf{Z'}_1. Z1=[1.2610.0761.1851.2500.0521.1981.2380.0271.2111.2360.0231.213],Z1R4×3.\bm{Z'_1} = \begin{bmatrix} -1.261 & 0.076 & 1.185 \\ -1.250 & 0.052 & 1.198 \\ -1.238 & 0.027 & 1.211 \\ -1.236 & 0.023 & 1.213 \end{bmatrix}, \quad \bm{Z'_1} \in \mathbb{R}^{4 \times 3}.
Ảnh minh họa luồng tính toán trong một Transformer Encoder Block được sử dụng trong Vision Transformer. Trong đó: LN = LayerNorm, MSA = Multi-head Attention, MLP = Multi-layer Perceptron. Hình 9: Ảnh minh họa luồng tính toán trong một Transformer Encoder Block được sử dụng trong Vision Transformer. Trong đó: LN = LayerNorm, MSA = Multi-head Attention, MLP = Multi-layer Perceptron.

Multi-layer Perceptron:

  1. Layer 1 (Linear Layer + GELU): H=GELU(Z1W1+b1)\mathbf{H} = \text{GELU}(\mathbf{Z'}_1 \cdot \mathbf{W}_1 + b_1) Với:

    W1=[0.10.20.30.40.50.60.70.80.9],b1=[0.10.10.1]\bm{W_1} = \begin{bmatrix} 0.1 & 0.2 & 0.3 \\ 0.4 & 0.5 & 0.6 \\ 0.7 & 0.8 & 0.9 \end{bmatrix}, \quad {b_1} = \begin{bmatrix} 0.1 & 0.1 & 0.1 \end{bmatrix}

    Tính:

    Z1W1=[0.7340.7340.7340.7340.7340.7340.7350.7350.7350.7350.7350.735]\bm{Z'_1} \cdot \bm{W_1} = \begin{bmatrix} 0.734 & 0.734 & 0.734 \\ 0.734 & 0.734 & 0.734 \\ 0.735 & 0.735 & 0.735 \\ 0.735 & 0.735 & 0.735 \end{bmatrix}

    Thêm b1b_1 vào ma trận trên, ta được:

    Z1W1+b1=[0.8340.8340.8340.8340.8340.8340.8350.8350.8350.8350.8350.835]\bm{Z'_1} \cdot \bm{W_1} + {b_1} = \begin{bmatrix} 0.834 & 0.834 & 0.834 \\ 0.834 & 0.834 & 0.834 \\ 0.835 & 0.835 & 0.835 \\ 0.835 & 0.835 & 0.835 \end{bmatrix}

    Áp dụng hàm GELU vào:

    H=[0.6650.6650.6650.6660.6660.6660.6660.6660.6660.6660.6660.666]\bm{H} = \begin{bmatrix} 0.665 & 0.665 & 0.665 \\ 0.666 & 0.666 & 0.666 \\ 0.666 & 0.666 & 0.666 \\ 0.666 & 0.666 & 0.666 \end{bmatrix}
  2. Layer 2 (Linear Layer):

    Tiếp tục áp dụng phép biến đổi tuyến tính: Z2=HW2+b2+Z1\mathbf{Z}_2 = \mathbf{H} \cdot \mathbf{W}_2 + b_2 + \mathbf{Z}_1. Với:

    W2=[0.20.40.60.50.70.90.30.50.7],b2=[0.20.30.4]\bm{W_2} = \begin{bmatrix} 0.2 & 0.4 & 0.6 \\ 0.5 & 0.7 & 0.9 \\ 0.3 & 0.5 & 0.7 \end{bmatrix}, \quad {b_2} = \begin{bmatrix} 0.2 & 0.3 & 0.4 \end{bmatrix}

    Tính:

    HW2+b2=[0.8661.3641.8630.8571.3561.8640.8661.3571.8650.8661.3661.865]\bm{H} \cdot \bm{W_2} + b_2 = \begin{bmatrix} 0.866 & 1.364 & 1.863 \\ 0.857 & 1.356 & 1.864 \\ 0.866 & 1.357 & 1.865 \\ 0.866 & 1.366 & 1.865 \end{bmatrix}
  3. Residual Connection:

    Kết hợp với Z1\mathbf{Z}_1:

    Z2=HW2+b2+Z1=[12.09414.48716.55616.79519.98822.76730.29635.88741.15834.99641.38947.458]\mathbf{Z_2} = \mathbf{H} \cdot \mathbf{W_2} + b_2 + \bm{Z_1} = \begin{bmatrix} 12.094 & 14.487 & 16.556 \\ 16.795 & 19.988 & 22.767 \\ 30.296 & 35.887 & 41.158 \\ 34.996 & 41.389 & 47.458 \end{bmatrix}

Trích xuất [CLS] Token

Input của bước này là ma trận Z2R4×3\mathbf{Z}_2 \in \mathbb{R}^{4 \times 3}, đầu ra của bước 5.

Trong ViT, token [CLS] được định nghĩa là hàng đầu tiên của ma trận Z2\mathbf{Z}_2, ký hiệu là ZCLS\mathbf{Z}_{\text{CLS}}. Đây là vector duy nhất đại diện cho toàn bộ thông tin từ các patch và có thể được sử dụng làm đầu vào cho bước tiếp theo - bước đưa ra kết quả dự đoán (Classification Head).

Áp dụng công thức trích xuất:

ZCLS=row1(Z2)=[12.09414.48716.556]\bm{Z_{\text{CLS}}} = row_1(\bm{Z_2}) = \begin{bmatrix} 12.094 & 14.487 & 16.556 \end{bmatrix}

Output của bước này là vector ZCLSR1×3\mathbf{Z}_{\text{CLS}} \in \mathbb{R}^{1 \times 3}, đại diện cho token [CLS]. Token [CLS] đóng vai trò là một đầu ra gọn nhẹ, tóm tắt toàn bộ thông tin học được từ các patch ảnh và là bước chuẩn bị cuối cùng trước khi thực hiện phân loại. Tính cô đọng của ZCLS\mathbf{Z}_{\text{CLS}} giúp tăng hiệu quả trong các tác vụ phân loại, đồng thời giữ lại ngữ nghĩa chính yếu từ toàn bộ ảnh đầu vào.

Transformer Encoder hoàn chỉnh. Bên trong bao gồm một số lượng $L$ các Encoder Block. Hình 10: Transformer Encoder hoàn chỉnh. Bên trong bao gồm một số lượng L các Encoder Block.

Classification Head (MLP Head)

Trong bước này, token [CLS] được đưa qua một mạng MLP (Multilayer Perceptron) để thực hiện tác vụ phân loại. Mạng MLP này bao gồm hai tầng tuyến tính (linear layers) và một hàm kích hoạt phi tuyến GELU ở giữa.

Vector đầu vào là ZCLSR1×3\mathbf{Z}_{\text{CLS}} \in \mathbb{R}^{1 \times 3}, được trích xuất từ bước 6:

ZCLS=[12.09414.48716.556]\bm{Z_{\text{CLS}}} = \begin{bmatrix} 12.094 & 14.487 & 16.556 \end{bmatrix}

7.1. Tầng tuyến tính đầu tiên: Ta có công thức như sau: H=GELU(ZCLSWhidden+bhidden)\mathbf{H} = \text{GELU}(\mathbf{Z}_{\text{CLS}} \cdot W_{\text{hidden}} + \mathbf{b}_{\text{hidden}}) Với:

Whidden=[0.20.30.40.50.60.70.80.91.0],bhidden=[0.10.10.1]\bm{W_{\text{hidden}}} = \begin{bmatrix} 0.2 & 0.3 & 0.4 \\ 0.5 & 0.6 & 0.7 \\ 0.8 & 0.9 & 1.0 \end{bmatrix} , \quad {b_{\text{hidden}}} = \begin{bmatrix} 0.1 & 0.1 & 0.1 \end{bmatrix} ZCLSWhidden=[12.09414.48716.556][0.20.30.40.50.60.70.80.91.0]=[22.90727.22131.535]\bm{Z_{\text{CLS}}} \cdot \bm{W_{\text{hidden}}} = \begin{bmatrix} 12.094 & 14.487 & 16.556 \end{bmatrix} \cdot \begin{bmatrix} 0.2 & 0.3 & 0.4 \\ 0.5 & 0.6 & 0.7 \\ 0.8 & 0.9 & 1.0 \end{bmatrix} = \begin{bmatrix} 22.907 & 27.221 & 31.535 \end{bmatrix}


Thêm bias:

ZCLSWhidden+bhidden=[22.90727.22131.535]+[0.10.10.1]=[23.00727.32131.634]\bm{Z_{\text{CLS}}} \cdot \bm{W_{\text{hidden}}} + {b_{\text{hidden}}} = \begin{bmatrix} 22.907 & 27.221 & 31.535 \end{bmatrix} + \begin{bmatrix} 0.1 & 0.1 & 0.1 \end{bmatrix} = \begin{bmatrix} 23.007 & 27.321 & 31.634 \end{bmatrix}


Áp dụng hàm kích hoạt GELU:

H=GELU([23.00727.32131.634])=[23.00727.32131.634]\bm{H} = \text{GELU(} \begin{bmatrix} 23.007 & 27.321 & 31.634 \end{bmatrix} \text{)} = \begin{bmatrix} 23.007 & 27.321 & 31.634 \end{bmatrix}

7.2. Tầng tuyến tính thứ hai: Ologits=HWout+bout\mathbf{O}_{\text{logits}} = \mathbf{H} \cdot \mathbf{W}_{\text{out}} + b_{\text{out}} Với:

Wout=[0.30.40.50.60.70.8],bout=[0.10.2]\bm{W_{\text{out}}} = \begin{bmatrix} 0.3 & 0.4 \\ 0.5 & 0.6 \\ 0.7 & 0.8 \end{bmatrix} , \quad {b_{\text{out}}} = \begin{bmatrix} 0.1 & 0.2 \end{bmatrix} HWout=[23.00727.32131.634][0.30.40.50.60.70.8]=[42.70750.903]\bm{H} \cdot \bm{W_{\text{out}}} = \begin{bmatrix} 23.007 & 27.321 & 31.634 \end{bmatrix} \cdot \begin{bmatrix} 0.3 & 0.4 \\ 0.5 & 0.6 \\ 0.7 & 0.8 \end{bmatrix} = \begin{bmatrix} 42.707 & 50.903 \end{bmatrix}


Thêm bias:

Ologits=[42.70750.903]+[0.10.2]=[42.80751.103]\bm{O_{\text{logits}}} = \begin{bmatrix} 42.707 & 50.903 \end{bmatrix} + \begin{bmatrix} 0.1 & 0.2 \end{bmatrix} = \begin{bmatrix} 42.807 & 51.103 \end{bmatrix}

7.3. Softmax để chuyển thành xác suất: Poutput=Softmax(Ologits)\mathbf{P}_{\text{output}} = \text{Softmax}(\mathbf{O}_{\text{logits}}) Tính toán softmax:

Poutput,i=exp(Ologits,i)jexp(Ologits,j)\bm{P_{\text{output}, i}} = \frac{\exp(\bm{O_{\text{logits}, i}})}{\sum_{j} \exp(\bm{O_{\text{logits}, j}})} Poutput=Softmax[42.80751.103]=[2.494×1049.998×101]\bm{P_{\text{output}}} = \text{Softmax} \begin{bmatrix} 42.807 & 51.103 \end{bmatrix} = \begin{bmatrix} 2.494 \times 10^{-4} & 9.998 \times 10^{-1} \end{bmatrix}

Kết quả cuối cùng của bước này là vector xác suất PoutputR1×2\mathbf{P}_{\text{output}} \in \mathbb{R}^{1 \times 2}, đại diện cho khả năng mẫu đầu vào thuộc về từng lớp. Như vậy mạng MLP Head thực hiện chuyển đổi từ token [CLS] thành các xác suất phân loại cho từng lớp. Đây là bước cuối cùng trong mô hình Vision Transformer (ViT), nơi toàn bộ thông tin từ ảnh được chuyển thành đầu ra phục vụ các tác vụ phân loại cụ thể.

Từ ảnh đầu vào đến giá trị dự đoán nhận được từ ViT. Hình 11: Từ ảnh đầu vào đến giá trị dự đoán nhận được từ ViT.

- Hết -