Deep Learning for NLP with PyTorch

#Deep-Learning-for-NLP-with-PyTorch

저자: Robert Guthrie
역자: Don Kim

Sequence Models and Long-Short Term Memory Networks

#Sequence-Models-and-Long-Short-Term-Memory-Networks

원본: http://pytorch.org/tutorials/beginner/nlp/sequence_models_tutorial.html

지금까지 우리는 여러 feed-forward network들을 봐 왔는데, feed-forward network는 상태(state)를 계속 간직할 필요가 없었다. 이것은 어쩌면 우리가 원하지 않는 모델의 성질일 수도 있다.

NLP의 핵심적인 개념으로 sequence 모델을 들 수 있는데, 이는 시간 (혹은 순서)에 따라 input 간의 의존 관계가 있다는 개념이다. Sequence 모델의 전통적인 예로, 품사 태깅을 위한 hidden Markov 모델이나 conditional random field를 들 수 있다.

Recurrent neural network은 이러한 상태 개념을 가지고 다니는 network이다. 예를 들어 network의 output이 다음 input에 포함되어 진행되면서, 예전 정보가 연속적으로 network에 계속 전파될 수 있는 것이다.

LSTM의 경우, sequence의 각 (@@0@@번째) 요소마다 hidden state @@1@@를 갖게 되는데, 이 @@2@@는 원칙적으로 과거의 어떤 정보라도 가지고 있을 수 있다. 이 @@3@@를 이용해서 수 많은 일들을 할 수 있다. language model을 구축해서 단어를 예측할 수도 있고, 품사 태깅을 할 수도 있게 된다.

LSTM's in Pytorch

#LSTM's-in-Pytorch

본격적인 예제에 들어가기 전에, 몇 가지 알아둘 것이 있다.

Pytorch의 LSTM은 모든 input을 3D tensor라고 가정하고 받는데, 이 세 가지 축이 의미하는 바를 알아두는 것이 중요하다. 1. 첫 번째 축은 sequence 순서 정보를 의미한다. 2. 두 번째 축은 mini-batch의 순서 정보를 의미하는데, 여기서는 mini-batch에 대해 다룬 적이 없으므로 무조건 1차원을 가진다고 가정하겠다. 3. 세 번째 축은 input 순서를 갖는다.

만약 sequence 모델에 "The cow jumped"라는 문장을 넣고 돌린다면, input은 아래와 같이 생길 것이다.

@@0@@

이 와중에 위 tensor의 1차원이라 나타나지 않는 두 번째 축이 있음을 기억하자.

또한, sequence를 차례차례 보내지 않고 한 번에 보낼 수도 있다. 이 경우에는 첫 번째 축 역시 1차원이 될 것이다.

아래 간단한 예제를 보자.

Loading output library...

Example: An LSTM for Part-of-Speech Tagging

#Example:-An-LSTM-for-Part-of-Speech-Tagging

이번에는 LSTM을 이용해서 품사 태깅을 해보려고 한다. 또한 여기서는 ViterbiForward-Backward와 같은 알고리즘은 사용하지 않을 것이지만, LSTM이 어떻게 돌아가는 지 경험한 후에는 언급한 알고리즘들이 어떻게 사용될 수 있을지 생각해보는 것도 독자들에게 좋은 (꽤 어려운) 연습 문제가 될 것 같다.

품사 태깅 모델을 설명하겠다.

  • Input 문장을 @@0@@ 이라고 한다.
    @@1@@, 즉 각 단어 @@2@@는 단어장 @@3@@ 안에 속해있다.
  • @@4@@를 품사 모음으로 표시한다. 그리고 @@5@@를 단어 @@6@@의 품사로 표시한다.
  • 이제 단어 @@7@@의 품사에 대한 우리의 예측을 @@8@@로 표시한다.

이 모델은 structured prediction을 하게 된다. 이는 모델의 output이 sequence 형태의 @@9@@인 것을 의미한다.

이제 예측을 하기 위해서 LSTM 모델에 문장을 던져줘야 한다. @@10@@ 번째 순서의 hidden state를 @@11@@라고 표시하겠다. 그리고 모든 품사 태그에 고유한 숫자를 부여하겠다. 이는 지난 번 word embedding 예제에서 word_to_ix를 만들었던 것과 똑같은 이치이다. 그러면 @@12@@를 계산하기 위한 규칙은 다음과 같다.

@@13@@

Hidden state를 affine map에 태운 것을 log softmax로 취한 후에, 그 결과 중 가장 큰 값을 갖는 품사 태그로 예측한다는 의미이다. Affine map @@14@@의 target space 차원 값이 @@15@@인 점도 알아두자.

실제 코드로 들어가보겠다. Data를 준비하자.

모델을 만들겠다.

이제 모델을 훈련시키겠다.

Exercise: Augmenting the LSTM Part-of-Speech Tagger with Character-Level Features

#Exercise:-Augmenting-the-LSTM-Part-of-Speech-Tagger-with-Character-Level-Features

지금까지 다룬 LSTM 예제에서 각 단어는 embedding을 갖게 되고, 이 embedding이 sequence 모델의 input으로 들어갔었다. 이제 이 word embedding에 더해서 단어의 각 철자들에서 생기는 효과를 얹어보려고 한다. -ly 로 끝나는 영어 단어는 부사일 가능성이 굉장히 높다는 점을 생각해보면, 철자 레벨의 정보가 우리에게 굉장한 도움을 줄 수 있겠다 생각할 수 있다.

이제 몇 가지 표기와 규칙을 정하겠다.

  • @@0@@를 단어 @@1@@의 철자 레벨의 표현이라고 하겠다.
  • @@2@@는 기존 word embedding을 의미한다.
  • 그러면 sequence 모델의 input으로는 @@3@@와 @@4@@를 합친 것을 넣어줘야 한다.
    따라서 @@5@@이 5차원이고 @@6@@가 3차원이라면, LSTM은 8차원의 input을 받아야 할 것이다.

철자 레벨의 표현을 얻기 위해서는 LSTM이 단어의 철자들을 받아서 작동시키고, 그 결과인 최종 hidden state를 @@7@@로 하면 된다. 몇 가지 힌트를 주겠다.

  • 새로운 모델은 두 개의 LSTM를 갖게 될 것이다.
    POS 태그 점수를 위한 기존 LSTM에 더해서, 각 단어의 철자 레벨의 표현을 얻기 위한 LSTM 하나가 더 추가된다.
  • 철자들을 sequence 모델로 돌리기 위해서는 character embedding이 필요할 것이다. 이 character embedding이 철자를 위한 LSTM에 input으로 들어가게 될 것이다.

아직 성공하지 못했지만, 현재까지 발버둥친 역자의 흔적을 아래 남겨둔다.