해당 글은 핸즈온 머신러닝 2판을 기준으로 작성되었습니다.
RNN이란?
RNN은 recurrent neural networks의 약자로, 한국어로 번역하면 순환 신경망이 된다. 고정 길이 입력이 아닌 임의 길이를 가진 시퀀스를 다룰 수 있어, 문장, 문서, 오디오 샘플을 입력으로 받고 자동 번역, STT와 같은 NLP 작업에도 유용하다.
input: x
output: y
위 RNN 구조를 보면 각 타임 스텝 t(또는 프레임)마다 $x_{(t)}$와 이전 타임 스텝의 출력인 $y_{(t-1)}$을 입력으로 받는다. 첫 번째 타임 스텝은 이전 출력이 없으므로 일반적으로 0으로 설정한다. 아래 왼쪽 그림은 순환층을 직관적으로 나타낸 것인데, 이것이 헷갈리면 시간에 따라 네트워크를 펼친(unrolling the network through time) 오른쪽 그림을 참고하면 된다.
각 순환 뉴런은 두 벌의 가중치를 가진다. 하나는 입력 $x_{(t)}$를 위한 것이고 다른 하나는 이전 타임 스텝의 출력 $y_{(t-1)}$을 위한 것이다. 이를 각각 $w_x$ 와 $w_y$라고 하겠다. 하나의 순환 뉴런이 아니라 순환 층 전체를 생각하면 가중치 벡터를 행렬 $W_x$와 $W_y$로 바꿀 수 있다. 순환 층 전체의 출력 벡터는 아래 식과 같이 계산된다.
$y_{(t)} = \phi (W_x^T x_{(t)} + W_y^T y_{(t-1)} + b)$
$\phi$: 활성화 함수로 RNN에선 보통 하이퍼볼릭 탄젠트(tanh) 활성화 함수를 선호한다.
타임 스텝 t에서의 모든 입력을 행렬 $X_{(t)}$로 만들어 미니배치 전체에 대해 순환 층 출력을 한 번에 계산할 수 있다. 참고로 $W$를 Andrew Ng 강의에선 stacking이라고 칭한다.
$Y_{(t)} = \phi (X_{(t)} W_x + Y_{(t-1)} W_y + b)
= \phi ([X_{(t)} Y_{(t-1)}] W + b)$ where $W=[W_x, W_y]^T$
표기법 정리
$Y_{(t)}$: 타임 스텝 t에서 미니배치에 있는 각 샘플에 대한 층의 출력을 담은 $m \times n_{neurons}$ 행렬 ($m$은 미니배치에 있는 샘플 수, $n_{neurons}$은 뉴런 수)
$X_{(t)}$: 모든 샘플의 입력값을 담은 $m \times n_{inputs}$ 행렬 ($n_{inputs}$은 입력 특성 수)
$W_x$: 현재 타임 스텝의 입력에 대한 연결 가중치를 담은 $n_{inputs} \times n_{neurons}$ 행렬
$W_y$: 이전 타임 스텝의 출력에 대한 연결 가중치를 담은 $n_{neurons} \times n_{nerouns}$ 행렬
$b$: 각 뉴런의 편향을 담은 $n_{nerouns}$ 크기의 벡터
보통 $W_x$와 $W_y$를 합쳐서 $(n_{inputs} + n_{neurons}) \times n_{neurons}$ 크기의 가중치 행렬 $W$ 하나로 연결한다.
$Y_{(t)}$는 $X_{(t)}$와 $Y_{(t-1)}$의 함수고, $Y_{(t-1)}$는 $X_{(t-1)}$와 $Y_{(t-2)}$의 함수고, 이를 계속 반복하다보면 결국 $Y_{(t)}$은 시간 t=0에서부터 모든 입력에 대한 함수가 된다.
메모리 셀
타임 스텝 t에서 순환 뉴런의 출력은 이전 타임 스텝의 모든 입력에 대한 함수이므로 이를 일종의 메모리 형태라고 말할 수 있다. 타임 스텝에 걸쳐 어떤 상태를 보존하는 신경망의 구성 요소를 메모리 셀(memory cell)이라고 한다. 일반적으로 타임 스텝 t에서의 셀 상태를 $h_{(t)}$라고 한다.
RNN은 입력 형태와 출력 형태를 다양하게 설정할 수 있다.
vector-to-sequnece network(one to many): 하나의 입력 벡터를 반복해서 네트워크에 주입하고 하나의 시퀀스를 출력 ex) 이미지(또는 CNN 출력)를 입력하여 이미지에 대한 캡션 출력
sequence-to-vector network(many to one): 입력 시퀀스를 네트워크에 주입하고 하나의 시퀀스를 출력 ex) 영화 리뷰의 연속된 단어를 주입하여 감성 점수 출력
sequence-to-sequence network(synched many to many): 입력 시퀀스를 받아 출력 시퀀스를 출력 ex) 주식가격 같은 시계열 데이터 예측
encoder-decoder sequence network(many to many): 인코더라 부르는 시퀀스-투-벡터 네트워크 뒤에 디코더라 부르는 벡터-투-시퀀스 네트워크를 연결 ex) 한 언어의 문장을 다른 언어로 번역하는 데 사용
RNN 훈련하기
RNN은 학습할 때 보통 역전파를 사용한다. 이를 BPTT(backpropogation through time)이라고도 부른다. 딥러닝에서 사용되는 역전파와 똑같이 작용하며, 현재 메모리 셀이 예측한 값이 실제값과 차이(=error)가 나면 이는 이전의 메모리 셀에서 잘못한 것이라고 생각하면 쉽다. 즉 연대 책임을 묻는 것이다.
주의할 점은 가중치가 각 메모리 셀마다 다른 값을 가지는 것이 아니라 정방향 패스 동안 모든 타임 스텝이 동일한 가중치 행렬을 공유한다는 것이다. 아래 그림에서 $W_a$, $b_a$는 각 셀마다 똑같이 적용된다. 따라서 역전파로 최종 업데이트되는 가중치는 모든 타임 스텝에 걸쳐 합산된 값이다.
위에서 Loss function은 보면 알 수 있듯이 sigmoid function을 사용한 예시이다.
지금까지 RNN 개념을 살펴봤고, 케라스를 활용한 예시 코드는 다음 글에서 소개한다. 이후에는 RNN의 단기 기억 문제를 해결한 LSTM에 대해서도 정리하려고 한다.
'문돌이 존버 > 데이터 분석' 카테고리의 다른 글
판다스 iloc로 여러 컬럼 선택하기 feat. np.r_ (0) | 2021.06.16 |
---|---|
RNN 개념 잡고 간단 예제 코드 돌려보기 (2) (1) | 2021.04.25 |
사용자-아이템 기반 협업 필터링(Collaborative Filtering) feat. Matrix Factorization (0) | 2021.04.10 |
앙상블 학습 - 부스팅(boosting) 알고리즘 개념 잡기 (0) | 2021.04.10 |
파이썬, pandas 일자 및 시간 처리 방법, feat. dt (0) | 2021.04.06 |