7.3. RNN
시간적으로 연속성이 있는 데이터 = 시계열 데이터를 처리하는 기초 모델. Recurrent NN.
다른 딥러닝 모델처럼 여러 층으로 되어있는 것은 똑같으나, 모든 층에서 입력을 받으며, 한 층의 출력 값은 이전 층의 출력값과 현재 층의 입력값의 영향을 받는다.
= 이전까지의 입력 데이터를 요약한 정보를 받아, 새로운 정보와 함께 갱신한다 -> 최종 출력값은 모든 입력을 요약한 정보가 됨
RNN 종류
- 일대일 - 순환이 없음, 순방향 네트워크
- 일대다 - 입력은 하나, 출력은 다수, 이미지 캡션 같은거.
- 다대일 - 입력은 다수, 출력은 하나, 문장을 입력해 긍정/부정을 판별하는 감성분석 같은거.
- 다대다 - 입력도 출력도 다수, 번역기 같은거.
- 동기화 다대다 - 다대다인데, 입력 중이더라도 모든 각각의 층은 출력값을 가진다.
다대일 RNN 구현 예시
self.em = nn.Embedding(len(TEXT.vocab.stoi), embedding_dim)
self.rnn = nn.RNNCell(input_dim, hidden_size)
self.fc1 = nn.Linear(hidden_size, 256)
self.fc2 = nn.Linear(256, 3)
3단계의 다대일 RNN.
다대다 RNN의 경우 텐서플로우는 return_sequence 옵션을 True로 설정하면 손쉽게 쓸 수 있지만, 파이토치는 그냥 seq2seq를 하나 만드는 게 훨씬 낫다.
7.3.1. RNN 레이어 / 셀
- 셀 - 하나의 단계만 처리하는 부분.
- 레이어 - 여러 개의 셀을 묶은 것. 즉 셀 묶음이 하나의 레이어.
만약 레이어를 이중으로 쌓게 된다면, 우리가 생각하는 그림에서 가로 방향이 아니라 세로방향으로 하나 더 쌓인다고 생각하면 됨
nn.RNNCell() # 일반 RNN에 쓰이는 셀
nn.GRUCell() # GRU 레이어에 쓰이는 셀
nn.LSTMCell() # LSTM 레이어에 쓰이는 셀
이런 종류의 셀들이 있다.
7.4. 구조
RNN은 입력층, 은닉층, 출력층 외에도 가중치 3개를 추가로 가짐
- Wxh - 입력층->은닉층 전달되는 가중치
- Whh - 은닉층->다음 셀의 은닉층 전달되는 가중치
- Why - 은닉층->출력층으로 전달되는 가중치
참고로 저 셋은 모든 시점에 대해서 동일하다.
계산 과정은 이렇다.
- 은닉층 - 일반적으로 tanh를 사용, tanh(Whh X h이전층 + Wxh X x현재층)
- 출력층 - 소프트맥스 씌워주면 끝
- loss E - 각 단계마다 측ㄷ정하며, 주로 MSE를 사용
백프로파게이션의 경우, BPTT라는 기법을 사용.
- BPTT - 각 단계마다 오차를 측정하고 그걸 이전 단계 방향으로 넘김
즉 RNN 진행방향의 반대로 오차를 수정하는 것
문제점이 있는데, 여기서 오차가 멀리까지 전파되는 경우 그 계산량도 많아지고 값도 옅어지는 기울기 소멸 문제가 발생함
따라서 오차의 전파를 일부 단계로 제한 시키는 truncated BPTT도 자주 사용되며, 아예 일반 RNN 말고 LSTM이나 GRU로 때우기도 함
7.5. LSTM
일반적인 RNN의 기울기 소멸 문제를 해결하기 위한 대안 중 하나.
- 순전파의 관점에서 - 기울기 소멸 문제 해결책으로 망각 게이트, 입력 게이트, 출력 게이트라는 새로운 요소를 은닉층 각 뉴런에 추가함
* 망각 게이트 - 과거 정보를 어느 정도 기억할지 결정, 0~1 사이의 값을 가짐
- 입력 게이트 - 현재 정보 기억용, 현재 정보를 어느 정도 보존할지 tanh로 나타냄
- 출력 게이트 - 과거 정보와 현재 데이터로 뉴런의 출력을 결정, 그 후 히든 스테이트와 다음 입력을 고려해 다음 히든스테이트를 계산함
- 역전파의 관점에서 - 셀을 통해서 역전파를 진행하므로 '중단없는 기울기'라고 불림. 셀 단위로 역전파가 일어나지만, 입력 방향으로 오차가 전파되지 않는것은 아님