9주차(1) - End-to-End Memory Network

2019. 3. 14. 13:53풀잎스쿨 NLP Bootcamp

논문링크: https://arxiv.org/abs/1503.08895

참고자료: (김성운님 발표자료) N2Nmem.pdf.pdf

추가참고자료: http://solarisailab.com/archives/690

Abstract

해당 논문에서는 End-to-End 방식을 이용한 Memory Network를 소개한다. 이 말은, 이전 버전의 Memory Network가 있는가? 라는 것으로 연결될 수 있을것이다. 결론부터 말하자면 이전 버전의 Memory Network는 존재한다. (https://arxiv.org/abs/1410.3916) 하지만 해당 논문에서는 딥러닝을 사용하지 않고 있는 관계로 생략한다.

이 논문에서는 Memory Network를 이용하여 Question Answering에 대한 문제를 풀고자 한다. (이전 논문까지는 Classification, Language Modeling, 또는 Neural Machine Translation을 다뤘지만 Question Answering은 아직 다루지 않았다)

여기서 Memory Network는 (정확히 말하자면 End-to-End방식의 Memory Network) 크게 3가지의 구조로 이루어진다.
  1. Input Sequence: 지문에 대한 사전정보. 질문에 대해 답변하기 위한 정보가 포함된다.
  2. Question Sequence: 질문에 대한 정보. Input Sequence의 어떤 부분을 살펴볼 것인가에 대한 단서가 된다.
  3. Answer: Question와 Input을 처리한 결과물. 답변에 대한 정보.
이러한 구조는 Question Answering을 처리하기 위한 큰 구조라고 생각하면 좋다.

이렇게 3가지의 구조로 처리하기 위해서는 Long-term Dependency에 대한 문제가 나타나게 된다. 여태까지 풀었던 문제는 한 문장 내에서 거의 모든 것을 처리(Classification, Sequence Labeling, Translation등)을 처리할 수 있었지만, Question Answering의 경우는 여러 문장에 걸친 정보를 탐색해야 하는 문제가 생긴다. 이 부분을 해결하기 위해서 기존 방식에서는 Supporting Fact라는 정보가 주어지게 된다. Supporting Fact라는 것은 어느 문장에 Question에 대해 관련이 있는가를 Labeling해놓은 것이다. (예를 들자면, 여러 문장이 주어지는데 주어진 질문에 대해 A문장은 관련이 있다/없다, B문장은 관련이 있다/없다, ...를 표시해놓은 것이다)

하지만 이 논문에서 제안하는 Memory Network는 이러한 Long-term Dependency문제를 해결하고, 또한 Supporting Fact 없이 어느 문장이 Question과 관련된 문장인가를 학습하는 구조를 제시하고자 한다.

Contribution

위 Abstract에서는 Question Answering에 대한 문제를 풀기 위해서라고 설명을 했지만, 엄밀히 말하면 두가지의 Task를 해결하고자 한다.

첫번째는, Abstract에서 이미 언급한 Question Answering이다. 주어진 지문이 있고 질문이 들어오면 답변을 해주는 구조이다. 해당 문제를 풀기 위해 bAbI 데이터셋(https://research.fb.com/downloads/babi/)을 사용하고 있다. bAbI는 20가지 주제의 문제로 구성되어있다. 지금은 상대적으로 많이 쓰이지 않는 데이터셋이다. (현재 Question Answering을 위해서는 SQuAD 데이터셋이 가장 많이 쓰인다.)

두번째는, Language Modeling이다. Language Modeling에 대해서는 기존 논문에서 설명을 했으니 넘어가도록 한다. Language Modeling을 위해서는 동일한 구조에 데이터셋만 다르게 (Penn Treebank, Text8 Dataset) 사용하는 방식이다.

Model Architecture


일단 이 그림에서 헷갈리기 쉬운 점은, Figure 1 전체가 Model의 큰 구조를 나타낸다는 점이다. (적어도 본인은 처음에 그렇게 헷갈렸다...) 해당 그림은 두 부분으로 나눠볼 수 있는데, (a)부분(왼쪽)은 모델 내의 각 Single Layer의 구조를 나타내고, (b)부분(오른쪽)은 모델의 전반적인 구조를 나타내고 있다. 따라서 여기서는 각 부분에 대해 따로 설명하고자 한다.


Single Layer


구조를 크게 살펴보면 다음 몇가지로 이루어져 있다.
  1. Question Encoding(q)와 Input Encoding(Embedding A)를 Input으로 받아 Attention을 Dot Product를 통해 계산하는 것으로 지문의 문장들과 질문의 Similarity를 확률로 표현
    1. 여기서 각 Setence를 Embedding한 결과는 Memory 벡터(m)이라고 칭함
    2. 질문 q의 Embedding한 결과는 벡터(u)라고 칭함
  2. 문장별로 주목할 정도를 학습함 (Soft Attention)
    1. 여기서 나온 결과물은 c_i로 표기 (Context)
  3. 문장들과 질문의 Similarity인 m_i를 Softmax로 Attention을 계산한 결과물인 p_i와 c_i를 곱해주는 것으로 Output 계산
  4. 여기에 output(o)과 Question을 Embedding한 결과물인 u를 곱해서 Softmax를 적용하는 것으로 최종 Prediction을 계산
    1. Embedding B = u
여기서 중요한 점은 Embedding A와 Embedding C는 같은 Sentence(Xi)에서 나옴에도 불구하고 다른 Embedding이라는 사실이다. 이러한 구조가 정확히 어떠한 구조로 돌아가는지는 아래 예시를 통해 알아볼 수 있다.



Layer-by-Layer Architecture

다음으로 전체적인 구조를 살펴보기로 한다. 여기서는 Embedding C(Sentence Attention)와 Embedding A(Sentence-Question Similarity)로 이루어져 있는 구조가 하나의 블럭이라고 보고 이러한 블럭을 쌓는 방식을 Residual Connection과 같은 방식으로 처리하고 있다. 이렇게 Residual Connection을 거치는 것으로 Question에 대한 Embedding(Embedding B)은 그대로 유지하는 방식을 취하고 있다. (u_k+1 = u_k + o_k)


Weight Details

여기서는 가중치를 설정하는 방법으로 두가지를 제시한다. 일단, 'Hops'라는 용어를 이해해야 하는데, 간단히 말하자면 앞서 말한 Layer 구조를 몇번 사용하느냐이다. 예를들어, Layer-by-Layer구조 그림에서 Single Layer구조가 3번 반복이 되고 있으므로 3 Hops인 것이다. 이렇게 Hop이 반복되는 과정을 거치고자 하면 Embedding A와 Embedding C의 Weight가 학습되게 되는데, 여기서 사용되는 Embedding A와 Embedding C의 Weight를 어떻게 설정하느냐에 대한 내용이다.

첫번째는 Adjacent 방식이다. 여기서는 k번째 Output Layer의 Embedding matrix가 다음 Input Layer에서 사용되는 Embedding의 Weight가 되는 것이다. 즉, 다음과 같은 방식이다.

또한 정답을 예측하는데 사용하는 Matrix는 마지막 Output Embedding과 동일하게 가져간다. (T: Token 길이, K: Hop갯수)이는 아래와 같은 수식으로 나타낼 수 있다.


두번째는 Layer-wise 방식이다. 여기서는 모든 Layer에서 사용되는 Embedding A와 Embedding C가 동일하다. (단 Embedding A != Embedding C이다. 즉, 두 Embedding은 다르다)

또한 Hop사이의 Residual Connection을 약간 변형해서 Question의 Encoding인 u_k(k번째 Hop의 Encoding)을 얼마나 감안할 것인가를 H를 통해 설정하게 된다.


Model Details

Encoding

모델에 대해 조금 더 설명을 해보려고 한다. 일단 Input/Question Encoding에 대해 알아보자. 우리는 Output을 계산할때 u와 o를 더해서 Hop마다의 Encoding을 계산하는 방식을 택하고 있다. 이때, 그냥 더하면 위치나 시간에 대한 정보가 사라지게 되는데, 이러한 경우를 방지하기 위해 Position Encoding과 Temporal Encoding을 사용한다.

Position Encoding은 Word Embedding 결과에 서로 다른 가중치를 곱해주는 방식이다. 이 방식을 취할 경우, 단어가 문장 안에서 순서가 바뀌는 경우, 메모리 Vector도 달라지게 된다.

Temporal Encoding은 문장 자체의 순서를 고려하기 위한 방식이다. 여기서는 문장의 순서가 영향이 있는 경우를 감안하고 있으며, 이를 위해 Time Embedding matrix를 별도로 학습하게 된다.


Random Noise

정확히는 Learning time invariance by injecting random noise라고 언급하고 있다. 학습 과정에서 Random empty memory를 넣어줌으로써 Regularization 효과를 얻는 방법이다.


Joint Learning

이 논문에서는 Question Answering을 학습하기 위해 bAbI 데이터셋을 사용하고 있다. 해당 데이터셋은 20가지의 Task로 이루어져 있는데, 학습시에 Task별로 따로 학습하는 것이 아닌 모든 Task에 대해 동시에 학습하는 방식이다.

Linear Start training

Local minima를 피하기 위한 방식이다. 일단 학습시에 Cost가 줄어들지 않을때까지는 Output Layer에서 Softmax를 적용하지 않은채로 진행한다. (u+o) 만약 학습 중 Cost가 더이상 줄어들지 않는 경우에 Softmax를 적용하여 진행한다. (Softmax(u+o))

Language Modeling

앞서 해당 논문이 Question Answering뿐만 아니라 Language Modeling에 대한 부분도 해결하고자 한다고 언급했다. Language Modeling에 대해 학습하기 위해서는 몇가지 셋팅을 해줘야 한다.
  • Question Vector는 0.1로 이루어진 Constant Vector이다. ([0.1, 0.1, ..., 0.1])
  • Memory Vector는 각 Word별로 학습하게 된다.
위 설정을 기반으로 아래와 같이 학습하게 된다.

Result & Conclusion

Results

해당 테이블에서는 적용 방법에 따른 결과를 분석하고자 한다. 각 용어는 다음과 같다.

  • PE: Positional Encoding

  • LS: Linear Start

  • RN: Random Noise

  • joint: Joint Training (for all tasks)

  • LW: Layer-wise weight tying (명시하지 않을 경우 Adjacent weight tying이 쓰인다)

일단 위 결과를 분석/요약하면 다음과 같이 나타낼 수 있다.
  • PE: 4, 5, 15, 18번 Task에 대해 나아진 결과를 보인다. (BoW에 비해)
    • 해당 Task들은 단어의 순서가 특히 중요한 Task들이다.
  • LS: local minima를 피하는데 충분히 효과적이었던 것으로 보인다.
  • RN: 특별히 효과적으로 보이지는 않지만 꾸준한 성능개션을 보인다.
  • Hops #: Hop이 늘어날 수록 계산량이 늘어남에 비해 성능 개션이 이루어진 것을 확인할 수 있다.


위 테이블에서는 Hop이 늘어날수록 얼마나 성능 개선이 이루어지는가에 대해 분석한다. 특히 Supporting Facts없이 얼마나 Target Sentence에 잘 근접할 수 있는가를 나타내고 있다.


여기서는 Memory Network의 Language Modeling에 대한 Task의 성능이 Hidden/Hop/Memory에 따라 얼마나 개선되는가 보여준다.


Conclusion

해당 논문은 End-to-End방식(Cost가 여러개가 아니라 하나만 계산되는 방식)을 통해 Question Answering과 Language Modeling에 대해 얼마나 성능 개선을 이루어 낼 수 있는가 보여줬다. 조금 더 생각해볼 수 있는것은, 과연 방식이 RNN을 이용한 방법에 비해 성능이 더 나을까 하는 부분이다. 또한 해당 구조는 CNN/RNN구조를 정확히 명시하지 않고 간단한 Dot Product와 같은 Matrix로 설명하고 있어서 만약 CNN이 적용되어야 할 부분에 RNN을 사용한다면 성능이 많이 달라질지에 대한 의문도 남아있다.