seq2seq
트랜스포머의 self-attention 과정에서 막혀서 이에 기반이 되는 seq2seq를 읽어볼 필요성을 느끼게 되어서 논문 리뷰를 하게 됩니다. 논문의 원제목은 Convolutional Sequence to Sequence Learning 이며 총 15page 분량의 논문입니다.
Abstract
PROB : 기존의sequence-to-sequence 학습 방식은 RNN을 통해 가변 길이 출력 시퀀스를 매핑합니다.
seq-2-seq를 보면 입력 시퀀스(문장 등) (그리고 sequence는 연속된 요소들의 나열임로 정의됨), 출력 시퀀스로 변환하는 학습 방법입니다.
그래서 이걸 RNN으로 구현한 ( Transformer 이전)초 초기 모델은 입력 시퀀스의 길이와 출력 시퀀스의 길이를 다르게 처리할 수 있었으며 이를 바로 매핑이라 합니다.
예시
입력 : I want to go to school
출력 : 나는 학교에 가고 싶다.
이 두 문장의 개수가 다르므로 가변 길이 출력입니다. 시퀀스의 각 단어가 순서대로 입력되고, 그걸 기반으로 또 하나의 시퀀스를 생성해야 하므로 이걸 seq-to-seq라고 하며 RNN을 통해 이걸 처리하는 방식이 과거에 널리 쓰였습니다.
SOL : 이걸 CNN으로 기반한 아키텍쳐를 새롭게 제안한 것이 바로 seq2seq입니다.
훈련 시 모든 요소에 대한 계산을 완전히 병렬화할 수 있으며 GPU 하드웨어의 효율을 극대화할 수 있습니다. 또한 비선형성의 수가 입력 길이에 무관하게 고정되어 최적화가 더 쉬워집니다. GLU(Gated Linear Unit)을 사용하여 기울기의 전달을 용이하게 하였고, 각 디코더 레이어마다 별도의 어텐션 모듈을 장착했습니다. LSTM보다 정확도가 더 높고 GPU와 CPU 모두 빠른 성능을 보입니다.
Introduction
Sequence-to-sequence 학습은 음성 인식, 텍스트 번역 등 다양한 작업에서 성공적으로 활용되어 왔다. 기존 접근 방식은 양방향 RNN을 통해 입력 시퀀스를 인코딩하고, 디코더 RNN으로 출력 시퀀스를 생성한 뒤, 양쪽을 soft-attention 메커니즘(softmax를 통한 attention score 계산)을 통해 연결하는 구조였다.
하지만 합성곱 신경망(CNN)은 시퀀스 모델링에서 상대적으로 덜 사용되어 왔다. CNN은 고정 크기 컨텍스트만 처리할 수 있지만,여러 층을 쌓으면 더 긴 의존성도 포착 가능하며, 이전 타임스텝의 계산에 의존하지 않아 병렬 처리가 가능하다는 장점이 있다.
논문에서는 완전한 합성곱 기반의 sequence-to-sequence 모델을 제안한다. 이 모델은 Gated Linear Unit(GLU)과 Residual Connection을 도입하고, 디코더의 각 층마다 효율적인 attention 모듈을 적용하여 계산량을 거의 증가시키지 않으면서도 정밀한 정보 선택을 가능하게 한다. 이러한 설계를 통해 대규모 시퀀스 변환 문제를 빠르고 효과적으로 처리할 수 있다
Recurrent Sequence to Sequence Learning
seq2seq는 RNN 기반 인코더-디코어 구조와 동일 사용
인코더는 입력 문장을 읽고 내부 표현을 만들고, 디코더는 이를 기반으로 단어를 하나씩 생성함, 디코더는 단허 하나 예측할 때마다 이전 상태, 이전 단어, 인코더 정보를 이용해 새로운 상태를 계산
인코더 RNN - m의 입력 시퀀스 x = (x1 x2 ... xm)를 처리하여 상태 표현 z = (z1, z2 , ... , zm)을 생성
디코더 RNN - z를 입력으로 받아 출력 시퀀스 y = (y1, ... , yn)을 왼쪽에서 오른쪽으로 생성
yi+1을 생성하기 위해, 디코더는 이전 상태 hi, 이전에 생성된 단어 yi의 임베딩 gi, 그리고 인코더 출력 z에 조건된 입력 ci를 바탕으로 은닉 상태 hi+1을 계산, 이러한 구조를 바탕으로 인코더-디코더 모델 제안, 조건 입력 ci의 정의 방식과 사용되는 RNN의 유형에서 차이를 보입니다.
인코더 디코더 구조로 흔히 사용되는 순환 신경망은 lstm과 gru가 있음
게이팅 매커니즘을 통해 과거 시점 정보 기억, 장기 의존성을 효과적으로 학습 양방향 인코더를 활용하여 과거 문맥과 현재 문맥 잔차 연결, 단축 연결로 학습 안정성 및 성능 향상시킴
Convolutional Architecture
중간 인코더 상태 z와 디코더 상태 h를 계산하기 위해 기존에는 RNN을 사용했지만, 본 논문에서는 이러한 순차적 계산 대신, CN 을 이용하여 입력과 출력을 처리하는 완전한 합성곱 기반 시퀀스-투-시퀀스 구조를 제안한다.
Positional Embeddings
단어의 위치 정보(position)를 벡터로 만들어서, 단어 임베딩에 더해주는 방식으로 모델에 순서 감각을 부여 하는 기법
CNN은 순서를 내재적으로 처리하지 못하기 때문에, 단어의 위치 정보를 명시적으로 부여할 필요가 있다. 이를 위해 위치 임베딩(Positional Embedding)을 도입한다.
입력 시퀀스 x = (x₁, ..., xₘ)의 각 요소는 분포 표현 공간(distributional space)에 임베딩되어 w = (w₁, ..., wₘ)으로 변환된다. 여기서 각 wⱼ는 차원 f의 벡터이며, 임베딩 행렬 D ∈ ℝ^(V×f)의 열 벡터 중 하나이다. 이와 함께, 각 입력 요소의 절대 위치를 나타내는 위치 벡터 p = (p₁, ..., pₘ)를 학습된 임베딩으로 표현한다. 각 pⱼ 역시 차원 f의 벡터이다.
이 두 정보를 더하여, 최종 입력 표현을 e = (w₁ + p₁, w₂ + p₂, ..., wₘ + pₘ)로 구성한다.
디코더가 이미 생성한 출력 요소들에 대해서도 같은 방식으로 처리하여 g = (g₁, ..., gₙ) 형태의 출력 임베딩을 만들고, 이를 디코더에 다시 입력으로 사용한다. 위치 임베딩은 모델이 입력 또는 출력 시퀀스의 어느 위치를 처리 중인지 인식할 수 있게 해주며, 합성곱 구조에서는 필수적인 순서 정보로 작용한다.
Convolutional Block Structure
CNN 모델에서는 인코더/디코더는 여러 개의 블록으로 구성되며, 각 블록은
- 1D convolution -> 문맥 정보 추출
- 비선형 함수(GLU 등) -> 패턴 강조 or 선택적 정보 필터링
수용 영역 (Receptive Field) 확장
인코더와 디코더 네트워크는 모두 고정된 개수의 입력 요소를 기반으로 중간 상태를 계산하는 단순한 블록 구조를 공유합니다.
디코더 h와 인코더 z로 나타내며, 블록과 레이어는 동일한 의미로 사용 각 블록은 1차원 합성곱 연산과 그 뒤에 비선형 활성화 함수로 구성
ex)
커널 너비가 k인 디코더 블록 하나를 사용할 경우 출력 상태 hl i 는 k개의 입력 요소에 대한 정보를 포함하게 됩니다. 여러 개의 블록을 쌓으면 더 많은 입력 요소를 반영하게 됩니다. 즉 커널 너비가 k = 5인 블록을 6개 쌓으면, 하나의 출력에는 최대 25개의 입력 요소에 기반하게 됩니다.
- CNN은 한 블록에서 고정된 범위(k개)의 단어를 봅니다.
- 블록이 여러 층 쌓이면 -> Receptive Field가 넓어짐
- R = 1 + (k -1) * L
W ∈ ℝ^(2d × kd) : 학습 파라미터
b ∈ ℝ^(2d) : 편향
입력 X ∈ ℝ^(k × d) : k개의 입력을 d차원 벡터로 임베딩해 연결한 것
출력 Y ∈ ℝ^(2d) : 2배 차원의 출력 생성
5개의 입력, 각 입력은 256 차원으로 이걸 합성곱해서 2배인 512차원으로 변환합니다. 이것의 원인은 바로GLU 때문입니다.
GLU ( 비선형 함수 )
비선형 함수로 Gated Linear Unit을 사용합니다. GLU는 합성곱 출력 Y = [A B] ∈ ℝ^(2d)를 두 부분(A, B)으로 나눕니다. 최중 출력은 다음과 같이 계산됩니다.
v([A,B])=A⊗σ(B)
여기서 ⊗는 원소별 곱, σ는 시그모이드 함수, 결과는 ℝ^d
σ(B)는 어떤 A의 정보가 중요한지를 제어한다
- A = 정보내용, B = 게이트 (필터 역할)
- 게이트가 1이면 A 그대로 통과, 0이면 차단 -> selective 정보 전달
- tanh보다 더 안정적이고 효과적임
Residual Connection
깊은 네트워크 학습이 어려우면서 입력을 직접 출력에 더하면서 학습 안정화
패딩
인코더에서 출력 길이 = 입력 길이를 유지하기 위해서 매 블록마다 zero패딩 적용, 디코더에서는 미래 단어 정보를 사용하지 않도록 주의, 좌우 (k-1)개의 0벡터 패딩한 후, 출력의 마지막 k개 요소 제거
임베딩 크기 정함 - 선형 변환 추가, 최종 softmax 계산
Causal 구조로 만들어야 함 ➡ 이를 위해 좌우 패딩을 추가한 뒤, 뒤쪽 일부를 잘라냅니다
방법
- 입력 앞뒤로 k−1k - 1개의 zero-padding 추가
(예: 커널 k=3이면, 앞뒤로 2개씩) - Convolution 수행 → 이 때 CNN은 전체를 볼 수 있지만...
- 출력의 마지막 k개는 삭제(remove)
➡ 이렇게 하면 CNN은 현재와 과거까지만 보게 됨
원래 입력: x₁ x₂ x₃ x₄ x₅
패딩 후 입력: 0 0 x₁ x₂ x₃ x₄ x₅ 0 0
CNN 출력: y₁ y₂ y₃ y₄ y₅ y₆ y₇
→ 마지막 2개 제거
최종 출력: y₁ y₂ y₃ y₄ y₅
Multi-step Attention
디코더의 각 레이어마다 별도의 어텐션 매커니즘 도입
어텐션을 계산하려면 현재 디코더 상태와 이전 출력 단어의 임베딩을 사용
어텐션 점수 계산 방식 (Scaled Dot Product)
컨텍스트 벡터 계산