Seq2Seq(Sequence-to-Sequence)

임정민·2024년 10월 13일
1

딥러닝 개념

목록 보기
11/13
post-thumbnail

*본 게시글은 유튜브 '신박Ai' [Deep Learning 101] 시퀀스-투-시퀀스, Seq2seq 모델을 소개합니다
자료를 참고한 점임을 알립니다.

Seq2Seq의 등장 배경 및 개요

Seq2Seq 모델은 입력 시퀀스를 다른 형태의 출력 시퀀스로 변환하는 문제를 해결하기 위해 개발된 딥러닝 아키텍처입니다. 주로 기계 번역, 텍스트 요약, 음성 인식, 이미지 캡션 생성 등에서 사용됩니다. Seq2Seq는 RNN의 변형인 LSTM 또는 GRU와 같은 구조를 사용하며, 인코더와 디코더라는 두 개의 네트워크로 구성됩니다.

Seq2Seq 모델의 핵심 아이디어는 'context vector'입니다. 이는 인코더의 마지막 hidden state로, 입력 시퀀스의 전체 정보를 압축하여 담고 있습니다. 이 context vector는 디코더의 초기 상태로 사용되어, 입력 시퀀스의 정보를 출력 생성 과정에 전달하는 역할을 합니다.

Seq2Seq 모델 구조(LSTM with Peephole Connections 기반 수식 전개)

Seq2Seq 모델의 인코더와 디코더는 LSTM with peephole connections 셀로 구성됩니다. 이 구조는 표준 LSTM에 비해 더 정확한 타이밍 학습이 가능하며, 시계열 데이터나 시간에 민감한 패턴을 학습하는 데 유용합니다.

인코더(Encoder)

인코더는 입력 시퀀스 X=(x1,x2,,xT)X=(x_1,x_2,…,x_T)를 받아들여, LSTM 셀을 사용해 숨겨진 상태 hth_t와 셀 상태 ctc_t를 업데이트합니다.

(1) Forget Gate
Forget Gate는 이전 타임스텝의 셀 상태에서 얼마나 잊을지를 결정합니다.

ft=σ(Wxfxt+Whfht1+Wcfct1+bf)f_t = \sigma(W_{xf}x_t + W_{hf}h_{t-1} + W_{cf}c_{t-1} + b_f)
(ft:Forget 게이트의 출력값)(f_t: \text{Forget 게이트의 출력값})
(xt:현재 입력)(x_t: \text{현재 입력})
(ht1:이전 타임스텝의 숨겨진 상태)(h_{t-1}: \text{이전 타임스텝의 숨겨진 상태})
(ct1:이전 타임스텝의 셀 상태)(c_{t-1}: \text{이전 타임스텝의 셀 상태})
(Wxf,Whf,Wcf:각각 입력, 숨겨진 상태, 셀 상태에 대한 가중치 행렬)(W_{xf}, W_{hf}, W_{cf}: \text{각각 입력, 숨겨진 상태, 셀 상태에 대한 가중치 행렬})
(bf:Forget 게이트의 편향)(b_f: \text{Forget 게이트의 편향})
(σ:시그모이드 함수)(\sigma: \text{시그모이드 함수})

(2) Input Gate & Candidate Cell State
Input Gate는 얼마나 새로운 정보를 받아들일지 결정하며, 새로운 셀 상태의 후보를 계산합니다.

it=σ(Wxixt+Whiht1+Wcict1+bi)i_t = \sigma(W_{xi}x_t + W_{hi}h_{t-1} + W_{ci}c_{t-1} + b_i)
c~t=tanh(Wxcxt+Whcht1+bc)\tilde{c}_t = \tanh(W_{xc}x_t + W_{hc}h_{t-1} + b_c)
(it:Input 게이트의 출력값)(i_t: \text{Input 게이트의 출력값})
(c~t:새로운 셀 상태의 후보값)(\tilde{c}_t: \text{새로운 셀 상태의 후보값})
(tanh:하이퍼볼릭 탄젠트 함수)(\tanh: \text{하이퍼볼릭 탄젠트 함수})
(Wxi,Whi,Wci,Wxc,Whc:가중치 행렬들)(W_{xi}, W_{hi}, W_{ci}, W_{xc}, W_{hc}: \text{가중치 행렬들})
(bi,bc:편향)(b_i, b_c: \text{편향})

