ViT 훈련 원리 요약, 질문에 대답하기
- -
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은 패치 간의 상관관계를 학습하는 과정입니다. 이를 위해 입력 토큰 $x_1, x_2, \dots, x_N$에 대해, 각각의 패치가 다른 패치와의 관계를 계산합니다.
- Attention Score는 Query, Key, Value를 통해 계산됩니다.
- $$ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right) V $$
- Feed-Forward Layer:
- 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 \times W \times C$ 형태로 나타냅니다.
- $H$: 이미지의 높이(height),
- $W$: 이미지의 너비(width),
- $C$: 채널 수 (RGB 이미지에서는 $C = 3$).
ViT는 이 이미지를 작은 패치(patch)로 나눕니다. 예를 들어, 이미지 크기가 $H = 224$, $W = 224$이고 패치 크기가 $16 \times 16$이라면, 이미지를 $16 \times 16$ 크기의 패치로 나눕니다. 각 패치는 RGB 채널을 포함하므로, 하나의 패치의 크기는 $16 \times 16 \times 3$이 됩니다.
2. 패치 벡터로 변환 (Flattening)
이미지를 패치로 나누었다면, 각 패치를 1차원 벡터로 변환해야 합니다. 예를 들어, $16 \times 16 \times 3$ 크기의 패치를 Flatten하여 $16 \times 16 \times 3 = 768$ 차원의 벡터로 변환할 수 있습니다. 이 과정을 통해 모든 패치는 하나의 고정된 크기의 벡터로 변환됩니다.
3. 패치 임베딩 (Linear Projection)
패치를 1차원 벡터로 변환한 후에는 이 벡터를 고차원 임베딩으로 변환해야 합니다. 이를 위해 선형 변환(Linear Projection)을 사용합니다. 선형 변환을 위해 학습 가능한 가중치 행렬 $W$를 사용하여, 각 패치 벡터를 고차원 벡터로 변환합니다.
변환 수식은 다음과 같습니다:
$$
z_i = W \cdot x_i
$$
여기서:
- $x_i$: Flatten된 패치 벡터 (차원: 768),
- $W$: 학습 가능한 가중치 행렬 (차원: $D \times 768$, $D$는 임베딩 차원, 예를 들어 $D = 768$),
- $z_i$: 고차원 임베딩 벡터.
따라서, 각 패치 $x_i$는 $W$와의 선형 변환을 통해 $D$-차원의 고차원 벡터 $z_i$로 변환됩니다. 이렇게 변환된 고차원 임베딩 벡터들은 Transformer의 입력으로 사용됩니다.
4. 패치 임베딩의 전체 과정 정리
- RGB 이미지 분할: $H \times W \times C$ 크기의 이미지를 패치 크기 $P \times P$로 분할합니다.
- 예: $224 \times 224 \times 3$ 이미지를 $16 \times 16$ 패치로 나누면 $14 \times 14$개의 패치가 생성됩니다.
- Flattening: 각 패치 $P \times P \times 3$을 Flatten하여 1차원 벡터로 변환합니다.
- 예: $16 \times 16 \times 3$ 패치를 1차원 벡터 768-차원으로 변환.
- Linear Projection: 각 패치 벡터를 선형 변환을 통해 $D$-차원의 고차원 벡터로 변환합니다.
- 예: 768차원 벡터를 $D = 768$ 크기의 임베딩 벡터로 변환.
5. ViT에서의 패치 처리 예시
- 입력 이미지 크기: $224 \times 224 \times 3$
- 패치 크기: $16 \times 16$
- 패치 개수: $(224 / 16) \times (224 / 16) = 14 \times 14 = 196$
- 각 패치의 차원: $16 \times 16 \times 3 = 768$
- 임베딩 차원: $D = 768$
결과적으로, ViT는 196개의 패치로 나뉜 이미지를 입력으로 받아, 각 패치를 768차원 고차원 벡터로 변환하여 Transformer의 입력으로 사용합니다. 이 고차원 벡터들은 Self-Attention을 통해 서로 상호작용하며 학습됩니다.
요약:
- RGB 이미지의 각 패치는 $P \times P \times 3$ 크기로 나뉘고, 이를 1차원 벡터로 Flatten한 후 선형 변환을 통해 고차원 임베딩 벡터로 변환됩니다.
- ViT는 이 패치 임베딩 벡터들을 Transformer의 입력으로 사용하여 패치 간의 상관관계를 학습합니다.
Inductive Bias
Inductive Bias을 직역하면 유도 편향이라고 한다.
이러한 Inductive Bias는 학습에 사용되지 않은 데이터에 대해서 어떤 것에 대해 예측할 때 정확한 예측을 위해 사용하는 추가적인 가정입니다.
https://velog.io/@pre_f_86/Vision-TransformerViT-%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0
1. Patch Embedding
이미지에서 Local Feature 추출하는 단계
이미지를 16x16으로 자른다.
16x16x3 짜리 패치가 여러개 만들고 각 패치를 flatten해서 1차원 벡터로 만든다. 그리고 이것들을 W의 가중치 행렬을 통해 고차원 벡터로 변환한다. 이를 선형변환 또는 선형 투영이라고 한다.
$z_i = W \cdot x_i$ 패치는 1차원 벡터가 되고 가중치 행렬 연산으로 고차원 벡터 z로 변함
Linear Projection과 Linear Transform은 동일한 개념
2. Position Embedding
각 패치간의 관계를 추출하는 단계
Transformer 모델은 각 패치나 토큰의 순서를 따로 인식하지 않기 때문에, 포지셔널 임베딩(Positional Embedding)이 필요합니다. 이는 패치의 순서 정보를 추가하기 위한 것으로, 각 패치의 임베딩 벡터에 위치 정보를 더해줍니다.
포지셔널 임베딩 벡터는 패치의 위치에 따라 미리 정의된 고차원 벡터로, Transformer Encoder에서 학습 가능한 고정된 벡터 또는 사인, 코사인 함수 기반으로 설계될 수 있습니다. ViT에서는 패치의 위치마다 고유한 벡터를 학습하게 됩니다.
포지셔널 임베딩(Positional Embedding)을 학습 가능한 파라미터로 처리합니다. 즉, ViT에서 포지셔널 임베딩 $p_i$는 학습 과정에서 자동으로 학습되며, 별도의 수학적 수식으로 계산되는 것은 아닙니다.
코드는 아래와 같이 크기에 맞춰 빈값으로 값이 바뀌도록 학습 가능한 파라미터로 처리한다.
# Positional Embedding Module
class PositionalEmbedding(nn.Module):
def __init__(self, num_patches, embed_dim):
super(PositionalEmbedding, self).__init__()
self.pos_embedding = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))
def forward(self, x):
return x + self.pos_embedding
3. Patch Embedding + Position Embedding
패치 임베딩 $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 = W_Q \dot z', K = W_K \dot z', V = W_V \dot 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 결과가 서로 다른 공간에서 학습되기 때문에, 다양한 관점에서 패치 간의 관계를 학습할 수 있다.
$$ \text{ MultiHead }= \text{ Concat}(\text{head}_1, \dots \text{head}_h ) W^{O}$$
여기서 ${W^{O}}$는 최종 선형 변환을 위한 학습 가능한 가중치 행렬이다.
4.3 Residual Connection (Skip Connection)
4.4 Layer Normalization
https://www.youtube.com/watch?v=MvZ2wzghbCg
https://daebaq27.tistory.com/108
'Machine Learning' 카테고리의 다른 글
멀티모달 역량 및 경험을 쌓아보자 (1) | 2024.09.17 |
---|---|
모델 경량화 (0) | 2024.09.14 |
AUC가 뭔가요? (0) | 2024.08.11 |
4.시계열_1_따릉이 (0) | 2024.06.02 |
3.다중분류문제_1_아이리스 (0) | 2024.06.02 |
소중한 공감 감사합니다