새소식

Machine Learning

ViT 훈련 원리 요약, 질문에 대답하기

  • -

Vision Transformer (ViT)는 이미지 데이터를 처리하는 데 있어 Transformer 모델을 사용하는 방법으로, 전통적인 CNN과는 다른 방식으로 이미지를 처리합니다. CNN이 이미지에서 로컬 특징(local features)을 추출하는 것과 달리, ViT는 이미지를 패치(patch) 단위로 나누어 각각의 패치를 토큰(token)으로 처리하고, 이 토큰 간의 관계를 학습합니다.

CNN이 로컬 특징을 학습하는 것과 달리, ViT는 모든 패치 간의 글로벌 관계를 학습하는 데 초점을 둡니다.

ViT의 핵심 구조는 일반적인 Transformer 모델과 유사합니다. Transformer는 원래 자연어 처리(NLP)에서 사용되었으며, 각 단어의 관계를 학습하는 방식입니다. ViT는 이를 이미지 처리에 적용한 모델입니다. ViT는 이미지의 패치 간 관계를 학습하여 이미지를 인식합니다.

  1. 이미지를 패치(patch)로 분할: 이미지를 여러 작은 패치로 나누고, 각 패치는 1차원 벡터로 변환됩니다. 예를 들어, 16×1616 \times 1616×16 크기의 패치로 이미지를 나누면, 각 패치가 하나의 입력 토큰이 됩니다.
  2. 패치 임베딩(Embedding): 각 패치는 고차원 벡터로 변환됩니다. 이를 패치 임베딩이라고 합니다. 패치 임베딩 후에 각 패치 벡터는 Transformer 입력으로 사용됩니다.
  3. 포지셔널 인코딩(Positional Encoding): Transformer는 순서를 고려하지 않는 모델이므로, 이미지 패치의 위치 정보를 주기 위해 포지셔널 인코딩을 추가합니다. 이를 통해 모델이 패치 간의 순서를 알 수 있습니다.
  4. Transformer Encoder: 각 패치 토큰은 여러 개의 Self-Attention LayerFeed-Forward Layer를 통과하면서 패치 간의 관계를 학습합니다. 여기서 Self-Attention Mechanism이 핵심 역할을 합니다.
  5. 클래스 토큰(Class Token): Transformer의 마지막에는 클래스 토큰이 추가되며, 이 토큰은 모든 패치로부터의 정보를 모아 최종적인 예측을 만듭니다.

ViT의 순전파는 다음과 같이 이루어집니다:

  1. 패치 임베딩과 포지셔널 인코딩:
    • 이미지를 패치로 나누고, 각 패치에 대해 임베딩을 수행한 후 포지셔널 인코딩을 추가합니다.
  2. Self-Attention Mechanism:
    • Self-Attention은 패치 간의 상관관계를 학습하는 과정입니다. 이를 위해 입력 토큰 x1,x2,,xNx1,x2,,xN에 대해, 각각의 패치가 다른 패치와의 관계를 계산합니다.
    • Attention ScoreQuery, Key, Value를 통해 계산됩니다.
    • Attention(Q,K,V)=softmax(QKTdk)VAttention(Q,K,V)=softmax(QKTdk)V
  3. Feed-Forward Layer:
    • Self-Attention을 통해 얻은 정보를 Feed-Forward Network에 통과시켜 각 패치 간의 상관관계를 바탕으로 패치를 변환합니다. 이 과정을 여러 번 반복하여 패치 간 관계를 학습합니다.
  4. 클래스 토큰으로 최종 출력:
    • 마지막에 클래스 토큰이 전체 패치로부터 정보를 통합하여 최종적으로 출력값을 생성합니다. 이 출력값은 분류 작업에 사용됩니다.

ViT에서도 역전파 과정은 CNN이나 ANN과 동일하게 이루어집니다.

  1. 손실 함수:
    • 분류 문제의 경우, 예측값과 실제값 사이의 차이를 계산하기 위해 Cross-Entropy Loss를 사용합니다.
  2. 기울기 계산:
    • Self-Attention LayerFeed-Forward Network의 가중치에 대해 기울기를 계산합니다. Self-Attention에서 사용하는 Query, Key, Value 가중치도 학습 가능한 파라미터이므로, 역전파를 통해 손실 함수에 따라 업데이트됩니다.
  3. 가중치 업데이트:
    • ViT의 모든 학습 가능한 파라미터(패치 임베딩, Self-Attention 가중치, Feed-Forward Network 가중치 등)는 역전파를 통해 업데이트됩니다.

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을 통해 패치 간의 상관관계를 강화하며, 이는 '기억'에 해당하는 중요한 학습 메커니즘입니다.

먼저, 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이 됩니다.

이미지를 패치로 나누었다면, 각 패치를 1차원 벡터로 변환해야 합니다. 예를 들어, 16×16×316×16×3 크기의 패치를 Flatten하여 16×16×3=76816×16×3=768 차원의 벡터로 변환할 수 있습니다. 이 과정을 통해 모든 패치는 하나의 고정된 크기의 벡터로 변환됩니다.

패치를 1차원 벡터로 변환한 후에는 이 벡터를 고차원 임베딩으로 변환해야 합니다. 이를 위해 선형 변환(Linear Projection)을 사용합니다. 선형 변환을 위해 학습 가능한 가중치 행렬 WW를 사용하여, 각 패치 벡터를 고차원 벡터로 변환합니다.

변환 수식은 다음과 같습니다:

zi=Wxizi=Wxi

여기서:

  • xixi: Flatten된 패치 벡터 (차원: 768),
  • WW: 학습 가능한 가중치 행렬 (차원: D×768D×768, DD는 임베딩 차원, 예를 들어 D=768D=768),
  • zizi: 고차원 임베딩 벡터.

