cs231n 2017 강의 10강 RNN 정리
안녕하세요. 으.. 날씨가 많이 춥네요. 건강 조심하세요.
이것도 정리가 조금 늦었네요
카카오 형태소 분석기 설치랑, 예전에 했던 LSTM 프로젝트 등을 정리하느라고 조금 늦어졌습니다.
이번 포스팅은 딥러닝 영상처리 강의 스탠포드 대학교 cs231n 2017강의 10번째 강의 RNN입니다.
RNN(Recurrent Nerual Networks)는 CNN과 함께 정말 많이 사용하는 네트워크입니다.
시계열 데이터(timestamp) 등에서 많이 사용되고 그 예로는 문자열 데이터, 주식(코인) 데이터, 비디오 데이터 등 정말 다양한 데이터가 RNN과 함께 사용될 수 있습니다.
아 그리고 이번 강의는 좀 정리가 힘드네요. 이 강사가 말이 너무 빠르고 그냥 훅훅 지나가서..
에흌ㅋㅋㅋㅋㅋ 힘듭니다. 아무튼
시작해볼까요
우리가 여태것 배운 것은 이런 one to one 구조를 배웠습니다. 단순히 x가 들어가면 y가 나오는 구조였죠.
하지만 이런 구조도 있습니다. One to many, many to one, many to many 등이 있죠.
One to many 같은 경우는 image captioning에 많이 쓰입니다.
Many to one같은 경우는 감정 분석, 뉴스 카테고리 분석 같은 경우에 쓰이는 것이죠.
Many to many는 기계 번역 같은 것입니다. 예를 들어 한글 -> 영어로 번역해주는 그런 것입니다.
또한 비디오를 분석하기 위한 프레임 레벨도 여기 포함되죠. 비디오는 프레임이 계속 들어오니까 이걸 계속 받고 바로바로 뭔가 분류를 해준다거나 그럴 때 쓰이는 것이죠.
RNN은 이러한 데이터들에게 매우 강력합니다. 아주 잘 처리해주죠. 그리고 이러한 데이터는 가변길이를 가지고 있습니다. 이런 강점이 있는 것이 RNN입니다.
그리고 RNN은 고정 길이의 데이터에도 매우 유용합니다. 이 그림을 보면 고정된 길이를 가진 데이터 크기이지만 sequential 하게 접근을 하고 있습니다. 이것은 이미지의 숫자가 몇 인지 인식하는 것입니다. 이미지의 여러 부분을 조금씩 sequential하게 접근합니다. 그리고 숫자가 몇인지 최종적으로 판단하죠.
그리고 다음은 동일한 방법으로 이미지를 생성하는 것이라고 합니다. 이 경우에도 출력은 고정된 길이입니다. 하지만 RNN을 이용해 빠르게 처리 가능하죠.
그러면 얘는 어떻게 동작할까요? RNN은 이 초록색 그림처럼 core cell을 가지고 있습니다.
그리고 여기에 입력 x가 들어가게 되죠. 이 RNN 내부에는 hidden state를 가지고 있구요. 여기 hidden state는 RNN이 새로운 입력 데이터를 가지고 올 때마다 업데이트가 됩니다. 그리고 뭔가 출력값을 내보내야할 경우가 있으면 y 처럼 출력을 내보내죠.
여기는 RNN을 수식적으로 표현한 것입니다. 그림에서는 나오지 않아 있지만 ht라는 것은 RNN에서 RNN으로 나가는 hidden state입니다. Ht는 현재 state를 뜻하죠. Ht는 기존 state인 ht-1과 현재 들어오는 xt에 영향을 받게 됩니다. 그리고 ht가 출력되고 이 ht는 또 다음 ht에 영향을 미치게 되죠. 이렇게 과거의 데이터가 미래에 영향을 줄 수 있는 구조를 가진 것이 RNN입니다.
그리고 중요한 사실은 파라미터w는 매 step 동일한 w가 쓰이게 됩니다. 그리고 function도 마찬가지로 same한 것을 쓴다고 합니다.
그럼 먼저 RNN을 만나보려면 Vanilla RNN부터 만나봐야겠죠? 아무래도 제일 기초적인 것이니까요. 바닐라(Vanilla) RNN은 이렇게 생겼습니다.
아까 말한 것 그대로인데 W가 여러 개이었죠? Whh, Wxh, Why가 있습니다. Whh는 hidden에서 오는 W입니다. 그리고 Wxh는 x에서 RNN으로 들어오는 weight이죠. 그리고 Why는 RNN cell에서 y로 넘어가는 weight입니다. 이렇게 3가지가 있습니다.
3가지 weight는 다르지만 이 각각은 자신의 영역에서 same한 것을 계속 사용하는 것이죠.
그래서 RNN을 그래프로 계속 그려보면 이런 모양이 나오게 됩니다.
이렇게 X가 계속 들어오면 H가 이어지고 H와 fw가 이어져서 연속적인 데이터를 처리할 수 있게 됩니다.
그리고 더 구체적으로 W를 그러볼까요? W는 이렇게 들어가는데요. 여기서 다시 알아야할 것! ‘동일한 가중치 행렬 w’가 계속 사용된다는 것입니다. H와 x는 계속 달라지지만 w는 동일하다는 것입니다.
그리고 이렇게 y가 출력될 수도 있죠. 그리고 여기 Loss가 붙게됩니다. 만약 각 스텝마다 y가 이렇게 있으면 개별적으로 y_t에 대한 loss를 계산하게 됩니다. 그러면 여기에서는 softmax가 loss가 될 수 있겠네요. RNN의 최종 loss는 각 개별 loss들의 합입니다!
각 단계에서 loss가 발생하면 전부 더하여 최종 네트워크 loss를 계산하게 됩니다.
여기서 backpropagation을 생각해보죠. 모델을 학습시키려면 DL/dW를 구해야합니다. Loss는 각 스텝에서 이루어지니까 각 스텝마다 가중치 w에 대한 local gradient를 계산할 수 있습니다. 이렇게 개별로 계산된 local gradient를 최종 gradien에 더합니다.
이제는 many to one입니다. 이 경우에는 최종 hidden state에서만 결과 값이 나옵니다.
그렇다면 one to many 에서는요?? 입력은 ‘고정’이지만 출력은 ‘가변’입니다. 이 경우 고정 입력은 모델의 initial hidden state를 초기화 시키는 용도로 사용한다고 하네요.
자 그러면 이제 sequence to sequence(시퀀스 to 시퀀스)에 대해서 알아보죠. 이거는 번역기 같은 곳에서 사용할 수 있습니다. 가변 입력과 가변 출력을 가지죠. 이거는 many to one과 one to many의 결합으로 생각할 수 있습니다.
그리고 2개의 stage로 나뉩니다. Encoder/decoder가 나오는데요. Encoder는 가변 입력을 받죠. 그리고 마지막 hidden state를 통해 전체 sentence를 요약합니다. 그리고 decoder로 가죠.
decoder에서는 가변 출력을 해줍니다. 매 스텝 적절한 단어를 내주는 것이죠.
좀 더 구체적인 예로 볼까요? RNN은 Langague model에서 자주 나오니까 자연어로 예시를 들어봅니다.
Hello로 예시를 들어보죠. 단어는 총 4개입니다. h,e,l.o이죠. 그러면 input은 h,e,l.l이 될 것입니다. Output은 e,l,l,o가 될 것이구요. 이제 여기서는 다음 문자를 예측을 해야합니다.
Train time에서는 training sequence로 hello의 각 단어를 넣어줍니다. 즉 hello가 RNN의 x_t가 되죠.
그리고 사전은 총 4가지라고 아까 봤죠. h, e, l, o요. 그럼 이 단어들을 [1,0,0,0]처럼 각 자리에만 1이고 나머진 0의 값으로 만들어줍니다. 이걸 흔히 one-hot encoding이라고 하죠.(웟-핫 인코딩)
첫 번째 셀에는 h가 들어갑니다. 그리고 출력으로 뭔가 값을 뿜어내죠. 다음에 e가 나올 것을 예측해야할 것입니다. 하지만 여기 모델에서는 다음에 나올 글자가 o라고 예측 하고 있네요. 왜냐하면 o가 [0,0,0,1]의 값인데 지금 4.1로 제일 높죠. 그러면 얘가 1이 됩니다. 즉 예측을 잘 못하고 있죠.
다음 스텝에서는 e가 들어가고 또 반복합니다. 여기서 e가 들어갈 때 이전 hidden state와 함께 새로운 hidden state를 만들어내는 것입니다. 이제는 두번째 hidden state를 이용해서 적절한 값을 예측해야 합니다. h -> e 니까 l을 예측해야 하는 거죠. 근데 여기서는 l에 대한 예측값이 낮죠. 그래서 loss가 굉장히 클 것입니다. 이 과정을 반복합니다. 이걸 반복하다 보면 다음 문자가 무엇이 나올 지 잘 훈련이 될 것입니다.
그렇다면 이 모델의 test time은 어떨까요? 입력값이 들어가면 train때 모델이 봤을 만한 단어를 모델이 만들어냅니다. 우선 모델에게 h만 줬습니다. 그러면 모든 문자 (h,e,l,o)에 대해서 score가 output layer에서 나오게 됩니다. Test time에서는 이 스코어를 다음 글자 선택에 이용합니다.
그리고 스코어를 확률분포로 표현하기 위해서 softmax 함수를 사용했습니다. 문장의 두 번째 글자를 선택하기 위해서 이 확률 분포를 사용하죠. 지금 여기서는 운 좋게 e가 선택되었습니다. O의 확률이 가장 높지만 운 좋게 e가 선택된 것이죠.
그럼 이 e를 다음 스탭으로 넘겨줍니다. 이 과정을 계속 반복하는 것이죠.
이렇게 쭉쭉 진행됩니다.
그럼 궁금하죠? 왜 확률분포에서 할 까?? 물론 가장 높은 score값을 사용하면 바로바로 할 수 있겠죠. 근데 만약 그렇게 했으면 올바른 결과를 낼 수 없었을 것입니다. 왜냐하면 e 스코어가 낮았기 때문이죠. 확률분포를 사용했기에 hello를 만들 수 있었습니다.
실제로는 확률 분포 or score 높은 것 2개를 모두 사용할 수 있다고 하네요. 근데 확률 분포를 사용하는 것은 모델에서의 다양성을 얻을 수 있기에 그렇게 한다고 합니다.
여기서 backpropagation through time이 있습니다. 우리가 앞에서 했던 모델의 경우 매번 출력값이 존재하죠? 이 출력값들의 loss를 계산해 final loss를 얻는데 이를 backpropagation through time이라고 합니다. 여기서는 forward pass의 경우 전체 시퀀스가 끝날 때 까지 출력값이 생성되는데 backward pass에서도 전체 시퀀스를 가지고 loss를 계산합니다. 근데 이게 문제가 되죠.
만약 시퀀스가 매우 길면?? 만약 어떤 소설책을 넣었다고 가정합시다. 이 소설책을 끝까지 다 보고나서야 gradient를 1회 계산(update)합니다. 정말정말 느리겠죠. 매우 비효율적입니다.
그래서 실제로는 truncated backpropagation을 사용합니다. 이거는 train time에 한 스텝을 일정 단위로 자릅니다. 만약 100개를 잘랐다고 하면 100개를 forward하고 여기서 loss를 계산합니다. 그리고 gradient step을 진행하죠. 이 과정을 반복합니다. 그리고 앞에서 배운대로 다음 hidden state는 이전 hidden state를 그대로 사용하구요. 마치 이전에 봤던 batch size 처럼 하는 것입니다. mini batch로 했었죠. 그거랑 비슷하다고 생각하시면 됩니다.
이거를 말로만 들었을 때 굉장히 어려워 보이지만 여기서는 단 112줄의 파이썬 코드로 이것을 구현했다고 하네요 개쩌네요. ㅎㅎㅎㅎㅎㅎ
자 그럼 여기서부터는 조금 재밌는 예제를 봐봅시다. 셰익스피어를 훈련시켜서 훈련을 시키면 시킬 수록 뭔가 그럴 듯 하게 나온다는 예제구요.
수학책을 훈련시켰을 때도 (물론 100% 맞지 않지만) 그럴듯하게 나온다고 하구요
리눅스 커널도 그럴듯하게 나온다고 합니다.
여기 부분은 그냥 재밌는 예시니까요. 넘어가겠습니다. ㅎㅎ 그냥 저 모델을 사용했더니 저렇게 수학 공식이나 리눅스 커널처럼 자기 나름대로 그럴 듯 하게 결과를 도출했다고 하네요 ㅎㅎ
여기서 searching for interpretable cells가 나옵니다. RNN에는 hidden vecotr가 있고 이 vector가 계속 업데이트됩니다.
여기서는 카파시가 이 vector를 추측한 것이 나옵니다.
이렇게 아무런 의미가 없는 패턴이 있는것도 있었지만
여기서는 “를 기준으로 뭔가 패턴을 인식하고 있는 것을 볼 수 있습니다.
그리고 여기서는 문장의 길이에 따라
여기서는 if문 안에 조건문에서 값이 켜지거나
주석문에서 패턴이 발생되거나
들여쓰기 레벨을 파악하는 등 cell의 활동을 볼 수 있었습니다.
Image captioning은 CNN과 RNN을 혼합한 대표적인 방법입니다. 입력은 이미지가 들어가지만 출력은 자연어로 된 캡션이 나오게 되죠.
빨간색 네모처럼 모델에는 입력 이미지를 받기 위한 CNN이 있습니다. 그리고 여기서 이미지ㅣ 정보가 들어있는 vector를 출력합니다. 이 벡터가 RNN의 초기 step으로 들어가죠. 그러면 RNN은 문장을 만들어내구요.
그렇다면 이 모델을 학습시킨 후에 test time에 어떻게 동작하는지 알아보죠
Test image를 넣습니다. 다만 마지막의 softmax score를 사용하지 않고 직전의 fc-4096 벡터를 출력으로 합니다. 이 벡터를 이용해 전체 이미지 정보를 요약합니다.
그리고 RNN으로 들어가는데 먼저 초기 값을 넣어줘야하죠. 이 경우에는 입력이 조금 특별하게? 들어갑니다. ‘문장을 만들어주세요’라는 신호?를 보내는 것이죠. Start 신호를 주는 것이죠.
그리고 이 전까지는 function에 2개의 가중치 행렬을 입력으로 받았다면(스텝 입력, 이전 ht) 이제 이미지 정보도 더해줘서(분홍색) 입력으로 줍니다.
그리고 hidden state를 계산할 때마다 모든 스텝에 이 이미지 정보를 추가해줍니다. 그래서 시작이 되면 샘플링된 단어가 나오고
이게 다음 input으로 들어가고 단어를 추정하게 됩니다. 반복하죠.
그리고 이게 끝나면(END) 문장이 만들어지죠. <END> 토큰이 나오면 더 이상 단어를 생성하지 않으며 이미지에 대한 caption이 완성됩니다.
그리고 train time에서는 모든 caption의 종료지점에 <END>토큰을 삽입합니다. 학습하는 동안에 시퀀스 끝에 <END>토큰을 넣어야 하는 것을 알려줘야 하기 때문입니다.
이러한 것은 supervised learning으로 된다고 합니다. 따라서 모델을 학습시키기 위해서는 natural language caption이 있는 이미지를 가지고 있어야 합니다. 대표적인게 Microsoft coco 데이터셋이라고 하네요. 이렇게 하면 상당히 그럴 듯 한 결과가 나오는데요.
예를 들어 고양이가 나무 위에 앉아 있다거나 2명의 사람이 서핑보드와 함께 해변가에서 걷고 있다 등을 보여주고 있습니다.
물론 완벽하게 다 잘 되지는 않습니다. 첫 번째 그림에서는 고양이가 없는데 고양이가 있다고 표현되고 있구요 오른쪽 위의 사진인 거미줄 모양에서는 새가 없는데 새에 대한 설명을 하고 있습니다. 그래도 나름 흥미로운 결과를 도출해냅니다.
여기서 조금 더 진보된 것이 있는데 그것은 attention입니다. 무엇인가 집중한 것이죠. 이 모델은 caption을 생성할 때 이미지의 다양한 부분을 집중(attention)해서 볼 수 있는 것입니다.
이 강의에서는 이 attention에 대해서 집중있게 다루진 않고 그냥 슬렁슬렁 넘어갑니다.
그냥 어떤식으로 동작하는지 설명하는데요. 여기 CNN이 있습니다. 여기서 벡터가 공강정보를 가지고 있는 grid of cector(L x D)의 모양을 만들어냅니다.
그리고 forward할 떄에 매 스탭 vocabulary에서 샘플링을 할 때
모델이 이미지에서 보고싶은 위치에 대한 분포를 만들어냅니다. 즉 train때에 모델이 어느 위치를 봐야하는지에 대한 attention이라고 할 수 있습니다. 첫 번째 hidden state(h0)는 이미지 위치에 대한 분포?를 계산한다고 합니다. 이게 a1입니다. 이것을 벡터 집합 (L x D)와 연산하여 attention(z1)을 만들어냅니다.
이 벡터 z1은 neural network 다음 스텝 입력으로 들어가게 됩니다. 그러면 a2, d1이라는 2개의 출력이 생성되죠.
이 반복이 계속 되는 것입니다.
Train이 끝나면 모델이 caption을 생성하기 위해서 이미지의 attention을 이동시키는 것을 볼 수 있습니다. 위 사진 처럼요. 여기서는 caption은 a bird flying over a body of water네요.
여기서 보면 위에는 soft attention이고 아래는 hard인데요. Soft는 모든 특징과 이미지 위치 간의 척도? Weight? 이런것을 뜻하는 것 같네요. 그리고 hard는 soft보다 좀 더 hard하게 즉 한 곳을 바라보는? 이런 것 같습니다.
그리고 실제로 훈련 시킨 후 보면 의미 있는 부분에 attention을 집중하는 것을 볼 수 있습니다. 우리가 어디를 보라고 메시지를 주지도 않았는데 모델 스스로 학습한 것이죠.
이 부분은 어렵네요. 뭐라는 지도 잘 모르겠고 여기서도 대충 설명하니까…
뭐 아무튼 다음은 visual question answering입니다. 여기서는 입력이 2가지입니다. 하나는 이미지, 다른 하나는 이미지와 관련된 질문입니다. 그래서 질문에 대한 답을 찾는? 뭐 그런 것 같습니다.
이 모델도 RNN과 CNN으로 만들 수 있다고 하네요. Many to one식으로 진행됩니다.
잘 모르겠습니다. 넘어갈게요 ㅠ
보통은 RNN을 이렇게 multilayer RNN으로 사용을 하는데요. 모델이 깊어질수록 성능이 좋아지기 때문이죠.
지금까지는 RNN과 그 예시를 살펴보았습니다. 하지만 일반적인 RNN은 잘 사용하지 않습니다. RNN을 학습시킬 때 문제가 발생되기 때문인데요.
이게 RNN의 기본 수식입니다. 현재 입력 x_t와 이전 hidden state h_t-1이 들어오죠. 그리고 두 입력을 stack합니다. 쌓는 것이죠.
이럴 때 backward pass에서 gradient를 계산하는 과정에서 어떤 일이 발생될까요? 우선 h_t에 대한 loss 미분값을 얻습니다. 그 다음 loss에 대한 h_t-1의 미분값을 계산하게 됩니다. 이 빨간색 경로처럼 진행됩니다. 근데 여기서 보아야할 것이 tanh gate를 타고 mul gate를 통과하게 되죠. 앞장에서 보았듯이 mul gate는 결국 transpose(가중치 행렬)을 곱하게 됩니다.
이는 매번 RNN cells를 통과할 때마다 가중치 행렬의 일부를 곱하게 되는 것이죠. 매번 이렇게 되는 것이죠! 결국 모든 RNN cells를 거쳐야합니다. Cell 하나를 통과할 때 마다 각 cell의 행렬 w transpose 요소가 관여하죠. 이는 많은 가중치 행렬들이 개입하게 되고 매우 비효율적입니다.
그리고 여기서는 그림이 4개지만 만약 수백개면? 매우 비효율적이게되겠죠. 그리고 만약 곱해지는 값이 1보다 큰 경우면 값이 점점 커지고 1보다 작으면 값이 점점 작아져서 0이 됩니다.
커지는 것은 어떻게 막을 수 있지만 작아지는 것은 결국 gradient vanshing으로 가게 되는 것입니다.
여기에 나와있네요. 커지는 것은 gradient clipping으로 막을 수 있지만 작아지는 것은 뭐 방법이 없습니다.
그래서 RNN대신 LSTM을 많이 선호하죠. LSTM은 Long Short Term Memory이빈다. 장기 의존성 문제를 해결하기 위해서 디자인 되었죠. LSTM 은 C_t라는 cell state라는 두 번째 벡터가 있습니다. 저기 식을 보시면 일단 2개의 입력을 받습니다. H_t-1과 x_t죠. 그리고 4개의 gate를 계산합니다. 흔히 ifog(아이포그)라고 불리우죠. i, f, o, g 게이트입니다. 이 gate를 이용해서 c_t를 업데이트하는데 이용합니다. 그리고 c_t로 다음 스텝의 hidden state를 업데이트합니다.
이제 이게 LSTM이 어떻게 동작되는지 자세히 보죠. 앞에서 설명한대로 이전 hidden state인 h_t와 현재 입력인 x_t는 똑같이 받습니다.
Vanilla RNN의 경우에는 이 두 입력을 concat하고 행렬곱 연산을 통해 hidden state를 구했습니다. 하지만 LSTM에선 좀 다릅니다.
2개의 값을 받고 쌓은 다음 4개의 gates를 계산하기 위해 가중치 행렬을 곱해줍니다. 각 gate 출력은 hidden state 크기와 동일합니다.
게이트 계산은 4개입니다. i,f,o,g gate이죠. i는 input gate입니다. cell에서의 입력 x_t에 대한 가중칩니다. f는 forget gate입니다.
이전 스텝의 cell을 얼마나 잊을지 정합니다. o는 output gate입니다. 이거는 cell state를 얼마나 밖에 드러낼 것이냐?를 정합니다.
g는 강의에서는 그냥 gate gate라고 하는데요. input cell을 얼마나 포함시킬지 정한다고 합니다.
그니까 forget gate는 과거 정보를 잊기 위한 게이트입니다. 그리고 input gate i와g는 현재 정보를 기억하기 위한 게이트입니다.
여기서는 앞에서 효율이 안좋다고 했던 sigmod, tanh를 사용하는데요.
잊기 위해서는 0에 가까운, 그리고 기억하려면 1에 가까운 값을 사용하겠죠? 0~1이니까요. 그래서 sigmoid를 씁니다.
그리고 -1, 1의 tanh는 i에서 0~1은 강도, gt의 범위 -1 ~ 1은 방향을 나타낸다고 생각하시면 되겠습니다.
뒤에서 뭐 그림이 나오지만 i와 g쪽을 보시면 더 이해하기 쉬우실겁니다.
sigmoid gate 출력값과 tanh 함수를 거쳐서 나온 -1~1의 값을 곱해서 우리가 원하는 값만 결과 쪽으로 뽑아내는 것이죠.
(솔직히 tanh를 쓰는 이유에 대해선 좀 어렵네요)
여기서 카파시의 설명은 아래와 같습니다.
벡터 i의 경우에는 시그모이드에서 나온 녀석이므로 0 또는 1입니다. cell state의 각 element에 대해서, 이 cell state를 사용하고 싶으면 1 이 됩니다. 반면 쓰고싶지 않으면 i = 0 이 될 것입니다. gate gate는 tanh 출력이기 때문에 값이 -1 또는 +1 입니다. c_t 는 현재 스텝에서 사용될 수 있는 "후보" 라고 할 수 있습니다. Cell State(c_t)를 계산하는 전체 수식을 살펴봅시다. 이 수식은 두 개의 독립적인 scaler 값(f, i)에 의해 조정됩니다. 각 값(f, i)은 1까지 증가하거나 감소합니다. c_t의 수식을 해석해보면, 우선 이전 cell state(c_t-1)을 계속 기억할지 말지를 결정합니다. (f * c_t-1) 그런다음 각 스텝마다 1까지 cell state의 각 요소를
증가시키거나 감소시킬 수 있습니다. (i * g) 즉 cell state의 각 요소는 scaler integer counters
처럼 값이 줄었다 늘었다 하는 것으로 볼 수 있습니다. Cell state를 계산했다면 이제는 hidden state를 업데이트 할 차례입니다. h_t는 실제 밖으로 보여지는 값입니다. 그렇게 때문에 cell state는 counters의 개념으로 해석할 수 있습니다. 각 스텝마다 최대 1 또는 -1씩 세는 것이죠
이렇다고 하네요. 솔직히 좀 어렵습니다. 이해가 잘 안가구요.
그래서 LSTM은 대체 사이트를 소개하려고 합니다.
아마 아래 피티 내용보다 이 소개해드린 사이트가 설명이 더 잘되어 있을 겁니다.
https://brunch.co.kr/@chris-song/9
https://ratsgo.github.io/natural%20language%20processing/2017/03/09/rnnlstm/
ratsgo님의 깃허브와 chris-song님이 colah님의 블로그를 번역하신 글이 있습니다. 위 2개의 게시글이 LSTM 설명을 매우 잘 해놨습니다. 꼭 보시길 바랍니다. 저도 계속 보면서 더 공부해야겠네요.
이걸로 이번 장 정리를 마치겠습니다.
수고하셨습니다.