안녕하세요. 솩코딩입니다.
오늘은 지난 번에 이어서 중요한 NN중 하나인 RNN에 대해 공부한 내용을 정리하겠습니다.
RNN은 NN 중에서 가장 활용도가 높은 것으로 알려져 있습니다.
------------------------------------------------------
<Recurrent Neural Network>
음성인식, 자연어 등 sequence data(이전의 단락에 영향을 받는, 현재만이 아닌)가 있죠.
다시 말해, 현재 state가 다음 state에 영향을 끼치는 그런 데이터들에 대한 Neural Network를 만들자는 것입니다.
계산방법은 위에서 말했듯이, rnn에는 state개념이 있는데, 이 state를 계산할 때 이전의 state가 사용됩니다.

가장 기본적인 방법은 Vanilla RNN이라는 것인데요.
아래의 그림에서 보시다시피, 이전의 state h_(t-1), x에 대해 각각의 weight를 만들어주고, 이를 서로 곱하여 더해준 뒤
tanh적용하여 현재의 state h_t를 계산하는 것입니다.
y값을 출력 시에는 현재 state에 곱해줄 weight를 주어 이를 곱해주면 됩니다.
참고로, 같은 part(동일한 함수, 파라미터 내에서)에 대해서는 weight가 모두 같습니다.
또한, 맨 처음부분은 이전 항이 없으므로, 그 부분은 무시하고(즉, 0이라고 보고) 계산하면 됩니다.

*character-level language model: 현재 글씨가 있을 때 그 다음 글씨가 무엇일까를 맞추는 모델이다.
이를 rnn으로 구현해보자. 먼저, 각 글자를 벡터로 표현하며, 이 input layer에 대해 다음과 같은 계산을 통해 new state를 구합니다.

그 다음으로는 앞에서 구한 state들과 그에 해당하는 가중치를 곱하여 우리가 원하는 output layer를 구할 수 있습니다.
최종 출력에서 초록색으로 칠해진 숫자부분이 우리가 정답이라 할 수 있는 부분입니다.
하지만, output layer 각각에서 가장 큰 숫자가 정답으로 나오게 되는데, 앞에 두 개는 못 맞췄음을 알 수 있습니다.

위의 예시 뿐만 아니라, 그 밖에도 다양한 application들이 있습니다.
또, rnn을 가지고 다양한형태로 구성 가능합니다.

one to one: vanilla rnn
one to many: image captioning(image -> sequence of words ex) 이미지를 보고 "나는 모자를 쓰고 있네"로 나오도록)
many to one: sentiment classification(sequence of words -> sentiment ex) 아 이 문장은 기쁜데? 슬픈데?)
many to many 1: machine translation(seq of words -> seq of words)
many to many 2: video classification on frame level
ex) 비디오의 각각의 프레임을 받고 이에 대한 설명하는 것을 출력함
*위의 vanilla rnn도 마찬가지로 layer가 많아지고 깊어지면 학습에 어려움이 있다.
이를 극복하기위해 LSTM(Long Short Term Memory), GRU 두 개중 하나를 쓰게 된다.
------------------------------------------------------------------
<rnn basics>
cell만들때 가장 중요한 것은 cell에서 나가는 출력의 크기를 정해줘야 합니다.
(rnn,lstm,gru,..이런 원하는 형태의 cell)
이를 "hidden_size" 또는 num_units라고 하며, 우리가 정할 수 있는 값입니다.
cell을 만든 후에, 이를 실제로 "구동(구현)"하기 위해 보통은 tf.nn.dynamic_rnn을 쓰게 됩니다.
cell을 여기에 넘겨주고, 우리가 원하는 input_data를 넘겨 주면 output과 마지막 state을 나오도록 해줍니다.
(여기서 output만 우리는 씀)
참고로, sequence_length는 한 번에 sequence를 몇 번 줄것인가 즉, cell을 몇 번 펼칠것인가? 라는 것입니다.
(뒤에서 원핫인코딩의 개수 결정해줌.)
이는 입력데이터의 shape에 따라 결정되는데, input data shape=(1,5,4)이면
자동으로 sequence_length = 5 입니다. 참고로, 여기서 input_dim=4입니다.

sequence를 하나씩이 아닌, 한 번에 처리하기 위해 batch size(문자열의 개수라고 보면 된다.)를 정하여 합니다.
문자열이 한 개라면 batch_size=1이 되는 것이죠.
이때 batch_size=3로 하고 싶으면, 아래와 같이 input shape=(3,5,4)로 주면 됩니다.

-------------------------------------------------------------------------------
<rnn 'hihello' 훈련>

우선, text의 unique chars(각 알파벳)를 알아내게 한 뒤에 이를 voc index(각 알파벳에 해당되는 인덱스)로 표현합니다.
그 후, one-hot encoding을 이용하여 벡터로 표현합니다.
그리고 x_data, y_data는 각 문자의 인덱스로 표현하게 됩니다.
참고로, rnn에서 squence loss로 cost function을 씁니다.(앞선 cost ftn로 하게 되면 계산 복잡<=자세히는 잘 모르겠음)
이때, pred,target 둘다 sequence형태이며, 여기서는 weight는 모두 1로 주었습니다.
-----------------------------------------------------------------
<rnn with long sequence>
문자열이 길어지면, 예를 들어 책을 한꺼번에 넣는다던가하면 직접 x_data, y_data부분을 직접 적기 힘들어지게 됩니다.
이를 보완하기 위해, 데이터 입력을 자동화하게 합니다.

