Transformer

RNN(Recurrent Neural Network)

  • RNN의 장점
    • 가변적인 길이의 Input Sequence를 처리할 수 있음.
    • 입력이 많아져도 모델의 크기는 증가하지 않음.
    • (이론적으로) t 시점에서 수행된 계산은 여러 단계 이전의 정보를 사용할 수 있음.
    • 모든 단계에서 동일한 가중치가 적용됨.
  • RNN의 단점
    • Recurrent computation이 느림.
    • Sequence output inference는 병렬화(parallelization)가 어려움.
    • 바닐라(=기본) RNN은 훈련 중 기울기 소실(vanishing gradient) 문제를 겪음.
    • 바닐라 RNN은 종종 시퀀스 내 장거리 의존성(long-rangedependence)를 모델링 하는데
      실패함.
      • 가장 최근에 들어온 정보 위주로 기억하기 때문에 기존의 정보가 사라지는 문제가 발생
        • 전체 sequence가 길이에 관계 없이 single embedding으로 encoding됨.
        • 따라서, long sequences에서는 informationloss가 불가피함.
        • 이전에 입력된 정보는 더 많이 잊혀지는 경향이 있음.
    • 실제로는 여러 단계 이전의 정보에 접근하기 어려움.



LSTM (Long Short Term Memory)




Seq2seq (Sequence-to-Sequence)

Implementation: Encoder

EncoderLSTM (nn. Module) :
class
def __init__(self, input_size, embedding_size, hidden_size, num_layers, p) :
    super(EncoderLSTM, self).__init__()
    self.input_size = input_size # one-hot input의 길이
    self.embedding_size = embedding_size # input token (word embedding)차원
    self.hidden_size = hidden_size # hidden representation 차원
    self.num_layers = num_layers # LSTM 내 레이어 개수
    self.**dropout** = **nn.Dropout(p)**
    self.embedding = nn.Embedding(self.input_size, self.embedding_size) #벡터화
    self.LSTM = nn.LSTM(self.embedding_size, hidden_size, num_layers, dropout=p)

def forward(self, x):
    # shape: [sequence Length, batch size, embedding dims J
    embedding = self.dropout(self.embedding(x))# x를 embedding 벡터화

    # outputs shape: [sequence length, batch size, hidden_size]
    # hs, cs shape: [num_layers, batch_size, hidden_size]
    outputs, (hidden_state, cell_state) = self.LSTM(embedding)
    # outputs => y1, y2 / hidden_state가 LSTM이기 때문에 cell_state도 같이

    return hidden_state, cell_state
    # seq2seq 모델은 encoder에서 hidden_state만 필요해서 outputs는 리턴하지 않음
  • Dropout

    Dropout은 과적합(overfitting)을 방지하기 위해 사용되는 정규화 기법

    • 학습 과정에서 특정 뉴런에 의존하지 않도록 일부 뉴런을 무작위로 비활성화(즉, 0으로 설정)함으로써 모델의 일반화 능력을 향상시킴

    • Encoder와 Decoder 모두 Dropout을 적용하여 임베딩 벡터에 노이즈를 추가함으로써 과적합을 방지하고, 모델이 더 일반화된 패턴을 학습하도록 함

    • 더 나아가, Encoder와 Decoder 모두에 Dropout을 적용함으로써 임베딩 벡터에 동일한 정규화 기법을 일관되게 적용할 수 있음 → 모델 전체의 성능을 높이는 데 도움

      → 시퀀스를 임베딩 공간으로 전환하는 self.embedding()


Implementation: Decoder

class DecoderLSTM(nn.Module):
    def __init__(self, input_size, embedding_size, hidden_size, num_layers, p, output_size):
         super(DecoderLSTM, self).__init__()
             self.input_size = input_size # one-hot input 의 길이
             self.embedding_size = embedding_size # input token (word embedding) 차원
             self.hidden_size = hidden_size # hidden representation 차원
             self.num_layers = num_layers # LSTM 내 레이어 개수
             self.output_size = output_size # one-hot output 길이 (output language vocab size)
             self.dropout = nn.Dropout(p)
             self.embedding = nn.Embedding(self.input_size, self.embedding_size)
             self.LSTM = nn.LSTM( self.embedding_size, hidden_size, num_layers, dropout = p)
             self.fc = nn.Linear( self.hidden_size, self.output_size)

    def forward(self, x, hidden_state, cell_state):
        x = x.unsqueeze(0) # shape of x: [1, batch_size]
        embedding = self.dropout(self.embedding(x)) # shape: [1, batch size, embedding dims]

 # outputs shape: [1, batch size, hidden_size]
 # hs, cs shape: [num_layers, batch_size, hidden_size] ← hs, cs from Encoder
      outputs, (hidden_state, cell_state) = self.LSTM(embedding, (hidden_state, cell_state))
      predictions = self.fc(outputs) # shape: [1, batch_size, output_size]
      predictions = predictions.squeeze(0) # shape: [batch_size, output_size]

      return predictions, hidden_state, cell_state

Implementation: Seq2seq Interface

 class Seq2Seq(nn.Module):
     def __init__(self, Encoder_LSTM, Decoder_LSTM):
         super(Seq2Seq, self).__init__()
         self.Encoder_LSTM = Encoder_LSTM
         self.Decoder_LSTM = Decoder_LSTM

     def forward(self, source, target):
         batch_size = source.shape[1] # source shape: [input language seq len, num_sentences]
         # num_sentences = 한 배치(batch) 안에 있는 문장의 개수, 즉 배치 크기(batch size)를 나타냄
         target_len = target.shape[0] # target shape: [output language seq len, num_sentences]
         target_vocab_size = len(english.vocab)

         outputs = torch.zeros(target_len, batch_size, target_vocab_size)
         hs, cs = self.Encoder_LSTM(source)
         #hs = hidden state, cs = cell state

         x = target[0] # Trigger token <SOS>; shape: [batch_size]
         # SOS token = Start Of Sentence

 for i in range(1, target_len):
         output, hs, cs = self.Decoder_LSTM(x, hs, cs)
         outputs[i] = output
         x = output.argmax(1)
 return outputs # shape: [output language seq len, batch_size, target_vocab_size]




Attention

  • Attention 함수: Attention (Q, K, V) = Attention 값
    query(context)와 key-valuepairs(references)가 입력되면, attention 값은 value들의 가중치 평균이며, 여기서 각 weight는 relevance query와 corresponding key 간의 관련성에 비례함.
  • Q와 K는 비교 가능해야 함. (일반적으로 동일한 dimensionality를 가짐)
  • V와 Attention value는 당연하게도 동일한 dimensionality를 가져야 함. (V와 Q&K는 달라도 OK)
  • 많은 응용 사례에서 이 4가지 요소는 모두 동일한 dimensionality를 가짐.

Attention Is All You Need 논문 참고



'Study - AI > Machine Learning' 카테고리의 다른 글

선형 대수  (0) 2025.01.06
Machine Learning Life Cycle  (0) 2025.01.06