Vision Transformer (ViT)는 이미지 데이터를 처리하는 데 있어 Transformer 모델을 사용하는 방법으로, 전통적인 CNN과는 다른 방식으로 이미지를 처리합니다. CNN이 이미지에서 로컬 특징(local features)을 추출하는 것과 달리, ViT는 이미지를 패치(patch) 단위로 나누어 각각의 패치를 토큰(token)으로 처리하고, 이 토큰 간의 관계를 학습합니다.
CNN이 로컬 특징을 학습하는 것과 달리, ViT는 모든 패치 간의 글로벌 관계를 학습하는 데 초점을 둡니다.
1. Vision Transformer의 구조
ViT의 핵심 구조는 일반적인 Transformer 모델과 유사합니다. Transformer는 원래 자연어 처리(NLP)에서 사용되었으며, 각 단어의 관계를 학습하는 방식입니다. ViT는 이를 이미지 처리에 적용한 모델입니다. ViT는 이미지의 패치 간 관계를 학습하여 이미지를 인식합니다.
ViT의 주요 단계:
이미지를 패치(patch)로 분할: 이미지를 여러 작은 패치로 나누고, 각 패치는 1차원 벡터로 변환됩니다. 예를 들어, 16×1616 \times 1616×16 크기의 패치로 이미지를 나누면, 각 패치가 하나의 입력 토큰이 됩니다.
패치 임베딩(Embedding): 각 패치는 고차원 벡터로 변환됩니다. 이를 패치 임베딩이라고 합니다. 패치 임베딩 후에 각 패치 벡터는 Transformer 입력으로 사용됩니다.
포지셔널 인코딩(Positional Encoding): Transformer는 순서를 고려하지 않는 모델이므로, 이미지 패치의 위치 정보를 주기 위해 포지셔널 인코딩을 추가합니다. 이를 통해 모델이 패치 간의 순서를 알 수 있습니다.
Transformer Encoder: 각 패치 토큰은 여러 개의 Self-Attention Layer와 Feed-Forward Layer를 통과하면서 패치 간의 관계를 학습합니다. 여기서 Self-Attention Mechanism이 핵심 역할을 합니다.
클래스 토큰(Class Token): Transformer의 마지막에는 클래스 토큰이 추가되며, 이 토큰은 모든 패치로부터의 정보를 모아 최종적인 예측을 만듭니다.
2. 순전파 (Forward Propagation)
ViT의 순전파는 다음과 같이 이루어집니다:
패치 임베딩과 포지셔널 인코딩:
이미지를 패치로 나누고, 각 패치에 대해 임베딩을 수행한 후 포지셔널 인코딩을 추가합니다.
Self-Attention Mechanism:
Self-Attention은 패치 간의 상관관계를 학습하는 과정입니다. 이를 위해 입력 토큰 x1,x2,…,xNx1,x2,…,xN에 대해, 각각의 패치가 다른 패치와의 관계를 계산합니다.
Self-Attention을 통해 얻은 정보를 Feed-Forward Network에 통과시켜 각 패치 간의 상관관계를 바탕으로 패치를 변환합니다. 이 과정을 여러 번 반복하여 패치 간 관계를 학습합니다.
클래스 토큰으로 최종 출력:
마지막에 클래스 토큰이 전체 패치로부터 정보를 통합하여 최종적으로 출력값을 생성합니다. 이 출력값은 분류 작업에 사용됩니다.
3. 역전파 (Backpropagation)
ViT에서도 역전파 과정은 CNN이나 ANN과 동일하게 이루어집니다.
손실 함수:
분류 문제의 경우, 예측값과 실제값 사이의 차이를 계산하기 위해 Cross-Entropy Loss를 사용합니다.
기울기 계산:
Self-Attention Layer와 Feed-Forward Network의 가중치에 대해 기울기를 계산합니다. Self-Attention에서 사용하는 Query, Key, Value 가중치도 학습 가능한 파라미터이므로, 역전파를 통해 손실 함수에 따라 업데이트됩니다.
가중치 업데이트:
ViT의 모든 학습 가능한 파라미터(패치 임베딩, Self-Attention 가중치, Feed-Forward Network 가중치 등)는 역전파를 통해 업데이트됩니다.
4. Transformer에서의 '기억'
Transformer는 Self-Attention Mechanism을 통해 입력의 모든 패치 간의 관계를 학습합니다. CNN이 로컬 특징을 학습하는 것과 달리, ViT는 모든 패치 간의 글로벌 관계를 학습하는 데 초점을 둡니다.
Self-Attention은 각 패치가 다른 모든 패치와 상호작용할 수 있게 만들어 주며, 이를 통해 ViT는 이미지의 모든 영역에서 중요한 정보를 추출하고 기억할 수 있습니다.
즉, 한 패치에서 중요한 정보가 다른 패치에 전달되며, 이 정보는 여러 레이어를 거치면서 누적됩니다. 이 과정을 통해 ViT는 패치 간의 상관관계를 학습하고, 이미지를 효과적으로 인식하게 됩니다.
요약:
순전파: 이미지 패치를 Transformer의 Self-Attention과 Feed-Forward Network에 통과시키면서 각 패치 간의 상관관계를 학습합니다.
역전파: 손실 함수의 기울기를 계산해 모든 학습 가능한 파라미터(패치 임베딩, Self-Attention 가중치, Feed-Forward Network 가중치)를 업데이트합니다.
기억: Self-Attention Mechanism을 통해 이미지 패치 간의 관계를 학습하고 중요한 정보를 '기억'하며, 이를 바탕으로 최종 예측을 수행합니다.
ViT는 CNN과는 다르게 글로벌 패턴을 학습하는 모델로, Self-Attention을 통해 패치 간의 상관관계를 강화하며, 이는 '기억'에 해당하는 중요한 학습 메커니즘입니다.
1. RGB 이미지와 패치 분할
먼저, RGB 이미지의 크기는 일반적으로 H×W×CH×W×C 형태로 나타냅니다.
HH: 이미지의 높이(height),
WW: 이미지의 너비(width),
CC: 채널 수 (RGB 이미지에서는 C=3C=3).
ViT는 이 이미지를 작은 패치(patch)로 나눕니다. 예를 들어, 이미지 크기가 H=224H=224, W=224W=224이고 패치 크기가 16×1616×16이라면, 이미지를 16×1616×16 크기의 패치로 나눕니다. 각 패치는 RGB 채널을 포함하므로, 하나의 패치의 크기는 16×16×316×16×3이 됩니다.
2. 패치 벡터로 변환 (Flattening)
이미지를 패치로 나누었다면, 각 패치를 1차원 벡터로 변환해야 합니다. 예를 들어, 16×16×316×16×3 크기의 패치를 Flatten하여 16×16×3=76816×16×3=768 차원의 벡터로 변환할 수 있습니다. 이 과정을 통해 모든 패치는 하나의 고정된 크기의 벡터로 변환됩니다.
3. 패치 임베딩 (Linear Projection)
패치를 1차원 벡터로 변환한 후에는 이 벡터를 고차원 임베딩으로 변환해야 합니다. 이를 위해 선형 변환(Linear Projection)을 사용합니다. 선형 변환을 위해 학습 가능한 가중치 행렬WW를 사용하여, 각 패치 벡터를 고차원 벡터로 변환합니다.
변환 수식은 다음과 같습니다:
zi=W⋅xizi=W⋅xi
여기서:
xixi: Flatten된 패치 벡터 (차원: 768),
WW: 학습 가능한 가중치 행렬 (차원: D×768D×768, DD는 임베딩 차원, 예를 들어 D=768D=768),
zizi: 고차원 임베딩 벡터.
따라서, 각 패치 xixi는 WW와의 선형 변환을 통해 DD-차원의 고차원 벡터 zizi로 변환됩니다. 이렇게 변환된 고차원 임베딩 벡터들은 Transformer의 입력으로 사용됩니다.
4. 패치 임베딩의 전체 과정 정리
RGB 이미지 분할: H×W×CH×W×C 크기의 이미지를 패치 크기 P×PP×P로 분할합니다.
예: 224×224×3224×224×3 이미지를 16×1616×16 패치로 나누면 14×1414×14개의 패치가 생성됩니다.
Flattening: 각 패치 P×P×3P×P×3을 Flatten하여 1차원 벡터로 변환합니다.
예: 16×16×316×16×3 패치를 1차원 벡터 768-차원으로 변환.
Linear Projection: 각 패치 벡터를 선형 변환을 통해 DD-차원의 고차원 벡터로 변환합니다.
패치 임베딩 $z_i$와 포지셔널 임베딩 $p_i$를 더하는 것은 매우 간단한 방식으로 이루어집니다. 각 패치의 임베딩 벡터 $z_i$에 해당 패치의 위치 정보가 담긴 포지셔널 임베딩 벡터 $p_i$를 더해줍니다:
$$z'_i = z_i + p_i$$
여기서:
$z_i$ 는 패치 임베딩 벡터 (패치의 특징 정보),
$p_i$ 는 포지셔널 임베딩 벡터 (패치의 위치 정보),
$z'_i $는 위치 정보가 더해진 최종 패치 임베딩 벡터.
이 덧셈 연산을 통해, 각 패치 벡터는 자신의 위치 정보와 패치의 특징 정보를 모두 포함하게 됩니다. 이를 통해 Transformer Encoder는 각 패치의 순서를 이해하면서, 패치 간의 관계를 학습할 수 있습니다.
4. Transformer Encoder로 입력
이제 위치 정보가 포함된 임베딩 벡터 $z'_i$ 가 Transformer Encoder의 입력으로 들어갑니다. Transformer Encoder는 이 벡터들을 Self-Attention Mechanism과 Feed-Forward Network를 통해 처리하며, 패치 간의 상관관계를 학습하고, 이미지의 글로벌 의존성(global dependency)을 학습하게 됩니다.
Transformer Encoder 전체 흐름 요약:
Multi-Head Self-Attention (MHSA): 입력 패치 간의 관계를 학습하고 상호작용을 계산합니다.
Residual Connection: 입력과 Multi-Head Attention의 출력을 더하여 정보 손실을 방지합니다.
Layer Normalization: Multi-Head Attention의 출력을 정규화하여 학습을 안정화합니다.
Feed-Forward Network (FFN): 각 패치 임베딩에 대해 독립적으로 비선형 변환을 수행합니다.
Residual Connection (두 번째): 입력과 FFN 출력을 더해줍니다.
Layer Normalization (두 번째): FFN 출력을 정규화하여 최종 출력을 생성합니다.
4.1 Layer Normalization (LayerNorm): Self-Attention에 들어가기 전에 입력 벡터를 정규화.
- Multi-Head Self-Attention에 들어가기 전에 먼저 입력 텐서에 대해 Layer Normalization이 적용됩니다.
이는 학습의 안정성을 높이고, 학습 속도를 개선하기 위해 사용하는 정규화 기법 중 하나
- LayerNorm은 패치별로 각 차원의 평균과 분산을 계산하여 정규화합니다
Layer Normalization은 각 입력 샘플에 대해 개별적으로 정규화를 수행합니다. 이는 네트워크의 한 레이어에서 활성화된 뉴런들을 대상으로, 그 값들이 같은 분포를 따르도록 정규화하는 방식
구체적으로, 하나의 입력 벡터(예: 패치 임베딩 벡터)의 평균과 분산을 계산하고, 이를 사용해 정규화한다.
이 과정은 모든 차원을 대상으로 이루어지기 때문에, 레이어에서 발생하는 모든 뉴런의 출력을 정규화하여 일정한 분포를 유지하게 만든다. Layer Normalization에 대해서도 따로 공부하자 검색해가면서
코드로는 아래와 같이 구현할 수 있다.
import torch
import torch.nn as nn
# 예시 입력: (배치 크기, 시퀀스 길이, 임베딩 차원)
x = torch.randn(3, 5, 768) # 배치 크기 3, 시퀀스 길이 5, 임베딩 차원 768# Layer Normalization을 위한 LayerNorm 정의# 여기서 normalized_shape는 입력의 마지막 차원 (768)입니다.
layer_norm = nn.LayerNorm(768)
# Layer Normalization 적용
output = layer_norm(x)
4.2 Multi-Head Self-Attention (MHSA)
4.2.1 Query (Q),Key (K), Value (V) 만들기
이렇게 정규화된 입력 벡터 x를 선형 변환을 통해 Q, K, V를 얻는다.
Q=WQ˙z′,K=WK˙z′,V=WV˙z′
4.2.2 Attention Score 만들기
\text{Attention}(Q, K, V) = \text{softmax} (\frac{QK^T}{\root(d_k)}) V
$d_k$는 Key 벡터의 차원입니다. Softmax를 통해 Query와 Key 간의 유사도를 계산하고, Value에 가중합을 적용하여 생성
임베딩된 z'들이 여러개임 모든 z'별 Attention head들에서 나온 결과들을 모두 Concat해준다. 즉, 각 헤드에서 나온 Self-Attention 결과가 서로 다른 공간에서 학습되기 때문에, 다양한 관점에서 패치 간의 관계를 학습할 수 있다.