(3) 셀 상태 업데이트
Forget Gate와 Input Gate의 값을 사용하여 새로운 셀 상태 ctc_t를 업데이트합니다.

ct=ftct1+itc~tc_t = f_t \odot c_{t-1} + i_t \odot \tilde{c}_t
(ct:현재 타임스텝의 셀 상태)(c_t: \text{현재 타임스텝의 셀 상태})
(:요소별 곱셈 (Hadamard product))(\odot: \text{요소별 곱셈 (Hadamard product)})

(4) Output Gate & 숨겨진 상태
Output Gate는 현재 타임스텝의 숨겨진 상태 hth_t를 계산합니다.

ot=σ(Wxoxt+Whoht1+Wcoct+bo)o_t = \sigma(W_{xo}x_t + W_{ho}h_{t-1} + W_{co}c_t + b_o)
ht=ottanh(ct)h_t = o_t \odot \tanh(c_t)
(ot:Output 게이트의 출력값)(o_t: \text{Output 게이트의 출력값})
(ht:현재 타임스텝의 숨겨진 상태)(h_t: \text{현재 타임스텝의 숨겨진 상태})

디코더(Decoder)

디코더는 인코더로부터 전달받은 hTh_TcTc_T를 초기 상태로 받아 출력 시퀀스를 생성합니다. 디코더는 인코더와 동일한 LSTM 셀을 사용하며, 입력 시퀀스로는 이전 출력값 yt1y_{t-1} 또는 시작 토큰을 사용하여 새로운 출력 yty_t를 생성합니다.

디코더의 LSTM 셀 수식은 인코더와 유사하지만, 입력으로 이전 출력 yt1y_{t-1}을 사용합니다.

Seq2Seq의 특징

인코더-디코더 구조

Seq2Seq 모델의 핵심은 인코더-디코더 구조입니다. 이 구조는 다음과 같은 특징을 가집니다.

인코더

입력 시퀀스 X=(x1,x2,...,xT)X = (x_1, x_2, ..., x_T)를 고정 길이 벡터 cc로 압축합니다.

ht=f(xt,ht1)h_t = f(x_t, h_{t-1})
c=q(h1,...,hT)c = q({h_1, ..., h_T})

여기서 hth_t는 시간 tt에서의 hidden state, ffqq는 비선형 함수입니다.

디코더