따라서, 각 패치 xixiWW와의 선형 변환을 통해 DD-차원의 고차원 벡터 zizi로 변환됩니다. 이렇게 변환된 고차원 임베딩 벡터들은 Transformer의 입력으로 사용됩니다.

  1. RGB 이미지 분할: H×W×CH×W×C 크기의 이미지를 패치 크기 P×PP×P로 분할합니다.
    • 예: 224×224×3224×224×3 이미지를 16×1616×16 패치로 나누면 14×1414×14개의 패치가 생성됩니다.
  2. Flattening: 각 패치 P×P×3P×P×3을 Flatten하여 1차원 벡터로 변환합니다.
    • 예: 16×16×316×16×3 패치를 1차원 벡터 768-차원으로 변환.
  3. Linear Projection: 각 패치 벡터를 선형 변환을 통해 DD-차원의 고차원 벡터로 변환합니다.
    • 예: 768차원 벡터를 D=768D=768 크기의 임베딩 벡터로 변환.
  • 입력 이미지 크기: 224×224×3224×224×3
  • 패치 크기: 16×1616×16
  • 패치 개수: (224/16)×(224/16)=14×14=196(224/16)×(224/16)=14×14=196
  • 각 패치의 차원: 16×16×3=76816×16×3=768
  • 임베딩 차원: D=768D=768

결과적으로, ViT는 196개의 패치로 나뉜 이미지를 입력으로 받아, 각 패치를 768차원 고차원 벡터로 변환하여 Transformer의 입력으로 사용합니다. 이 고차원 벡터들은 Self-Attention을 통해 서로 상호작용하며 학습됩니다.

  • RGB 이미지의 각 패치는 P×P×3P×P×3 크기로 나뉘고, 이를 1차원 벡터로 Flatten한 후 선형 변환을 통해 고차원 임베딩 벡터로 변환됩니다.
  • ViT는 이 패치 임베딩 벡터들을 Transformer의 입력으로 사용하여 패치 간의 상관관계를 학습합니다.

 

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의 가중치 행렬을 통해 고차원 벡터로 변환한다. 이를 선형변환 또는 선형 투영이라고 한다. 

 

zi=Wxizi=Wxi 패치는 1차원 벡터가 되고 가중치 행렬 연산으로 고차원 벡터 z로 변함 

 

Linear ProjectionLinear Transform은 동일한 개념

 

2. Position Embedding

 

각 패치간의 관계를 추출하는 단계 

 

Transformer 모델은 각 패치나 토큰의 순서를 따로 인식하지 않기 때문에, 포지셔널 임베딩(Positional Embedding)이 필요합니다. 이는 패치의 순서 정보를 추가하기 위한 것으로, 각 패치의 임베딩 벡터에 위치 정보를 더해줍니다.

 

포지셔널 임베딩 벡터는 패치의 위치에 따라 미리 정의된 고차원 벡터로, Transformer Encoder에서 학습 가능한 고정된 벡터 또는 사인, 코사인 함수 기반으로 설계될 수 있습니다. ViT에서는 패치의 위치마다 고유한 벡터를 학습하게 됩니다.

 

포지셔널 임베딩(Positional Embedding)을 학습 가능한 파라미터로 처리합니다. 즉, ViT에서 포지셔널 임베딩 pipi는 학습 과정에서 자동으로 학습되며, 별도의 수학적 수식으로 계산되는 것은 아닙니다.

 

코드는 아래와 같이 크기에 맞춰 빈값으로 값이 바뀌도록 학습 가능한 파라미터로 처리한다. 

# 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'_

 

여기서:

  •  $z_i$ 는 패치 임베딩 벡터 (패치의 특징 정보),
  • $p_i$ 는 포지셔널 임베딩 벡터 (패치의 위치 정보),
  • $z'_는 위치 정보가 더해진 최종 패치 임베딩 벡터.

이 덧셈 연산을 통해, 각 패치 벡터는 자신의 위치 정보패치의 특징 정보를 모두 포함하게 됩니다. 이를 통해 Transformer Encoder는 각 패치의 순서를 이해하면서, 패치 간의 관계를 학습할 수 있습니다.

 

4. Transformer Encoder로 입력

이제 위치 정보가 포함된 임베딩 벡터 $z'_Transformer Encoder의 입력으로 들어갑니다. Transformer Encoder는 이 벡터들을 Self-Attention MechanismFeed-Forward Network를 통해 처리하며, 패치 간의 상관관계를 학습하고, 이미지의 글로벌 의존성(global dependency)을 학습하게 됩니다.

 

  1. Multi-Head Self-Attention (MHSA): 입력 패치 간의 관계를 학습하고 상호작용을 계산합니다.
  2. Residual Connection: 입력과 Multi-Head Attention의 출력을 더하여 정보 손실을 방지합니다.
  3. Layer Normalization: Multi-Head Attention의 출력을 정규화하여 학습을 안정화합니다.
  4. Feed-Forward Network (FFN): 각 패치 임베딩에 대해 독립적으로 비선형 변환을 수행합니다.
  5. Residual Connection (두 번째): 입력과 FFN 출력을 더해줍니다.
  6. 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

 

는 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}$$

 

여기서 WO는 최종 선형 변환을 위한 학습 가능한 가중치 행렬이다. 

 

 

 

 

 

4.3  Residual Connection (Skip Connection)

 

4.4 Layer Normalization

 

 

 

https://www.youtube.com/watch?v=MvZ2wzghbCg

 

 

 

https://daebaq27.tistory.com/108

 

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.