다시 말해서 loop를 돌려서 long sequence를 sequence_length만큼의 window를 움직이면서 위와 같이 자르게 됩니다.
이때, sequence_length는 직접 정해주면 됩니다.
그러나, 이를 실행해보면 잘 작동하지 않게 됩니다.
logit에서 매끄럽지가 않고, rnn이 깊지 않다는 문제 때문인데요.
(*logit: 딥러닝에서 확률화되지 않은 '날 것의' 예측 결과를 말함. multinomial classification에서는 보통 softmax함수의 입력으로 사용된다.)
-----------------------------------------------------------------------
<stacked rnn(여러층) + softmax layer>
위의 문제를 해결해봅시다.
앞에서 보았던 rnn은 한 층 밖에 없었습니다. 이를 층을 쌓아보자며 나온 것이 stacked rnn이라는 것입니다.
형태는 아래와 같습니다.(layer를 두 개 쌓은 case)

또한, cnn처럼 기존 rnn 뒤에 fc(full connected layer), softmax를 붙여주면 됩니다.
이때, softmax를 적용하기 전에는 위의 그림처럼 reshape를 시켜주어야 합니다.
**이런 부분은 계속 반복되어 나오니 코드 자체로 기억하는 것이 좋습니다.
앞에서 했던 기존 rnn의 예측 결과는 activation을 거친 것이었습니다.
위와 같이 activation을 거친 후에 원래의 형태로 바꿔준 output(다시 말해, activation을 거치지 않은)으로
sequence loss를 계산하게 됩니다.
이렇게 되면, 성능이 좋게 나오며, 위의 문제가 극복이 됩니다.
생각해보면, 당연합니다. loss 계산 시에, 실제 값과 예측 값으로 계산될 텐데, 예측 값이 activation 적용된 것이면
문제가 발생하는 게 당연합니다. 그래서 activation 적용하지 않은 것으로 하는 게 맞습니다.
그 밖에 char rnn & word rnn 구현된 것을 소개하겠습니다.
영상에서 알려준 사이트인데, 저도 차차히 구현해보도록 하겠습니다.
https://github.com/hunkim/word-rnn-tensorflow
GitHub - hunkim/word-rnn-tensorflow: Multi-layer Recurrent Neural Networks (LSTM, RNN) for word-level language models in Python
Multi-layer Recurrent Neural Networks (LSTM, RNN) for word-level language models in Python using TensorFlow. - GitHub - hunkim/word-rnn-tensorflow: Multi-layer Recurrent Neural Networks (LSTM, RNN)...
github.com
------------------------------------------------------------------------
<Dynamic RNN>
번역 등에서 생각해보면 sequence length는 가변하게 됩니다.
이에 대한 rnn을 만든다면 어떻게 처리할 수 있을까요?
->각 batch에 해당하는 seq_length을 리스트 형태로 적어주면, 여기에 따라 rnn이 나머지 셀은 0이 되도록 처리합니다.
-----------------------------------------------
<rnn with time series data>
시간에 따라 값이 변하는 데이터로 rnn을 이용해 예측해봅시다.
주식시장이 대표적이죠.
many to one 형태 즉, 7일 동안의 데이터가 있을 때 7일 이전의 데이터를 넣고
8일째되는 날의 가격이 어떻게 될지 예측하는 형태로 보려 합니다.

이때, input_dim, seq_len(timesteps), hidden_dim을 넣어주어야 하며,
여기서 input=5(open, high, low, volume, close 값들), seq_len=7(7일 간의 데이터), output=1(8일째 되는 날의 close 값)
영상에서 linear regression로 주가 예측한거랑 비교해 볼 필요 있다는 메세지로 마무리하게 됩니다.
이전의 state를 이용한 모델과, linear 성질을 이용한 모델... 예상은 전자가 훨 좋을 거라 생각하는데,
이것 또한 해봐야되겠죠.!
또한, 뉴스 관련 기사를 추가로 하여 예측할 수도 있겠습니다. 여기서 크롤링이 필요하니, 크롤링 공부 후 해야겠네요.
이로써 모두를 위한 딥러닝 시즌1에 대한 '리뷰(?)' 글을 마치겠습니다.
거의 대부분 필기하듯이 쓴 거지만, 나중에 훑어볼 때는 도움될 것 같습니다. :>
저의 다음 계획은 cs231n의 딥러닝 강의에 대한 리뷰를 하는 것입니다.
그 때는 진짜로 저만의 언어로 표현할 수 있었으면 하는 바람입니다. ㅎㅎ
감사합니다. :>
모두를 위한 딥러닝 시즌1(김성훈 교수님)
https://www.youtube.com/watch?v=BS6O0zOGX4E&list=PLlMkM4tgfjnLSOjrEJN31gZATbcj_MpUm
솩코딩 깃허브
https://github.com/lala991204/DL-self-study
'DL(Deep Learning)' 카테고리의 다른 글
| Fast campus(혁펜하임) - 강화학습 (2) | 2023.10.21 |
|---|---|
| Fast campus(혁펜하임) - 자기지도학습 (2) | 2023.10.09 |
| CNN(Convolutional Neural Network) (0) | 2022.02.01 |
| NN의 몇 가지 팁들(ReLU 사용, weight초기화, dropout과 앙상블) (0) | 2022.01.28 |
| XOR 문제 딥러닝으로 풀기/ Back Propagation (0) | 2022.01.27 |