압축된 벡터 cc를 기반으로 출력 시퀀스 Y=(y1,y2,...,yT)Y = (y_1, y_2, ..., y_{T'})를 생성합니다.

p(yty1,...,yt1,c)=g(yt1,st,c)p(y_t | {y_1, ..., y_{t-1}}, c) = g(y_{t-1}, s_t, c)

여기서 sts_t는 디코더의 hidden state, gg는 비선형 함수입니다.

컨텍스트 벡터 (Context Vector)

컨텍스트 벡터 cc는 Seq2Seq 모델에서 인코더와 디코더를 연결하는 핵심 요소입니다. 이 벡터는 입력 시퀀스의 전체 정보를 압축하여 담고 있습니다. 컨텍스트 벡터는 두 가지 방식으로 생성될 수 있습니다.

(1) 인코더의 마지막 hidden state를 사용: 이 경우, 컨텍스트 벡터는 입력 시퀀스의 마지막 정보에 더 큰 가중치를 둡니다.

(2) 모든 hidden state의 함수로 표현: 이 방식은 입력 시퀀스의 모든 부분에 대한 정보를 균형 있게 반영할 수 있습니다.

컨텍스트 벡터는 디코더가 출력 시퀀스를 생성할 때 참조하는 "요약본" 역할을 합니다.

Seq2Seq 모델에서의 가변 길이 입출력 처리

Seq2Seq 모델의 큰 장점 중 하나는 입력과 출력의 길이가 서로 다른 경우에도 잘 작동한다는 것입니다. 예를 들어, 짧은 문장을 긴 문장으로 번역하거나, 긴 문서를 짧게 요약할 수 있습니다.

p(YX)=t=1Tp(yty1,...,yt1,c)p(Y|X) = \prod_{t=1}^{T'} p(y_t | {y_1, ..., y_{t-1}}, c)
(p(YX):입력 시퀀스 X가 주어졌을 때 출력 시퀀스 Y의 확률)(p(Y|X): 입력\ 시퀀스\ X가\ 주어졌을\ 때\ 출력\ 시퀀스\ Y의\ 확률)
(t=1T:출력 시퀀스의 각 요소에 대한 확률의 곱)(\prod_{t=1}^{T'}: 출력\ 시퀀스의\ 각\ 요소에\ 대한\ 확률의\ 곱)
(p(yty1,...,yt1,c):이전에 생성된 출력과 컨텍스트 벡터를 고려한 현재 출력의 확률)(p(y_t | {y_1, ..., y_{t-1}}, c): 이전에\ 생성된\ 출력과\ 컨텍스트\ 벡터를\ 고려한\ 현재\ 출력의\ 확률)

이 수식은 출력 시퀀스의 각 요소가 이전에 생성된 모든 요소와 입력 시퀀스의 정보(컨텍스트 벡터)에 의존함을 나타냅니다.

학습 과정

Seq2Seq 모델의 학습 목표는 주어진 입력에 대해 올바른 출력을 생성할 확률을 최대화하는 것입니다. 이는 다음 수식으로 표현됩니다:

maxθ1Ni=1Nlogpθ(Y(i)X(i))\max_\theta \frac{1}{N} \sum_{i=1}^N \log p_\theta(Y^{(i)}|X^{(i)})
(θ:모델의 모든 학습 가능한 파라미터 (가중치와 편향))(\theta: 모델의\ 모든\ 학습\ 가능한\ 파라미터\ (가중치와\ 편향))
(N:학습 데이터셋의 총 샘플 수)(N: 학습\ 데이터셋의\ 총\ 샘플\ 수)
(X(i),Y(i):i번째 학습 샘플의 입력과 정답 출력)(X^{(i)}, Y^{(i)}: i번째\ 학습\ 샘플의\ 입력과\ 정답\ 출력)
(pθ(Y(i)X(i)):모델 파라미터 θ를 사용하여 입력 X(i)가 주어졌을 때 정답 출력 Y(i)를 생성할 확률)(p_\theta(Y^{(i)}|X^{(i)}): 모델\ 파라미터\ \theta를\ 사용하여\ 입력\ X^{(i)}가\ 주어졌을\ 때\ 정답\ 출력\ Y^{(i)}를\ 생성할\ 확률)

이 목적 함수는 로그 가능도(log-likelihood)의 평균을 최대화하는 것으로, 모델이 정답에 가까운 출력을 생성하도록 학습됩니다.

Attention 메커니즘

Attention 메커니즘은 디코더가 출력을 생성할 때 입력 시퀀스의 어떤 부분에 집중해야 할지 결정하는 방법입니다. 이는 긴 입력 시퀀스를 처리할 때 특히 유용합니다.

Attention 가중치 계산:

eij=a(si1,hj)e_{ij} = a(s_{i-1}, h_j)
αij=exp(eij)k=1Texp(eik)\alpha_{ij} = \frac{\exp(e_{ij})}{\sum_{k=1}^T \exp(e_{ik})}
(eij:디코더의 i번째 스텝에서 인코더의 j번째 hidden state와의 연관성 점수)(e_{ij}: 디코더의\ i번째\ 스텝에서\ 인코더의\ j번째\ hidden\ state와의\ 연관성\ 점수)
(a:alignment model (연관성을 측정하는 함수, 주로 신경망으로 구현))(a: alignment\ model\ (연관성을\ 측정하는\ 함수,\ 주로\ 신경망으로\ 구현))
(si1:디코더의 이전 hidden state)(s_{i-1}: 디코더의\ 이전\ hidden\ state)
(hj:인코더의 j번째 hidden state)(h_j: 인코더의\ j번째\ hidden\ state)
(αij:정규화된 attention 가중치 (모든 가중치의 합이 1이 되도록 함))(\alpha_{ij}: 정규화된\ attention\ 가중치\ (모든\ 가중치의\ 합이\ 1이\ 되도록\ 함))

컨텍스트 벡터 계산:

ci=j=1Tαijhjc_i = \sum_{j=1}^T \alpha_{ij} h_j
(ci:i번째 디코딩 스텝에서의 컨텍스트 벡터)(c_i: i번째\ 디코딩\ 스텝에서의\ 컨텍스트\ 벡터)
(T:입력 시퀀스의 길이)(T: 입력\ 시퀀스의\ 길이)

Teacher Forcing

Teacher Forcing은 Seq2Seq 모델의 학습을 가속화하는 기법입니다.
학습 시:

yt=g(yt1,st,c)y_t = g(y_{t-1}^*, s_t, c)

추론 시:

yt=g(y^t1,st,c)y_t = g(\hat{y}_{t-1}, s_t, c)
(g:디코더 함수)(g: 디코더\ 함수)
(yt:현재 시간 스텝의 출력)(y_t: 현재\ 시간\ 스텝의\ 출력)
(yt1:실제 정답의 이전 출력 (학습 시 사용))(y_{t-1}^*: 실제\ 정답의\ 이전\ 출력\ (학습\ 시\ 사용))
(y^t1:모델이 생성한 이전 출력 (추론 시 사용))(\hat{y}_{t-1}: 모델이\ 생성한\ 이전\ 출력\ (추론\ 시\ 사용))
(st:현재 디코더의 hidden state)(s_t: 현재\ 디코더의\ hidden\ state)
(c:컨텍스트 벡터)(c: 컨텍스트\ 벡터)

학습 시에는 이전 시간 스텝의 정답 출력을 다음 입력으로 사용하여 학습 속도를 높이고 안정성을 개선합니다. 그러나 이로 인해 학습과 추론 시의 불일치가 발생할 수 있습니다.

양방향 RNN (Bidirectional RNN)

양방향 RNN은 입력 시퀀스를 양방향으로 처리하여 더 풍부한 문맥 정보를 캡처합니다.

ht=f(xt,ht1)\overrightarrow{h_t} = f(x_t, \overrightarrow{h_{t-1}})
ht=f(xt,ht+1)\overleftarrow{h_t} = f(x_t, \overleftarrow{h_{t+1}})
ht=[ht;ht]h_t = [\overrightarrow{h_t}; \overleftarrow{h_t}]
(ht:정방향 RNN의 hidden state)(\overrightarrow{h_t}: 정방향\ RNN의\ hidden\ state)
(ht:역방향 RNN의 hidden state)(\overleftarrow{h_t}: 역방향\ RNN의\ hidden\ state)
(xt:t번째 입력)(x_t: t번째\ 입력)
(f:RNN 셀 함수 (: LSTM, GRU))(f: RNN\ 셀\ 함수\ (예:\ LSTM,\ GRU))
(ht:최종 hidden state (정방향과 역방향 결합))(h_t: 최종\ hidden\ state\ (정방향과\ 역방향\ 결합))

양방향 RNN을 사용함으로써, 모델은 각 입력 요소에 대해 과거와 미래의 문맥을 모두 고려할 수 있게 됩니다.

profile
https://github.com/min731

0개의 댓글

관련 채용 정보