ResNet에서 LSTM까지

LSTM이 RNN의 기울기 문제를 어떻게 우회하는지를, ResNet의 skip connection에서 Highway network를 거쳐 LSTM에 이르는 흐름으로 따라간다. 마지막에는 nn.LSTM으로 양방향 RNN을 쓰는 법까지 정리한다.

ResNet의 skip connection#

가장 기본적인 skip connection은 입력 와 변환 결과 를 더하는 것이다.

덧셈으로 입력을 그대로 흘려보내는 경로를 두면, 역전파에서 gradient가 그 경로를 따라 손실 없이 전달된다.

Highway network: 가중치를 학습한다#

여기서 한 발 더 나아가면, 를 단순히 더하는 대신 가중 평균(weighted average)으로 섞을 수 있다.

가중치의 합이 1인 가중 평균이고, 이때 는 학습 가능한 파라미터다. 에 가중치를 둠으로써 어느 쪽에 더 중요성을 둘 것인가를 나타낼 수 있다.

단순 스칼라 값이던 가 입력의 차원과 동일한 matrix 형태가 되면, 차원마다 동적으로 가중치를 부여할 수 있다. 이 matrix를 라 하고, 에 sigmoid를 씌운 레이어를 라고 부른다.

여기서 하나가 의 가중치를 함께 묶어 조절하고 있었는데, 라는 레이어를 따로 두면 둘을 독립적으로 조절할 수 있다.

이제 는 출력 를, 는 입력 를 각각 독립적으로 조절한다.

LSTM: Cell state라는 highway#

LSTM은 RNN의 vanishing, exploding 문제를 ResNet의 skip connection과 비슷한 방법으로 접근한다. 가장 중요한 부분은 덧셈을 이용한다는 것이다.

LSTM에는 Cell state가 highway 역할을 한다. LSTM의 계산 결과물이 이 Cell state에 어떤 정보를 지우고 어떤 정보를 추가할지를 결정한다(지우고 더하는 것은 element-wise 곱셈으로).

핵심 아이디어는, Cell state 정보를 어떠한 왜곡 없이 전달할 수 있는 능력을 가진다는 것이다. 이를 통해 장기 기억 문제(long-term dependency)를 해결한다. Cell state의 갱신이 곱셈이 아니라 덧셈()을 거치기 때문에, 역전파에서 gradient가 그대로 흘러 멀리까지 전달된다.

LSTM의 gate 구성#

LSTM의 계산 결과물은 hidden state를 4개의 단위로 쪼갠 것이고, 모두 동일한 사이즈다.

  • Forget gate: 이전 Cell에서 받은 내용을 얼마나 지울 것인가
  • Input gate: Cell의 내용을 얼마나 업데이트할 것인가
  • 적을 내용(function output): Cell에 새로 적을 내용
  • Output gate: Cell의 내용을 다음 출력 층과 hidden state로 얼마나 반영할 것인가

Cell state의 갱신은 forget gate가 이전 Cell state를 조절하고, input gate가 현재 타임스텝에서 계산한 내용을 조절하는 형태다.

여기서 (forget), (input)는 sigmoid, (적을 내용)는 tanh를 거친 값이고, 는 element-wise 곱셈이다. 그리고 output gate가 갱신된 Cell state를 hidden state로 내보낸다.

nn.LSTM으로 양방향 RNN 쓰기#

nn.LSTM을 bidirectional로 쓰면, 출력에서 정방향과 역방향을 분리해 합쳐줘야 한다.

# 양방향의 경우 마지막 레이어의 양쪽 방향 출력을 연결
if model.bidirectional:
    last_output = torch.cat((output[:, -1, :model.hidden_size],
                             output[:, 0, model.hidden_size:]), dim=1)
else:
    last_output = output[:, -1, :]

여기서 -1은 시퀀스의 마지막, 0은 시퀀스의 처음을 의미한다. bidirectional이 켜져 있으면 output의 마지막 dim은 정방향 hidden_size와 역방향 hidden_size 두 개를 이어 붙여 가진다. 정방향 RNN의 최종 결과는 시퀀스의 마지막 위치(-1)의 앞쪽 hidden_size이고, 역방향 RNN은 시퀀스를 거꾸로 처리하므로 그 최종 결과가 시퀀스의 처음 위치(0)의 뒤쪽 hidden_size에 있다. 그래서 둘을 분리해서 concat 해준다.

정리#

  • ResNet skip connection 는 덧셈 경로로 gradient를 그대로 흘린다.
  • Highway network는 이를 학습 가능한 가중치 로 일반화해 의 비중을 동적으로 조절한다.
  • LSTM은 Cell state를 highway로 두고, forget/input/적을 내용/output gate로 정보를 지우고 더한다. 갱신이 덧셈이라 gradient가 멀리 전달되어 장기 의존성을 해결한다.
  • nn.LSTM을 양방향으로 쓰면 정방향(마지막 위치 앞쪽)과 역방향(처음 위치 뒤쪽) 출력을 분리해 concat한다.

댓글