2019년 1월 16일 수요일

LSTM 시작


태초에 Recurrent Neural Network(RNN)가 있었다.
Implicit한 temporal dependency를 고려할 수 있어
일반 feed-forward 구조에서는 할 수 없는 것들을
실현가능하게 해줄 수 있을 것 같은 녀석이었다.


수식도 이뻤다.
$$\mathbf z_n^l = \mathbf W^l \mathbf h_n^{l-1} + \mathbf R^l \mathbf h_{n-1}^l + \mathbf b_l$$
$$\mathbf h_n^l = \sigma (\mathbf z_n^l) \quad for \quad 1 \le l \le L$$
여기서 \(\mathbf W\)는 하위층 현재출력, \(\mathbf R\)은 동일층 이전 출력에 대한 weight이다.

하지만 RNN의 초기 모델은 이내 여러 훈련상의 문제점을 드러내고 만다.
Recurrent 정보를 non-linear하게 전달하는 sigmoid가 문제였다.

특정시간 \(n\)에서의 출력에 대해
이전 시간의 동일층 출력에 의한 gradient는
$$\frac{\partial \mathbf h_n^l}{\partial \mathbf h_{n-1}^l}=(\mathbf R^l)^T \sigma'(\mathbf z_n^l)$$$$\frac{\partial \mathbf h_n^l}{\partial \mathbf h_{n-2}^l}=\frac{\partial \mathbf h_n^l}{\partial \mathbf h_{n-1}^l}\frac{\partial \mathbf h_{n-1}^l}{\partial \mathbf h_{n-2}^l}=[(\mathbf R^l)^T \sigma'(\mathbf z_n^l)]\odot [(\mathbf R^l)^T \sigma'(\mathbf z_{n-1}^l)]$$
이 된다.

기본적으로 \(\sigma(\cdot)\)은 좁은 영역에서 gradient를 형성하는 것도 모자라
최대치가 1/4밖에 되지 않는 것이 문제였고

Image result for gradient sigmoid

또한 time step이 멀어지면서 \(\sigma'(\cdot)\)의 효과가 중첩되어
gradient가 기하급수적으로 줄어들기 때문에
원래의 취지와는 다르게 
유연한 temporal dependency를 고려하는 방식으로
network를 훈련할 수 없게 만들기 때문이었다.

이는 learning rate를 훈련이 될 수준으로 설정하면
temporal dependency가 제대로 고려가 안되고 (vanishing gradient problem)
그렇다고 이 문제를 피해보겠다고 learning rate를 무작정 키우면 
훈련 도중 weight가 발산하는 (exploding gradient problem)
문제를 일으켰다.

사람들은 learning rate는 크게 키워 훈련이 잘되도록 하면서도
weight의 크기는 무작정 커지지 않도록 제약을 거는 방법을 생각해냈지만,
맘에 들지 않았다.

그건 왠지 모르게 nice해 보이지 않았다.
연구자들은 억지스러운 것이 싫었다.

그리하여 오랜 고민 끝에 LSTM이 등장하게 되었다.