BPTT와 TBPTT

RNN을 시간 축으로 펼쳐 역전파하는 BPTT와, 긴 시퀀스를 잘라 부분적으로 역전파하는 TBPTT를 정리한다.

BPTT(Backpropagation Through Time)#

RNN은 시퀀스를 따라 forward를 진행하면서 각 타임스텝마다 출력과 Loss를 만든다. Loss는 forward 과정에서 진행한 Sequence 만큼, 모든 구간 Loss의 총합이다.

여기서 헷갈렸던 부분이 있다. 한 토큰씩 예측하는 동시에 그때그때 역전파를 하는 게 아니라, 역전파는 문장이 다 끝나면 진행된다. 이때의 Loss가 각 구간 Loss의 총합인 것이다. 즉 forward로 전체 시퀀스의 Loss를 다 모은 뒤에 한 번에 거꾸로 흘려보낸다.

문제는 구간이 길어질수록 두 가지가 같이 커진다는 것이다. 하나는 기울기 소실 문제의 발생 가능성이고(자세한 이유는 RNN과 기울기 소실, 폭발), 다른 하나는 필요한 하드웨어 리소스다. 전체 시퀀스를 펼친 채로 역전파해야 하니 시퀀스가 길수록 메모리 부담이 커진다.

TBPTT(Truncated BPTT)#

TBPTT는 전체 Sequence를 한 번에 backprop하지 않고, 구간을 Chunk로 나눠 부분 BPTT를 진행하는 방식이다.

핵심은 forward와 backward를 다르게 다룬다는 데 있다.

  • Forward는 그대로 이어서 진행한다. Hidden state 값은 이전 Chunk로부터 계속 전달받아야 한다. 구체적으로 이전 Chunk의 마지막 hidden state 는 다음 Chunk에서 마치 처럼 사용된다.
  • Backward는 Chunk 단위로만 진행한다. 그래서 한 번에 펼치는 길이가 Chunk 크기로 제한되고, 계산량과 메모리를 줄일 수 있다.

정리#

  • BPTT는 forward로 전체 시퀀스의 Loss(각 구간 Loss의 총합)를 모은 뒤, 문장이 끝나면 한 번에 역전파한다. 시퀀스가 길수록 기울기 소실과 리소스 부담이 커진다.
  • TBPTT는 시퀀스를 Chunk로 나눠 Chunk 안에서만 역전파한다. Forward는 hidden state를 이어받아 계속 진행하고(이전 Chunk의 마지막 가 다음 Chunk의 역할), 그래서 계산량을 줄인다.

댓글