2019년 12월 2일 월요일

논문 리뷰 - Knowledge Enhanced Contextual Word Representations

EMNLP를 다녀왔습니다.
재밌는 논문들이 많았는데, 앞으로 그 중 몇 개를 포스팅 해보려고 합니다.

첫번째 논문은 Knowledge Enhanced Contextual Word Representations 입니다.


논문 정보


  • 논문 링크 : https://arxiv.org/pdf/1909.04164.pdf
  • 저자 : Matthew E. Peters et al. from Allen AI, UC Irvine.
    • ELMo를 쓴 Matthew E. Peters가 1저자로 참여한 논문입니다.
  • 발표 학회 : EMNLP 2019


요약


  • 기존의 Pretrained model(BERT)에 Knowledge base(Wikipedia, Wordnet) 같은 외부 지식을 결합하는 방법을 제안
  • 이런 메카니즘을 활용한 Pretrained model은 외부 지식을 반영하는 word representation을 만들수 있음
  • 결합하는 방법은 주로 attention을 활용하였고, 많은 부분 - 특히 Knowledge에 관련된 - 은 이미 개발되거나 공개된 데이터, 알고리즘 등을 활용.
    뭔가 설명이 없이 툭 튀어나오면 이미 있는 걸 활용한 거라 생각하면 됩니다...


Introduction


  • ELMo, GPT, BERT 같은 모델들은 SOTA를 달성했지만, real world entity에 대한 기반(grounding)이 없고 factual knowledge를 알기 힘들다(Logan et al. 2019).
  • Knowledge bases(KBs)를 활용하면, raw text에서 적은 빈도로 등장하거나 long range dependency 문제로 학습이 힘든 정보들을 학습할 수 있다.
  • 우리는 여러 KB들의 정보를 pretrained model에 주입할 수 있는 KAR(Knowledge Attention and Recontextualization)이란 메카니즘을 제안한다.
  • 특정 task를 위한 모델에 외부 지식을 활용했던 이때까지의 다른 접근법들과는 다르게 이 방법으로 여러 task에 모두 활용될 수 있는 general representation을 얻을 수 있다.
  • BERT-base 모델에 KAR을 통해 Wikipedia와 Wordnet을 결합했을 때 BERT-large모델보다도 더 좋은 실험 결과를 얻었다.

KnowBert


Knowledge Bases


  • KB에 있는 K개의 entity들은 E차원의 임베딩 벡터 e_k로 표현되어 있다고 가정한다.
  • 또한 KB는, text에서 C 개의 entity 후보와 그들의 start, end index를 찾아주는 entity candidate selector를 갖고 있다고 가정한다. 
  • Entity candidate selector는 각 entity가 어떤 종류의 entity인지에 대한 prior 확률도 갖고 있다. (Prince가 가수인지, 자동차인지에 대한 확률)
  • Candidate의 숫자는 고정된 작은 수자(30)으로 제한하여 실행 시간이 KB의 크기와 상관없어진다.

KAR



  • 보통의 transformer 구조에서  H_i+1 = Transformer(H_i)이다. 하지만 특정 한 레이어에서는 knowledge를 활용하는 H_i+1 = KAR(H_i) 연산을 수행한다. 
  • KAR은 아래와 같은 구성요소들로 이루어져 있다.

Mention-span representation(번호 1, 2)
  • 처음으로, 적은 차원(200 또는 300) 차원으로 projection한다.
  • Entity candidate selector에서 받은 정보들(entity의 list, 각 entity들의 span)을 이용하여, 각 entity(그림 상의 Prince, Purple-Rain, Rain)에 해당하는 hidden vector들을 뽑아낸다(S에 해당).
  • 각 entity의 span 안에 있는 word piece들에 대한 hidden vector들을 self-attentive span pooling(Lee et al. 2017)을 이용하여 각 entity 당 하나의 hidden vector - mention-span representations, S - 로 뽑아낸다.


Entity linker(번호 3, 4)
  • Entity linker는 어떤 candidate를 이용할 지 구분하는 역할을 한다.
  • Se = Transformer(S) 를 통해 mention-span 간의 attention을 반영한 representation을 구한다.
  • This allows KnowBert to incorporate global information into each linking decision so that it can take advantage of entity-entity co-occurence and resolve which of several overlapping candidate mentions should be linked.
  • Se는 각 후보 entity를 평가하고 KB에서 얻은 entity prior를 통합하기 위해 활용된다(Kolitsas et al.).

  • 각 후보 span m 에 해당하는 mention-span vector se_m과, KB를 통해 얻은 entity의 embedding e_mk, prior p_mk로 어떤 entity가 현재의 context에 잘 맞는지 score를 매긴다(attention weight와 비슷한 개념).
  • 이 때, 2 층의 MLP를 이용하며 hidden units은 100이다.

  • 이 때, 정답 entity를 알고 있으면 entity의 scoring을 좀 더 정확히 하기 위한 학습이 가능하다. EL은 entity linker의 약자이다.
  • 위의 식에서 g는 정답 entity의 인덱스를 의미하며, 정답 entity의 임베딩 벡터와 prior를 이용해 얻은 score를 loss function에 활용한다.

Knowledge enhanced entity-span representations(번호 5)

  • 후보 entity들 중 score의 값이 일정 threshold 이하인 score들은 0으로 간주하여 무시한다.
  • Threshold 이상인 score들은 softmax normalization한다.

  • 이렇게 계산한 score와 embedding을 weighted sum을 한 후,
  • 기준의 Se에 더하여 KB의 entity embedding을 반영한 새로운 entity-span representation을 만들어낸다.

Recontextualization(번호 6, 7)
  • 이렇게 얻은 S'e를 이용하여 기존의 word piece representation을 recontextualize한다.
  • 그리고, 다시 BERT의 hidden vector size로 projection한다.
  • 여기서 W2는 맨 처음 차원을 줄이기 위해 쓰인 파라미터 W1의 matrix inverse이다.


Training Procedure



  • 우선 각 KB에서 entity embedding을 계산해야 한다. Entity embedding은 한 번 학습된 후에는 고정된다.
  • Entity linker를 학습시킬 수 있으면 다른 네트워크의 파라미터들은 고정시킨 채 미리 학습시켜 KB에 특화된 EL을 만든다.
  • 이후 최종적으로 Masked language model의 loss와 entity linker의 loss를 더하여 학습한다.
  • 여러 KB를 쓸 경우 각각 다른 레이어 사이에 배치한다.
  • Candidate mention span에 masking된 word piece가 하나라도 있을 경우 전체 entity들 word piece를 마스킹한다.

Experiments





  • Language Modeling 실험 결과. 위 실험에서 KnowBert는 BERT_base모델에 KAR을 적용한 모델이다.


  • Relation extraction task에서 좋은 성능을 기록했다.


Conclusion



  • KB를 효과적으로 language model에 반영할 수 있는 방법을 제안한다.
  • 실험을 통해 알고리즘의 효용성을 입증하였다.

2019년 12월 1일 일요일

맥북 포맷 에러 : no packages were eligible for install. contact the software manufacturer for assistance

회사에서 맥북을 더이상 안쓰려고... 포맷하고 반납했다.
포맷을 하는데

https://techsparx.com/computer-hardware/apple/macosx/install-osx-when-you-cant.html
위 그림처럼 이상한 에러가 났다.

내 경우, 해결책은 해당 버전 OS-El Capitan - 가 출시될 때 쯤의 날짜로 돌리는 것이었다.
대략 2015년 11월 쯤으로 했다.

방법은,
https://techsparx.com/computer-hardware/apple/macosx/install-osx-when-you-cant.html

Utilities -> Terminal을 열고
`date 1108080815` 명령어를 입력한다.
숫자는 [월][날짜][시간][분][연도] 형식을 따른다.

2019년 11월 25일 월요일

Is language modeling Self-supervised or Unsupervised?

도대체 Language model은 Unsupervised 모델인가? Self-supervised model인가? 둘 다인가?

Unsupervised


"Language modeling is usually framed as unsupervised distribution estimation"
https://arxiv.org/pdf/1810.04805.pdf

"Another notable family within unsupervised learning are autoregressive models, in which the data is split into a sequence of small pieces, each of which is predicted in turn. Such models can be used to generate data by successively guessing what will come next, feeding in a guess as input and guessing again. Language models, where each word is predicted from the words before it, are perhaps the best known example"
https://deepmind.com/blog/article/unsupervised-learning

"Unlike Peters et al. (2018a) and Radford et al. (2018), we do not use traditional left-to-right or right-to-left language models to pre-train BERT. Instead, we pre-train BERT using two unsupervised tasks, described in this section. This step is presented in the left part of Figure 1."
https://arxiv.org/pdf/1810.04805.pdf (BERT paper)



Self-supervised



"This idea has been widely used in language modeling. The default task for a language model is to predict the next word given the past sequence. BERT adds two other auxiliary tasks and both rely on self-generated labels."
https://lilianweng.github.io/lil-log/2019/11/10/self-supervised-learning.html

ALBERT: A Lite BERT for Self-supervised Learning of Language Representations
https://arxiv.org/abs/1909.11942

"A robustly optimized method for pretraining natural language processing (NLP) systems that improves on Bidirectional Encoder Representations from Transformers, or BERT, the self-supervised method released by Google in 2018. BERT is a revolutionary technique that achieved state-of-the-art results on a range of NLP tasks while relying on unannotated text drawn from the web, as opposed to a language corpus that’s been labeled specifically for a given task."
https://ai.facebook.com/blog/roberta-an-optimized-method-for-pretraining-self-supervised-nlp-systems/



Self-supervised is Unsupervised


Self supervised learning is an elegant subset of unsupervised learning where you can generate output labels ‘intrinsically’ from data objects by exposing a relation between parts of the object, or different views of the object.
https://towardsdatascience.com/self-supervised-learning-78bdd989c88b



결론은... 자기 마음대로 정의해서 쓴다.

2019년 11월 21일 목요일

TPU 사용 시 storage 관련 문제(HTTP 403, OutOfRangeError) 해결법

TPU에서 bert를 학습시키려고 했다.

VM 접속부터 여러 난관들이 있겠지만 ㅋㅋㅋ
Storage에 관련된 문제들이 두 개가 발생했다.


1. Checkpoint를 저장할 때 생기는 문제

Permission denied: Error executing an HTTP request: HTTP response code 403 with body '{
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "my_account_email does not have storage.objects.list access to object.~~."
}

2. OutOfRangeError (see above for traceback): End of sequence 에러


해결법
해결법은 내 tpu 서비스 계정에 storage에 대한 owner 권한을 주는 것이다.
Tpu 서비스 계정은 tpu를 누르면 맨 아래쪽에 표시된다.
형식은 service-{project 번호}@cloud-tpu.iam.gserviceaccount.com 이다.
프로젝트 번호는 Google cloud console 메인 페이지에 가면 project id 밑에 보인다.

Tpu 서비스 계정을 알았으면, 로컬 터미널에서 아래 명령을 실행하면 된다.
gsutil acl -r ch -u TPU계정:OWNER STORAGE_BUCKET_주소

* 참고 사항
READER WRITER 두개의 권한을 부여했더니 안 됐고, 꼭 OWNER 권한이 있어야 되는 것 같다.

-r 옵션은 recursive 옵션 같은데, 폴더 별로 따로 권한을 설정할 수도 있겠지만 최상위 폴더에 -r 옵션을 주어서 한 번에 전체 권한을 주는게 가장 속 편한 것 같다.
-r 옵션이 없으면 해당 폴더에만 권한이 생기고 하위 폴더에는 권한이 안 생기는 것 같다.
학습용 데이터와 학습된 모델을 다른 폴더에 저장하는 게 편할 것이기 때문에 폴더에 권한을 각각 주는 것보다 -r을 쓰는 게 좋을 듯하다.

2019년 11월 20일 수요일

Flask(web server) 상에서 matplotlib.pyplot 사용시 프로세스가 죽을 때

Tensorflow의 수행 결과를 간단하게 보여줄 데모 페이지를 만들게 되었다.
환경을 Flask - TF serving으로 구성하고, flask 상에서 matplotlib로 그래프를 만들어 페이지에 띄우도록 했다.
그런데 일정 횟수 이상으로 결과를 뽑으면 maplotlib 상에서 쓰레드 또는 메모리 관련 문제가 생겨 flask 프로세스가 죽는 문제가 발생했다.

이에 검색을 좀 해보니 홈페이지에 사용법을 설명해 놓아 따라해보니 문제가 해결되었다.
링크 : https://matplotlib.org/faq/howto_faq.html

Matplotlib 3.1 이전 버전의 경우
import matplotlib
matplotlib.use('Agg')
코드만 추가해주면 해결되었다.


-------------------------------------------------------------------------------------------------
그 이후 버전의 경우, 홈페이지의 코드대로
from matplotlib.figure import Figure
를 이용하면 되는 듯했다.

홈페이지 코드를 보면 pyplot없이 Figure()만으로 그래프를 그릴 수 있는 것 같은데 정확히는 모르겠다.
코드에 show()가 없는 것으로 봐서는 클라이언트에 전송하기 위한 용도로만 코드를 짠 것 같다.
Figure를 사용한 예제는 거의 pyplot.figure()던데...

2019년 10월 17일 목요일

Linux에 PyQt4 설치하기

Linux에서 Python matplotlib를 쓰기 위해 PyQt4를 설치해야 했다.
쉽게 되지 않아 그 과정을 정리해봤다.

1. tar 압축 파일을 다운받아서 풀고, 컴파일하는 방법 : 링크

근데, 위의 방법으로 했을 때 안 되는 경우가 있어서 다른 방법을 찾았다.


2. 훨씬 간단하다. 명령어 한 줄이면 된다. 링크 
`sudo apt-get install python-qt4 python-sip`


Python2, 3 모두에서 잘 동작한다.

추가적으로, 서버에 설치했을 땐 `ssh 아이디@접속주소 -X ` 이렇게 -X 옵션을 주면 XWindows로 GUI를 볼 수 있다.

2019년 8월 20일 화요일

Inductive bias란?


인공지능에 대한 논문을 읽다보면 inductive bias란 용어를 자주 본다. 하지만 inductive bias가 정확히 어떤 의미인지 설명해놓은 곳을 찾기가 힘들어, 정리해보려고 한다.

--------------------------------------------------------------------------------------------------------------

일단 영문 위키의 정의를 보면, "The inductive bias of a learning algorithm"은 학습 시 보지 못한 입력에 대한 출력을 예측할 때 사용된 가설들이다.

예를 들어, 데이터를 0과 1로 구분하는 함수 f를 학습시킨다고할 때, 이 f를 어떤 함수들의 집합에서 골라야할 지를 지정해야 한다. 그리고 어떤 함수를 선택해야할 지에 대한 기준을 설정할 필요가 있다.

학습 데이터를 완벽하고 가장 쉽게 반영하는 함수는 테이블이다(모조리 기억하는 것). 이 데이터가 입력됐을 때의 출력은 저것이라고 지정하는 방식이다. 하지만 inductive bias의 정의에 나와 있듯이, 이 방식은 "학습 시 보지 못한 입력"에 대해서는 아무런 답을 주지 못한다.

그래서 함수 f를 가능한 가설로부터 찾아낸다고 하고, 가설공간을 H로 표기한다. 그리고 이 H에 대해 제약 조건을 설정한다. 이 때의 제약 조건을 inductive bias 또는 bias라고 한다. 이런 bias를 기준으로 이용하여 여러 가설들 중 하나를 선택할 수 있다.

이런 inductive bias의 예시는 아래와 같은 것들이 있다.

  • Maximum margin : 분류 공간을 나눌 때, 경계와의 margin을 가장 크게 하는 가설을 선택하겠다는 것으로, support vector machine에서 사용하는 inductive bias이다.
  • Minimum description length : 가장 단순한 가설이 맞을 확률이 높다는 가정 하에, 그러한 가설을 찾겠다는 inductive bias이다. Information gain을 줄이는 방식으로 학습하는 decision tree에서 사용한다.
  • 그 외에 Nearest neighbors(k-nearest neighbors), Maximum conditional independence(Naive Bayes classifier), Minimum features 등이 있다.

Inductive bias는 그냥 bias라고 불리기도 하며, bias-variance trade-off란 용어에 나오는 그 bias이다.


참고 사이트

http://blog.naver.com/PostView.nhn?blogId=cake54&logNo=40108485351

https://en.wikipedia.org/wiki/Inductive_bias

http://www.aistudy.com/ai/learning_dean.htm

http://axon.cs.byu.edu/~martinez/classes/478/slides/Bias.pdf

2019년 7월 22일 월요일

논문 설명 - Transformer-XL : Attentive Language Models Beyond a Fixed-Length Context

이번 포스트에서는 Transformer-XL 모델에 대해 써보려고 합니다.

지난 포스트 이후 Universal Transformer 논문을 읽고 정리를 하려고 했으나 워낙 정리를 잘 해놓은 블로그가 있어서 패스하고, 설명이 별로 없었던 Transformer-XL에 대해 쓰려고 했는데, 이해가 잘 안가는 부분들이 많아서 계속 미루어졌습니다. 

그 후에, Transformer-XL을 활용한 XLNet이 나오면서 사람들이 좀 더 관심을 갖게 됐을 것 같은데, 여전히 XLNet에 대한 포스트만 많고, Transformer-XL에 대해서는 별로 없는 것 같습니다. 이 포스트가 Transformer XL 모델을 이해하려고 하는 분들에게 도움이 되길 바랍니다.

논문 정보


저자 : Zihang Dai, Zhilin Yang, Yiming Yang, Jaime Carbonell, Quoc V. Le, Ruslan Salakhutdinov

굉장히 유명한 연구자 두 명의 이름이 보이네요. Quoc V. Le, Ruslan Salakhutdinov!

글을 쓰면서 찾아보니 신기하게도 Universal Transformer는 ICLR 2019에 accept 되었는데, Transformer-XL은 안 됐네요. 쓰다보니 ACL 2019에 aceept된 걸로 나오네요.


요약


기존의 transformer는 고정된 개수의 token들을 갖는 한 개의 segment만을 input으로 사용하여, 연속된 segment들 간의 dependency를 반영하지 못했습니다. 이에 저자들은 현재 segment를 처리할 때, 이전 segment를 처리할 때 계산된 hidden state들을 사용하는 recurrence를 추가하여 이런 문제을 해결하고, 그에 맞게 positional encoding을 변형하였습니다. 이렇게 제안된 Transformer-XL은 Language Modeling에서 State-of-the-art의 성능을 기록하였습니다.


Introduction


Language Modeling task에 많이 쓰였던 RNN 계열의 LSTM은 보통 200 단어(step) 정도를 참고한다고 합니다. 많이 쓰이던 LSTM 외에도, attention을 활용하여 long-term dependency를 학습할 수 있고, 학습 속도와 성능도 개선된 transformer를 사용하여 language modeling을 수행한 시도도 있었습니다. Transformer를 활용하여 character-level language modeling을 수행한 결과 LSTM보다 훨씬 더 좋은 성능을 보였습니다(Al-Rfou el al).

하지만 기본적인 transformer 구조를 그대로 이용하면, input으로 사용되는 segment 안의 character들간의 dependency만 학습할 수 있고, segment 간의 dependency를 학습하지는 못합니다. 그리고 이런 segment들은 문장의 구분, 의미적인 구분이 없이 단순하게 character의 개수를 기준으로 분리되었습니다. 이로 인해 한 segment 안에서, 처음 몇 개의 character를 예측할 때 사용할 수 있는 정보들이 별로 없습니다. 이 문제를 저자들은 'context fragmentation'이라고 부릅니다.

이런 문제를 해결하기 위해 Transformer-XL이란 모델을 제안합니다. 이 모델은 기존의 self-attention 기반 모델에 recurrence 개념을 추가한 모델입니다. 새로운 segment의 hidden state를 계산할 때 이전 segment에서 계산한 hidden state를 이용합니다. 이렇게 재사용된 hidden state는 segment들을 recurrent하게 연결해주는 memory의 역할을 합니다. 그래서 segment들 간의 long-term dependency를 모델링할 수 있게 됩니다. 또한 이런 모델링으로 'context fragmentation' 문제를 해결할 수 있습니다. 그리고 이렇게 모델링하면 추후에 설명할 relative positional encoding이 필요합니다. Recurrence를 추가하는 것과 relative positional encoding은 독립적으로 적용되지 않고, 같이 쓰일 때 큰 의미를 갖습니다. 

이렇게 제안된 Transformer-XL은 character-level language modeling을 포함한 5개의 데이타셋에서 좋은 결과를 냈습니다. 또한 coherent한 긴 text를 만들어내는 것도 가능합니다.


모델 설명


Vanilla Transformer Language Model


위에서 설명한 것처럼 segment 단위로 language modeling을 학습하면, segment 크기를 넘어서는 long-term dependency를 학습할 수 없고, 문장이나 의미를 고려하지 않고 segment가 나눠지는 'context fragmentation' 문제가 발생합니다. 


추가적으로, 이런 방식은 학습이 끝나고 prediction을 수행할 때 중복된 연산이 많아집니다. Prediction 단계에서는 한 segment를 이용하여 segment의 맨 마지막 한 개의 위치에 올 token만 예측하게 됩니다 - [x1, x2, ... xt-1]을 이용하여 xt를 예측. 그리고 segment를 한 칸 옆으로 이동하여 그 다음 위치에 올 token을 예측하게 되는데 - [x2, x3 .. xt]을 이용하여 xt+1을 예측, 이 때 겹치는 token들에 대한 연산을 다시 수행해야 합니다. 아래 그림에서 표시된 부분은 총 3 번의 prediction 단계에서 중복된 연산을 수행하는 영역 - [x3, x4] - 을 나타냅니다.

이런 prediction 방법은 training 때와 달리 항상 segment 길이만큼의 context를 활용하여 다음 token을 예측하며 training을 할 때보다 'context fragmentation' 문제의 영향을 덜 받습니다. 하지만 그만큼 중복되는 연산량이 굉장히 많아집니다. Transformer-xl은 이런 연산량을 줄여 prediction의 속도도 빠르게 향상시킵니다.

Segment-Level Recurrence with State Reuse


이와 같은 문제들을 해결하기 위해 transformer 구조에 recurrence 메카니즘을 도입합니다. 학습 시에, 이전 segment를 처리할 때 계산된 hidden state를 사용합니다. 이전 segment의 hidden state를 활용하면 이전보다 더 긴 long-term dependency를 학습할 수 있게 됩니다.

첫번째 그림에서, x5 시점에서 다음을 예측할 때 x2, x3, x4의 hidden state들을 활용하는 것을 볼 수 있습니다. Recurrence 메카니즘이 없었다면 x5의 input만 참고하여 예측했을 것입니다. 이렇게 항상 segment의 max input개수만큼 예측에 참고할 수 있는 장점이 생깁니다.

이전 segment의 hidden state들이 다음 segment를 처리하기 위해 사용될 때는 gradient에 따라 학습시키지 않고 고정시킵니다. 이 때 학습되는 weight들은 현재 segment에 속한 weight들 뿐입니다.

학습 과정을 수식으로 나타내면 아래와 같습니다.
n : Layer의 층수
h_T : 길이가 L인 input [x_1, x_2 .. x_L]
h_T+1 : h_T의 뒤에 이어진 길이가 L인 input [x_L+1, x_L+2 .. x_L+L]
SG : stop-gradient
[h_u ㅇ h_v] : 두 hidden state를 concatenate.
수식에 나와 있듯 self-attention의 key, value를 계산할 때 이전 segment의 hidden state와 현재 segment의 hidden state를 concatenate하여 얻은 벡터를 이용합니다(h 위의 ~표시).

이런 recurrence 메커니즘은 segment 단위의 recurrence를 만들어냅니다. 그래서 필요한 context가 두 개의 segment를 넘어서서 여러 segment에 걸쳐 전파될 수 있습니다. 하지만 기존 RNN의 recurrence와 다른 점은, recurrence가 두 layer에 걸쳐서 만들어진다는 점입니다 - recurrence가 만들어질 때 layer의 층이 하나 증가합니다; RNN에서의 recurrence는 같은 층에서 만들어지죠. 그래서 가장 긴 dependency 길이가 N X L(N : layer 수, L : segment 길이)이 됩니다. 이 구조는 truncated BPTT를 이용한 RNN과 비슷합니다(BPTT에서 backpropagation time-step을 제한한 알고리즘) .

Recurrence를 활용하면 evaluation(prediction)이 훨씬 빨라집니다. Prediction 시, 이전 segment의 계산 결과를 저장해놓고 활용할 수 있기 때문에 매번 다시 계산할 필요가 없어집니다. 실제로 enwiki-8 데이터를 사용한 실험에서 vanilla 모델보다 1800배 이상 빠른 속도를 보여줬다고 합니다.


Relative Positional Encodings


Transformer 구조에 recurrence 메카니즘을 적용하면 문제가 하나 생깁니다. 바로 transformer 구조에 사용되는 포지션 정보를 어떻게 추가할 것인가 하는 문제입니다. 이전 segment에 사용된 포지션 정보가 현재 segment에도 변함없이 동일하게 적용되기 때문에 h_T[1](이전 segment의 첫번째 input)에 더해진 포지션 정보와 h_T+1[1](현재 segment의 첫번째 input)에 더해진 포지션 정보가 같습니다.

이 문제를 해결하기 위해 기존의 'absolute' 포지션 정보가 아닌 'relative' 포지션 정보를 주입합니다. 'Absolute' 포지션 정보는 현재 input token의 절대적 위치 - 첫번째, 20번째 같은 위치 - 에 대한 정보를 의미하며, 이 포지션 정보는 두 token 간의 attention을 계산할 때 활용됩니다.

Query인 Q와 Key인 K 사이의 attention을 Q^T * K - 수식 (1) - 로 계산하는데요,
여기서 Q = (E + U) * Wq, K = (E + U) * Wk로 얻을 수 있습니다. E는 토큰 임베딩이며 U는 포지션 정보입니다.
이걸 수식 (1)에 대입해보면
위와 같은 식을 얻고, U에 인코딩된 i번째, j번째 absolute 포지션 정보을 통해 두 단어 간의 위치 차이를 반영합니다.

'Absolute' 포지션 정보가 두 수의 차이를 계산하기 위해 a=1, b=2 이렇게 값을 지정하고 그 값으로 차이를 계산하는 방식이라면,  'relative' 포지션 정보는 두 수의 값과는 상관없이 두 수의 차이 값만 갖고 있는 방식입니다. a=1, b=2이든 a=5, b=6이든 상관없이 두 수(위치)의 차이가 1이라는 것만 알려주면 됩니다. 이 방식을 이용한 attention 계산을 수식으로 나타내면 아래와 같습니다.


위의 식에서 R이 'relative' 포지션 정보를 encoding한 matrix를 가리키며 기존에 쓰이던 U를 대체하고 있습니다. 아래 첨자로 표시되어 있듯이 i, j 두 위치의 차이에 대한 포지션 정보를 담고 있습니다. 그리고 R은 'Attention is all you need'에서 제안한 방식대로 학습되는 matrix가 아닌 sinusoid encoding matrix를 그대로 사용합니다.

추가적으로 벡터 형태의 u, v 파라미터가 도입되었습니다. 두 벡터는 query 단어의 위치와 상관없이 같은 값을 갖습니다. 절대 위치를 사용하지 않고, 상대 위치 정보는 R을 통해서만 알 수 있기 때문에 기존 A^abs을 구하는 식의 (c), (d)처럼 Ui * Wq를 계산할 필요가 없습니다(못합니다, 절대 위치 정보인 U가 없기 때문이죠.). 그래서 Ui * Wq를 u, v로 대신하였습니다.

그리고 Wk를 W_k,E와 W_k, R로 분리하였습니다. W_k, E는 token의 임베딩을 이용한 attention 계산에 쓰이고, W_k, R은 상대 위치 정보를 반영한 attention을 계산할 때 쓰입니다.

Technically, it expands the simple multiplication of the Attention Head’s Score (QiKj) to include four parts:  
  1. Content weight – the original score without the addition of the original positional encoding of course.
  2. Positional bias with respect to the current content (Qi). It uses a similar sinusoidal function that receives the distance between tokens (e.g. i-j), instead of the absolute position of the current token.
  3. A learned global content bias – The model adds a learned vector that adjusts the importance of the other token content (Kj).
  4. A learned global bias – Another learned vector that adjusts the importance based only on the distance between the tokens (e.g. the last previous words are probably more important than a word from a previous paragraph).
출처 : https://www.lyrn.ai/2019/01/16/transformer-xl-sota-language-model/

위 수식을 다시 묶으면 아래와 같습니다.
출처 : https://www.notion.so/Transformer-XL-Attentive-Language-Models-Beyond-a-Fixed-Length-Context-19-06-23-62ecd6bfb61b47d1aa3e3a3c91fe2bae

최종적인 Transformer-XL의 계산 과정은 아래와 같습니다.
위의 식에서 m_T는 현재 input segment T가 사용되기 이전에 T-1, T-2 등을 이용하여 이미 계산한 결과를 저장하는 메모리를 말합니다.


Experiments


Main Results



여러 데이터를 이용한 word-level, character-level language modeling에서 sota를 기록했습니다. 문장들이 섞여 있어 long-term dependency가 없는 One Billion Word dataset(table 4)에서도 가장 좋은 성능을 기록한 것이 인상적입니다.

Ablation Study


Transformer-XL에서 제시한 recurrence 메카니즘과 relational positional encoding의 효과를 알아보기 위해 ablation study를 진행했습니다.


Encoding 방법들의 종류는 총 3가지인데, 그 중에서 Saw et al.(2018)은 또다른 relative encoding 방식을 말하며, Vaswani et al.과 AlRfou et al.은 absolute encoding 방식을 뜻합니다.
Half loss는 segment의 뒤쪽 반에만 cross entropy loss를 적용했다는 것을 의미하는데요, absolute encoding 방식이 half loss를 사용했을 때는 잘 동작했다고 합니다. Attention을 조금밖에 사용하지 못한 앞쪽에서 생긴 loss를 제외시켰기 때문입니다. 사실 이 loss를 적용해 본 의미를 잘 모르겠네요.
PPL init은 training할 때 사용한 attention 길이를 evaluation할 때도 그대로 사용했다는 뜻이며, PPL best는 evaluation할 때 attention 길이(사용하는 context - input token의 길이)를 증가시켜가며 얻은 가장 좋은 결과를 의미합니다. 그리고 PPL best를 달성하기 위해 필요한 최소 attention 길이를 Attn Len으로 표기했습니다. 실제 training 시 사용된 attention 길이는 120입니다(글설명하는 글에는 128이라 되어 있는데, 표에는 120으로 되어 있네요;). Atten Len이 커진다는 것은 그만큼 evaluation 시 많은 context를 반영하여 성능을 높일 수 있다는 뜻입니다.

첫번째 실험과 그 다음 실험을 비교해보면, 이 논문에서 제시된 relative positional encoding 방식이 얼마나 효과적인가를 알 수 있습니다. Attn Len이 많이 차이가 나는 것을 볼 수 있습니다. 그리고 전반적으로 recurrence 메카니즘이 적용됐을 때 성능이 개선된 것을 알 수 있습니다.
맨 마지막 블럭을 보면 evaluation 시 attention 길이를 증가시키면 PPL best도 좋아지는 것을 볼 수 있습니다.

Transformer-XL은 recurrence 메카니즘으로 인해 더 많은 메모리가 필요하게 되는데요, 같은 메모리를 사용하도록 제한된 상황에서도 recurrence를 사용한 모델이 더 좋은 성능을 보여주었습니다.



Relative Effective Context Length


기존의 Effective Context Length(ECL)의 문제점을 개선한 RECL이란 평가 지표를 제안합니다. ECL은 context 길이를 늘려가면서 일정 threshold 이상 성능이 증가하는지를 확인하고, 성능 향상이 멈췄을 때의 context 길이를 말합니다.

이 지표의 문제점은 "ECL ignores the fact that it is harder to get improvement when a model already achieves a lower perplexity using only a shorter context, and thus it is not suitable for fair comparison among multiple models" 이라고 합니다. "한 모델이 짧은 context만 갖고 lower perplexity를 달성했다면 더 이상 성능 향상이 어렵고, 이 때문에 여러 모델 간의 공정한 비교가 어렵다." 즉, 모델마다의 특성이 있기 때문에 모델마다 다른 값을 가지며, 비교 지표로 삼기 어렵다 라는 뜻 같습니다. 아마 어떤 모델의 ECL이 길다고 해서 꼭 성능이 좋은 것은 아니다라는 뜻인 것 같습니다.
대충 무슨 말인지 잘 모르겠다는 말입니다ㅜㅜ 앞뒤 문장이 어떻게 'thus'로 이어지는지... 비교 지표로 적합하지 않다라는 말만 알아듣겠네요.

아무튼! 이에 저자들은 비교 대상인 여러 모델들에게 공통적으로 적용할 수 있는 지표인 Relative Effective Context Length를 제안합니다. 수식이 좀 복잡하여 제외하였지만, 비교 대상인 모델들 가운데 가장 좋은 성능을 공통의 평가 지표로 삼아 context length를 늘릴 수 있는지 없는지를 판단합니다.
파라미터 r은 전체 전체 토큰들 중 loss를 계산하는 데 사용할 토큰의 비율을 나타내며, loss 값이 가장 큰 토큰들을 우선하여 선택합니다. 첫번째 비교군은 {Transformer-XL, QRNN, LSTM}이며, 두번째 비교군은 {Transformer-XL, 기존 구조에서 인코딩 방식 변경, 기존 구조에서 recurrence만 제거, Transformer}입니다. 비교군끼리는 같은 수의 파라미터를 가졌으며, 그룹이 다른 모델들 간의 비교보다는 그룹 내의 모델들끼리의 비교가 중요한 것 같습니다.


여러 모델들 중 Transformer-XL의 RECL이 가장 길었으며, relative positional encoding과 recurrence 메카니즘의 효과도 알아볼 수 있는 실험이었습니다.



참고 사이트

Tae Hwan's TIL Paper(or etc.) :
https://www.notion.so/Transformer-XL-Attentive-Language-Models-Beyond-a-Fixed-Length-Context-19-06-23-62ecd6bfb61b47d1aa3e3a3c91fe2bae

LyrnAI Deep Learning explained :
https://www.lyrn.ai/2019/01/16/transformer-xl-sota-language-model/

AI Information
https://ai-information.blogspot.com/2019/06/nl-040-transformer-xl-attentive.html

2019년 6월 13일 목요일

논문 리뷰 - BERT Rediscovers the Classical NLP Pipeline

BERT에 대해 분석한 또다른 논문입니다. "What do you learn from context? Probing for sentence structure in contextualized word representations" 논문을 쓴 Ian Tenney, Dipanjan Das, Ellie Pavlick이 수행한 후속 연구에 대한 논문인 듯 합니다. 위 논문에 대한 리뷰는 여기서 볼 수 있습니다.

논문 링크 : https://arxiv.org/pdf/1905.05950.pdf

요약

BERT의 하부 레이어는 syntactic한 분석을, 상부 레이어는 semantic한 분석을 수행한다.


실험 내용

실험 내용은 "What do you learn from context?" 논문과 거의 같습니다. 다만 이 논문에서는 BERT에 대해서만 분석합니다. 각 task들을 수행할 때 pre-train 된 파라미터들을 freeze하고 실험을 수행합니다.


Metrics

1. Scalar mixing weights

각 task에 맞는 classification을 위해 쓰이는 마지막 linear + softmax layer의 input을 각 layer들의 output을 weighted sum을 하여 얻습니다.
t는 task를 의미하고, i는 각 input 토큰의 index 뜻합니다. s가 각 layer에 곱해지는 스칼라 weight를 의미하며 각 layer의 weight들로 softmax를 수행한 값입니다. 감마는 scaling을 위한 파라미터 같습니다.

이렇게 구한 h로 classification을 수행하면 학습된 s를 통해 어떤 layer의 정보를 많이 참조하였는지 알 수 있습니다.

또한 아래와 같이 Center-of-Gravity를 정의하여 각 task 별 특성을 파악할 수 있습니다.
각 task에서 가장 많이 참조한 layer를 평균적으로 나타낸 지표입니다.

2. Cumulative scoring

한 layer가 추가될  때마다 얼마나 성능이 변화되었는지를 측정합니다.
P(l)은 훈련이 완료된 전체 모델에서 l번째까지의 layer를 사용한 모델입니다.  Cumulative score들을 이용해 아래와 같이 expected layer를 구합니다. Center-of-Gravity와 거의 같은 개념입니다.
각 task에서 최고 성능을 내기 위해 평균적으로 필요한 layer의 수라고 생각하면 될 것 같습니다.


실험 결과


보라색 막대그래프의 숫자는 center-of-gravity이며 파란색 그래프의 숫자는 expected layer입니다.

위의 실험 결과를 보면 POS tagging -> Constituents -> Dependency -> SRL -> Coreference 순으로 높은 층의 정보를 많이 활용한다는 것을 알 수 있습니다. 이를 통해 Syntactic한 정보는 low layer에, semantic한 정보는 high layer에 위치한다는 것을 알 수 있습니다.

각 layer에 대한 weight와 cumulative score는 아래와 같습니다.
K(x) 값은 KL(x||Uniform) 을 의미하며 cumulative score와 weight가 얼마나 uniform 한지를 나타냅니다. 0에 가까울수록 uniform합니다.

Syntactic한 task들의 weight들이 spiky(특정 layer의 weight들이 다른 layer들의 weight들에 비해 눈에 띄게 높다)한 특성을 보입니다. 반면 semantic한 task들의 weight들은 전반적으로 고루 퍼져 있습니다. 어쩌면 이를 통해 BERT가 이런 semantic한 task를 위한 정보를 저장하는 데 아직 부족하다고 유추해볼 수도 있습니다. BERT 모델의 semantic한 task들의 수행 능력에 대해서는 아직도 추가 연구가 필요해 보입니다.

대부분의 task들에서 하부 레이어들만 이용해도 거의 최고 성능에 근접하는 것을 볼 수 있습니다. 논문에서는 "heuristic shorcuts : ... many cases can be guessed from shallow statistics" 라는 표현을 썼습니다. 그렇지만 mixing weights는 비교적 상부의 정보들을 이용하는 것으로 보입니다.
그리고 특이한 점으로, weights의 분포가 일부 layer들에 몰려있는 경우 cumulative score가 높은 layer 또는 바로 그 다음 layer에 대한 weight가 높게 나왔다는 점입니다.

예시로 두 문장에 대한 분석을 보여줍니다.
여기서는 base 모델을 사용했습니다. (a) 예시에서는 하부 layer에서 모델이 'toronto'를 지명이라고 예측합니다. 하지만 SRL task에 의해 'toronto'가 'smoked"의 대상이 되는 것으로 판단한 후 ORG로 예측을 변경하게 됩니다.비슷하게 (b) 예시에서는 하부 layer에서  'today'를 시간을 나타내는 NN(POS), DATE(Entity)로 인식하지만 상위 layer로 갈 수록 "china today"를 proper noun으로 인식하면서 entity 종류와 semantic role을 변경시켜나가는 것을 볼 수 있습니다.

결론

실험을 통해 BERT 내부에서 layer 층이 높아지면서 전통적인 NLP pipeline에 해당하는 task들을 수행한다는 것을 보였습니다. 또한 위의 예시와 같이 하부 layer에서 부정확한 예측을 하더라도 상위 layer에서 예측을 수정했을 때 어떤 일이 벌어지는가를 분석하여 보여주었습니다. 오히려 syntactic -> semantic 순으로 분석하는 게 아니라 semantic 정보를 활용하여 syntactic 정보를 개선해나가는 경우도 있었습니다.

결론적으로 딥러닝 모델이 syntactic, semantic 정보를 잘 표현(저장)할 수 있으며 그 정보를 hierarchical 하게 저장하고 있다는 점을 알 수 있었습니다.

저는 개인적으로 BERT를 훈련시킨 (Masked) Language Modeling이라는 task 또는 학습 방법이 단순히 language modeling만 잘 하게 만드는 것이 아니라 다른 모든 NLP task들을 잘 하게 만드는 방법이란 생각이 들었습니다.

2019년 5월 19일 일요일

논문 리뷰 - What do you learn from context? Probing for sentence structure in contextualized word representations

지난 번 포스트에 이어서 Contextualized word representation 모델들에 대해 실험한 논문을 리뷰해보려 합니다. 이번 논문의 제목은 What do you learn from context? Probing for sentence structure in contextualized word representations. 입니다. Google AI Language와 여러 대학에서 공동으로 작업했습니다.

논문 링크 : https://openreview.net/pdf?id=SJzSgnRcKX 

일단 기본적으로 실험을 통해 모델들의 능력을 알아보고, 어떤 task에서 잘 하는지를 분석합니다.  실험에 대한 디테일한 부분보다는 결과에 대한 해석이 중요하다고 생각하여 그 부분을 위주로 정리하겠습니다. 아쉬운 부분이 있다면 성능의 평가가 ELMo를 중심으로 되어 있고, GPT, BERT에 대한 분석은 큰 비중이 없습니다.

실험 task들


POS tagging
Consituent labeling
Dependency labeling
Named entity labeling
Semantic role labeling
Coreference
Sementic proto-role
Relation classification

사용 모델


CoVe (McCann et al., 2017)
Elmo (Peters et al., 2018a)
GPT (Radford et al., 2018)
BERT (Devlin et al. 2018) base, large

실험 


1. Lexical baselines

이 실험 세팅은 contextual encoder를 통해 얻은 embedding vector의 성능을 알아보기 위한 세팅입니다. 각 모델들을 학습시킨 후, input으로 사용되는 벡터만 이용하여 각 task들에 대한 성능을 측정하고, 학습된 모델의 output을 사용하여 측정한 성능과 비교합니다. 모델을 통해 얻은 lexical prior와, 모델이 lexical prior에 context를 결합한 정보를 비교하는 것입니다.

CoVe의 input은 300 dimension의 Glove이며, output은 영어-독일어를 번역하면서 학습한 2층의 biLSTM에 input 벡터를 concatenate한 900차원의 벡터입니다. 이렇게 input과 output의 벡터를 concatenate하여 얻은 결과를 cat라 표기합니다.
ELMo의 input은 character-CNN을 통해 얻은 단어의 벡터이며 output은 2-layer biLSTM에서 얻을 수 있는 각 단어의 벡터를 weight parameter를 이용하여 조합한 1024 dimension의 벡터입니다. 앞으로 이렇게 각 layer의 벡터들을 조합하여 얻은 결과를 mix라 표기합니다.
GPT, BERT base모델의 input은 768 dimension의 subword embedding이며 BERT large 모델의 input은 1024 dimension입니다. 실험에서 cat, mix 방식 통해 얻은 output을 사용합니다.


모델 간의 성능을 비교해보면, ELMo와 GPT가 CoVe보다 6.3정도 F1이 높고, BERT는 이 둘보다 2~3정도 F1이 높았습니다. ELMo와 GPT의 input 벡터는 Glove 벡터보다 훨씬 높은 성능을 보여줍니다. Parsing과 SRL( + Rel)에서 매우 큰 성능 향상을 보였는데, constituent parsing이나 semantic role labeling 같은 경우 character나 subword 정보가 많은 도움이 되기 때문에 그렇다고 합니다.
논문에는 없는 내용이지만 어떤 task에서는 ELMo나 GPT의 input 벡터로 얻은 성능이 CoVe 모델의 output을 이용할 때보다도 좋은 경우도 있네요. 그리고 ELMo의 input 벡터는 BERT의 input 벡터보다도 좋은 성능을 보입니다. BERT 모델의 output을 이용한 성능과도 크게 차이가 나지 않으며 parameter 개수의 차이를 고려하면 꽤 경쟁력이 있는 것 같습니다.

또한 ELMo 스타일의 벡터 조합(mix)을 GPT나 BERT에 사용했을 때 성능을 더 향상시킬 수 있었습니다. 이를 통해 중간 layer들에도 성능 향상에 도움을 주는 정보들이 많이 담겨 있다는 것을 알 수 있으며 이런 내용은 Blevins et al. (2018), ELMo, BERT 논문에서도 확인할 수 있습니다. 그리고 Peters et al. (2018b)에서는, 마지막 layer가 next-word prediction을 위해 overly specialized 되어 있다고 합니다.

BERT 모델은 OntoNotes, Winograd coref에서 ELMo에 비해 많은 성능을 향상시켰는데, 이를 통해 깊은 비지도학습 언어모델이 semantic task의 성능을 높이는데 좋아 보이며, 모델을 더 깊게 하면 더 좋은 결과를 얻지 않을까 예측합니다.

Input 벡터를 사용했을 때와 비교하여 위의 모델들을 사용했을 때 가장 성능 차이가 컸던 task는 syntactic한 정보가 필요한 constituent, dependency labeling이며 성능 차이가 가장 적었던 task는 semantic한 SPR이나 Winograd입니다. POS tagging이나 entity labeling에서도 성능 차이가 작지만 이는 word-level 벡터가 이미 많은 정보를 담고 있기 때문이라고 추측합니다.

Semantic Role labeling은 모델들을 통해 많은 성능 향상이 있었는데, core-role을 찾아내는 능력이 많은 기여를 했으며 core-role을 찾는 능력은 syntactic 정보를 얻는 능력과 관련이 있다고 합니다(Punyakanok et al. (2008), Gildea & Palmer(2002)). SRL 중에서도 semantic 정보가 중요한 purpose, cause, negation과 관련된 non-core labeling에서는 성능 향상 정도가 비교적 적었습니다. 그리고 semantic encoding 능력이 더 요구되는 SPR에서는 성능이 더 적게 향상되었습니다.

Relation classification task도 semantic reasoning 능력이 많이 요구되는데, 모델을 이용했을 때 성능 향상이 큰 것으로 보입니다. 하지만 그 이유는 input 벡터를 사용했을 때 정확도가 많이 낮기도 하고, 어떤 relation은 문장 내에서 중요한 단어만 보아도 쉽게 분류를 할 수 있기 때문으로 보입니다. 실제로 bag-of-words feature를 사용했을 때 ELMo의 70%에 해당하는 성능을 얻었습니다.(다른 실험들에서는 20~50%정도)


2. Randomized ELMo, non-local context.

이 실험은 훈련된 모델의 효과를 알아보기 위한 실험입니다. ELMo의 네트워크 구조는 그대로 유지한 채 파라미터를 random orthonormal matrices로 대체한 모델과 학습된 ELMo 모델의 성능을 비교합니다. Input은 동일합니다.
여기에 추가적으로 window size 1, 2(앞뒤로 1, 2개의 단어)인 word-level CNN을 사용해 얻은 벡터만 이용하여 성능을 측정합니다. 이를 통해 ELMo가 얼마나 앞뒤로 멀리 떨어진 단어의 정보들도 사용하는지를 비교합니다.


빨간 네모로 표시된 성능과 보라색 원으로 표시된 성능을 비교하면 ELMo의 파라미터가 random하게 분포할 때와 학습된 파라미터를 이용할 때의 성능을 비교할 수 있습니다. Random한 파라미터를 가질 때도 input 벡터만을 이용했을 때보다 성능이 좋지만 학습된 파라미터들은 ELMo가 향상시킨 성능 중 약 70% 정도를 담당합니다.
그런데 Winograd 에서는 random 파라미터의 성능이 학습된 파라미터의 성능보다 좋네요..

CNN을 이용하여 3~5개의 단어 정보를 같이 활용할 경우 ELMo를 사용했을 때에 비해 72, 79% 정도의 성능을 냈습니다. POS, constituent, dependency task같은 경우 80% 이상의 성능을 냈습니다. 이를 통해 이런 syntactic한 task들에서는 멀리 떨어져 있는 단어들은 별로 참조할 필요가 없다는 것을 알 수 있습니다. 반대로 semantic한 task들인 coreference, SRL non-core roles, SPR에서는 ELMo와의 차이가 컸습니다. 이를 통해 ELMo가 semantic한 정보들을 잘 뽑아내지는 못하지만 그래도 성능을 향상시킨 부분들에서는 멀리 떨어진 정보들을 잘 조합했다고 볼 수 있습니다.

ELMo가 멀리 떨어진 단어들의 정보를 잘 참조한다는 것은 아래 그래프를 통해 알 수 있습니다. Dependency labeling task에서 ELMo는 단어가 멀리 떨어져 있어도 단어가 가까울 때보다 성능이 크게 떨어지지 않습니다.



2019년 5월 8일 수요일

형태소 분석기를 이용한 Bert-Multilingual Model 기반 Korquad 결과의 성능 개선

제목이 논문 제목같다...

차례

1. Konlpy가 설치된 도커 만들기
2. 형태소 분석을 통해 마지막 조사를 제거하도록 run_squad.py 수정
3. codalab에 제출하기

공개된 Multilingual Bert 모델을 써보니 vocab 때문인지 몰라도 조사가 답에 포함되는 경우가 많았다.

예 :
이전 업데이트가 내장 메모리에 저장되었던 것과는 달리 이 업데이트는 최초로 무엇을 요구하는가?
prediction:  저장 장치를 truth :  ['저장 장치']

엑스박스 360의 물품 중  별도로 판매되고 있는 것은?
prediction:  액세서리를 truth :  ['액세서리']

이런 조사 한두글자 덕분에 내 EM이 한 10 정도 낮다...
그래서 예전부터 시도해보려고 한 형태소 분석기를 이용하여 조사를 떼어내어 정확도를 높이는 작업을 해보려고 한다.

Konlpy가 설치된 도커 만들기

일단, konlpy의 코모란을 사용하려고 하는데, codalab에서 konlpy를 이용하려면 konlpy가 설치된 나만의 도커를 만들어서 그 도커를 codalab에서 불러와 실행하야 한다. 그래서 도커를 우선 만들어야 한다.
참고 url : https://github.com/codalab/codalab-worksheets/wiki/Creating-Docker-Images

(새로운 폴더를 만들고,) " Vim Dockerfile"을 입력해 도커파일을 만든다. 파일 내용은 아래와 같다.

# 기본 이미지는 gpu를 쓰기 위해 tensorflow gpu 지원 오피셜 이미지를 쓴다. 파이썬 버전과 tensorflow 버전에 맞춰 쓴다.
FROM tensorflow/tensorflow:1.12.0-gpu-py3
MAINTAINER "dockerhub id" <이메일>
RUN apt-get -y update
# konlpy의 형태소 분석기에 필요한 자바를 설치한다.
RUN apt-get -y install openjdk-8-jdk
# Language pack을 설치하고 환경변수를 설정해주지 않으면 한글을 파일에 쓰지 못한다. 기본 Decoder가 ascii 코드를 쓴다.
RUN apt-get -y install language-pack-ko
ENV LANG ko_KR.UTF-8
RUN pip3 install konlpy

도커 허브에 회원 가입을 한 후에, repository를 만들고, terminal 상에서 "docker login" 명령어를 통해 로그인한다.

이후, "docker build -t 도커허브id/repository이름:태그이름 "을 입력하여 이미지를 생성한다.
그리고 "docker push 도커허브id/repository이름:태그이름 "을 입력하면 konlpy가 설치된 이미지가 docker hub에 업로드 된다.


run_squad.py 수정

이 부분은 사실 크게 중요하지 않은 듯 하다. 알아서 잘 하실 거라 생각한다...

write_predictions 함수 시작 부분에
from konlpy.tag import Komoran
pos_analyzer = Komoran()
를 추가하고,

all_predictions[example.qas_id] = nbest_json[0]["text"]
이 코드에서 사용되는 nbest_json[0]["text"]를 미리 형태소 분석을 통해 마지막에 붙은 조사를 띄어내도록 수정한다.


Codalab에 제출

이전에 작성한 codalab에 korquad 결과를 제출하는 포스트를 참고하여 결과를 확인한다.
--request-docker-image의 값을 내가 생성한 도커로 설정하면 된다.

아직 리더보드에 반영은 되지 않았지만 EM은 확실히 10 정도 올랐다!
F1은 사실 형태소 분석을 통해서 개선되는 부분이 기껏해야 한두글자이고, 많지는 않지만 형태소 분석기가 조사로 잘못 인식해 없애버리는 글자들도 있고 해서 한 1점 정도 올랐다.(로컬 환경과 codalab 상에서 평가한 점수도 차이가 좀 있고)
이정도 점수면 한 16등 할래나... ㅎㅎ

2019년 5월 6일 월요일

논문 설명 - Learning and Evaluating General Linguistic Intelligence

Intro

작년 한 해 Contextual Embedding을 만들 수 있는 Language Model들이 많이 나왔습니다. 이런 모델들은 자연어 처리의 여러 문제들에서 기존의 모델들보다 좋은 평가 결과를 냈습니다. 이후, 이런 모델들을 분석한 논문들도 나와서 읽어보고 정리해 봤습니다.

논문 1. "Learning and Evaluating General Linguistic Intelligence" by DeepMind, 업로드 날짜 : 2019. 1.
https://arxiv.org/pdf/1901.11373.pdf

논문 2. "What do you Learn from Context? Probing for Sentence Structure in Contextualized Word Representations" by Google AI Language, etc, ICLR 2019.
https://openreview.net/pdf?id=SJzSgnRcKX


요약

두 논문 모두 실험을 통해 모델의 능력들을 평가한다는 공통점이 있습니다. 각 논문을 간단히 소개해보겠습니다.

논문 1의 중요 단어는 "General" 입니다. 특정 task의 특정 dataset으로 훈련시킨 언어 모델이 같은 task의 다른 dataset으로 평가했을 때 얼마나 빨리, 얼마나 좋은 성능을 내는지, 또 다른 task에 적용했을 때는 얼마나 빨리, 좋은 결과를 보여주는지에 관심이 있습니다. 결론적으로 아직 갈 길이 먼 것 같습니다.

논문 2의 중요 단어는 "Context"입니다. 제목에 두 번이나 나오죠. 이 논문의 결론은, "Context를 반영한 word embedding이 주로 syntactic한 정보들을 많이 반영하며, semantic한 정보들은 별로 갖고 있지 않다." 입니다.

이제 본격적으로 두 논문을 하나씩 좀 더 자세히 살펴 보겠습니다.


Learning and Evaluating General Linguistic Intelligence



사실 DeepMind가 아니면 이런 거창한 제목을 붙이기도 힘들었을 것이라 생각합니다. 아무리 BERT가 대단하다고 해도 말이죠. 아래는 논문 Abstract의 첫 문장입니다.
"We define general linguistic intelligence as the ability to reuse previously acquired knowledge about a language’s lexicon, syntax, semantics, and pragmatic conventions to adapt to new tasks quickly"
논문에서는 General linguistic intelligence를 이미 습득한 단어, 문법적, 의미론적, 실용적(?) 지식을 새로운 task에 맞게 빠르게 재사용하는 능력이라 정의합니다. 그리고 이를 반영할 수 있는 학습 평가 지표도 제시합니다.

Introduction

최근까지의 연구는 특정 데이터에 맞는 모델을 설계하여 좋은 성능을 얻는 것이 목표인 경우가 많았습니다. 이런 경향 때문에 어떤 task에서 좋은 성능을 얻었다고 해서 그만큼 언어에 대한 지능, 이해가 높아졌다라고 보기는 힘들었습니다.

이런 가운데 매우 큰 데이터로 unsupervised pretraining을 거친 후, 각 task, dataset에 맞게 fine-tuning을 하는 language model들이 등장했습니다(ELMo, GPT, BERT 등). 이런 경우 pretrained된 모델은 특정 dataset에 맞게 설계, 학습된 모델보다 상대적으로 일반적인 언어지능을 가졋다고 볼 수 있겠죠.

또한 여러 task들을 동시에 학습하는 multi-task learning도 등장했습니다. 이렇게 학습된 모델도 좀 더 일반적인 언어 지능을 갖고 있겠죠.

논문에서 얘기하는 일반적인 언어 지능의 요소에는
1. 여러 task를 수행할 수 있는(아마 ELMo, GPT, BERT 등이 이런 능력을 갖고 있다고 볼 수 있을 것 같습니다.) 능력
2. 단어 표현을 쉽게 저장하고, 재사용하고 조합(단어 -> phrase, 문장, 문서)하며 이미 습득한 언어 지능을 재활용하는 능력
3. 조금의 학습만으로 새로운 task에 잘 적응할 수 있는 능력
들을 얘기합니다. 이 중에서 이 논문에서 알아보고자 하는 능력은 3. 에서 설명하는 능력입니다.


Tasks

모든 task들에 대해 실험을 하기 어려우니 논문에서는
Reading Comprehension(QA) - (데이터셋 : SQuAD 1.1, TriviaQA, QuAC),
Semantic Role Labeling,
Relation Extraction,
Natural Language Inference - (데이터셋 : MNLI, SNLI)
4가지 task에 대해 실험하고 결과를 분석합니다.

Models

사용한 모델은 ELMo + BiDAF, BERT 입니다.

Evaluating Transfer

위에서 언급했던 것처럼 얼마나 빨리 학습되는가를 평가하기 위한 지표인 "codelength"를 제시합니다. 수식은 아래와 같습니다.
|y| 는 라벨의 개수입니다.
A는 {(x_i, y_i)}, i : 1 ~ N : N개의 데이터 x와 라벨 y의 쌍으로 이루어진 데이터셋입니다.
A_j는 {(x_i, y_i)}, i : 1 ~ j :  j번째까지의 데이터, 라벨로 이루어진 A의 부분 집합입니다.
W^A_i는 A_i를 이용해서(처음 i개의 데이터만 이용해서) 학습한 파라미터입니다.
이를 통해 p(y_i | x_i; W^A_i-1)의 의미는 i-1개의 데이터를 이용해 파라미터 W를 학습한 후, i번째 데이터의 라벨을 예측하는 것이라 알 수 있을 것입니다. 이 값은 학습이 100% 정확하다면 1.0이 될 것이고(x가 주어졌을 때 100% 확률로 y를 예측함) 로그를 씌우면 0이 됩니다.

i를 2부터 N까지 증가시키면서 결과를 모두 더하는데, 학습이 빨리 되면 빨리 될수록 l(A)의 값은 작아지게 됩니다. 예를 들어 설명해보겠습니다.

|y|은 2이고, 데이터의 개수인 N이 4일 때,
예시 1 : (x1, y1)로는 학습이 전혀 되지 않았으나(p(y|x, W)는 1/2), (x2, y2)를 학습한 후 완벽하게 모델이 학습된 경우.
p(y2|x2, W^A1) = 1/2
p(y3|x3, W^A2) = 1
p(y4|x4, W^A3) = 1 이므로 l(A) = 1-(-0.5 + 0 + 0) = 1.5

예시 2 : (x1, y1), (x2, y2)로는 학습이 전혀 되지 않았으나(p(y|x, W)는 1/2), (x3, y3)를 학습한 후 완벽하게 모델이 학습된 경우.
p(y2|x2, W^A1) = 1/2
p(y3|x3, W^A2) = 1/2
p(y4|x4, W^A3) = 1 이므로 l(A) = 1-(-0.5 + -0.5 + 0) = 2

이렇게 codelength는 학습이 빨리 될수록 작아지는 것을 알 수 있습니다.
실제로 이런 아이디어를 적용해볼 경우 부분집합을 나누는 단위를 데이터 한 개가 아닌 여러 개의 묶음으로 나누어야겠죠.

Experiments


Unsupervised Pretraining

챕터의 제목이 조금 이상하다는 느낌이 들지만 이 챕터는 얼마나 많은 in-domain(training) 데이터가 필요한가에 대해 살펴봅니다. 실험 대상 task는 SQuAD와 MNLI입니다. BERT와 ELMo 모두 4만개 정도의 데이터를 학습해야 최고 성능에 근접했다고 합니다. pretrained 모델 치고는 매우 많다고 하네요. BERT 모델이 ELMo에 비해 최종 성능도 높았고, 학습도 빨리 진행됐습니다. 아래 그림은 차례대로 SQuAD 1.1, MNLI에 대한 실험 그래프 입니다. (+supervised는 뒤에서 설명하겠습니다.)
---

pretraining을 거치치 않고 task의 데이터로 BERT를 학습시킨 BERT_scratch모델은 그리 좋은 성능을 내지 못했습니다. (이 비교를 통해 pretraining의 효과를 알아보려는 것인지도 모르겠습니다)

그리고 추가적으로 codelengh지표를 측정합니다. SQuAD는 만개씩 8개로, MNLI는 4만개씩 10개의 부분집합으로 나누어서 측정했습니다. SQuAD 데이터셋에서는 BERT가 102.42, ELMo가 112.96을 기록했고, MNLI에서는 BERT가 89.22, ELMo가 132.17의 codelength를 가졌습니다. BERT가 성능도 좋았지만 학습도 그만큼 빨리 되었다는 것을 위의 그래프와 함께 codelength로도 알 수 있었습니다.


Beyond Unsupervised Pretraining

이 챕터에서는 다른 데이터셋으로 미리 학습했을 때 성능이 향상되는지를 알아봅니다. 실험에서는 semantic role labeling, relation extraction, SNLI, TriviaQA, QuAC 데이터셋으로 먼저 학습시킨 후 SQuAD 데이터를 학습시킵니다. 이 모델을 각각 BERT+supervised, ELMo+supervised라 부릅니다. 이 때의 성능은 아래의 표와 같습니다.


이런 pretraining을 통해 최종 EM, F1 성능이 향상되었지만 가장 크게 차이나는 것은 codelength입니다. 다른 데이터셋으로 미리 학습시키면 학습이 그만큼 빨리 된다는 것을 알 수 있습니다. 이는 pretrained 모델에 추가되는 각 task에 맞는 final layer가 미리 학습됐기 때문이라고 추정합니다. 좀 더 해석하면 같은 QA task인 TriviaQA, QuAC 데이터셋을 통해 SQuAD도 잘 할 수 있도록 학습된 것이라 할 수 있습니다. 실제로 SQuAD 데이터를 하나도 학습하지 않은 상태에서 BERT+supervised, ELMo+supervised 모델은 각각 62.9, 43.3 F1을 냈다고 합니다.


Generalization

이제 반대로 특정 데이터로 학습한 모델이 그 데이터에 오버피팅 됐는지 아니면 같은 task의 다른 데이터셋에도 잘 적용되는지를 알아봅니다. 실험은 SQuAD를 학습한 모델로 다른 TriviaQA와 QuAC 등에서 얼마나 잘 할까를 평가합니다. 다른 데이터셋으로는 학습하지 않고 평가했습니다.

결론적으로 충분히 좋은 결과를 보여주지 못합니다. TriviaQA의 1등 점수는 68.65입니다.  괄호 밖의 점수는 F1이고 괄호 안의 점수는 EM 점수입니다.


같은 task의 데이터셋이라도 데이터의 분포가 다르기 때문인 것 같습니다. 특정 Task를 배우는 것과 데이터셋에 대해 학습하는 것은 차이가 있어 보입니다.


Curriculum and Catastrophic Forgetting

이 챕터에서는 학습 순서가 성능에 영향을 주는지, 그리고 모델이 이전에 습득한 지식을 얼마나 발리 잊어버리는지 실험합니다.

첫번째는 SQuAD로 학습한 모델을 이어서 MNLI로 학습하면서 성능을 측정합니다. Training iteration은 MNLI의 학습량을 의미합니다.

학습이 진행될 수록 MNLI의 성능은 증가한 후 거의 수렴하지만 SQuAD의 성능은 점점 감소합니다.
MNLI의 final layer는 QA task와는 다른 layer(parameter)를 사용합니다. 그럼에도 불구하고 QA의 성능이 떨어진다는 것은, MNLI를 학습하면서 공통으로 사용하는 pretrained model의 파라미터들도 많이 바뀐다는 뜻이겠죠.

이러한 경향은 SQuAD로 학습한 모델을 TriviaQA로 학습할 때도 이어집니다.

MNLI로 학습할 때보다 SQuAD의 성능이 더 떨어지네요.
재밌는(?) 것은 이 모델(pretrain->SQuAD->TriviaQA로 학습된 상태)에 MNLI를 계속해서 학습시키면 SQuAD, TriviaQA의 성능은 거의 그대로이고, MNLI의 성능만 증가합니다.


마지막 실험에서는 random하게 아무 task들의 데이터를 뽑아서 학습시킵니다. 아래는 BERT를 그렇게 학습시킨 실험 결과입니다. 모든 task에서 고루 좋은 성능을 보입니다.


이런 학습 방법의 장점은 모든 task에서 성능이 좋다는 것이지만, 단점으로는 그만큼 여러 종류의 데이터가 필요하고, 새로운 task가 생겼을 경우 처음부터 다시 학습해야 하죠. 학습을 다시하는 것은 매우 비용이 큰 만큼 여러 task를 이어서 학습하는 continual learning을 잘 하기 위한 연구도 필요해 보입니다.

Discussion

이 논문은 제목대로 General Linguistic Intelligence가 있나 평가를 하지 새로운 방법을 제시하지는 않습니다. 실험을 통해 분석한 결과로는 아직 general linguistic intelligence를 달성하기 위한 여러 능력들이 부족하다고 하죠. Pretrained 모델의 성능이 좋다 해도 여전히 fine tuning을 위한 많은 데이터가 필요하고, 하나를 학습시키면 다른 하나는 또 잊어버린다는 것을 알았습니다.

이런 문제들을 해결하기 위한 방법들을 언급하는데, 일반적인 해법들을 제시합니다.
- transfer and continual learning methods
- memory module
- meta learning : 새로운 task에 빨리 적응하는 기술. NLP의 입력은 거의 같기에 많은 도움이 될 것이라 합니다.
- training curriculum
- generative language model

또한 adversarial example들에 대한 robustness, 여러 언어를 동시에 처리하는 능력 등 연구가 필요하다는 등의 언급을 하며 끝을 맺습니다.


결론적으로 아직은 멀었다....... 라는 얘기를 여러 실험을 통해 하는 DeepMind의 논문이었습니다. 다른 사람들의 연구를 약간 까려고 한 실험일 수 있겠다는 생각도 들고요 ㅎㅎ. 아직 이런 General Linguistic Intelligence를 논하기엔 이른 시점이라고 생각합니다.

한 편으로는 실제로 BERT에 Multi-task learning(random으로 task를 선택해서 학습하는)을 적용한 BigBird논문이 BERT보다좋은 성능을 냈는데, 그래도 어느정도 방향성은 제대로 제시했다는 느낌도 주는 논문이었습니다 .

2019년 3월 2일 토요일

20190302 일기

다양한 언어 생성의 이유

여러 나라에서 다른 언어를 쓴다.
동물들은 지역에 따라 다른 언어를 쓸까?ㅋㅋ

만약 인간의 한 종이 한 곳에서 승리하여 퍼져나갔다면 딱히 지역에 따라 언어가 바뀔 일이 없을 것 같다. 물건을 지칭하는 명사나 지역에 좀 특화된 단어들이 생겨날 순 있겠지만 기본적으로 문법과 단어들이 비슷할 것 같다.

그게 아니라면 여러 곳에서 현대 인류가 동시에 생겼다는 건데 그런 것 같지는 않고...
한 번 찾아봐야겠다.

2019년 2월 16일 토요일

Bert-Multilingual model을 이용해 KorQuAD 수행해보기 Part 2 제출

지난 번 글에 Pre-trained Multilingual Bert를 KorQuAD에 맞게 fine tuning시키고 평가하는 방법을 올렸다. 이제 이어서, 실제 KorQuAD leaderboard에 내가 훈련시킨 모델을 등록하는 방법에 대해 정리해 보겠다. Codalab을 처음 쓰는 사람이라면 KorQuAD 홈페이지에 링크되어 있는 제출 튜토리얼만 보고는 알아야 할 사항들이 추가적으로 더 있어서 그런 부분까지 포함하는 제출 방법을 써 보았다.

기본적인 참고 url은 KorQuAD 공식 홈페이지에 링크 되어 있는 KorQuAD codalab 페이지이다.



설명대로 CodaLab에 회원가입(Sign up) 한다.
http://codalab.org 에 가보면 아래와 같은 화면이 나온다. Competetions는 현재 codalab에서 진행되고 있는 대회들을 보여준다.



실제 제출을 위해 필요한 작업들은 Worksheets에서 진행된다. 그리고 Worksheets와 Competetions에서 사용되는 계정이 다른 듯하다...(???) 그러니 Competetions은 둘러보기만 하고 Worksheets 페이지에 가서 Sign up 하자.



로그인하면 위와 같은 화면이 보일 것이다. My Home은 기본으로 만들어진 worksheet을 보여주고, My Dashboard는 나의 모든 worksheets, 기타 여러 정보들을 보여준다. 기본 worksheet을 써도 좋고, 새로운 worksheet을 만들어도 상관없다.

---------------------------------------------------------------------------------------------------

Dev set 평가 단계


이제 KorQuAD codalab 페이지의 Dev set 평가 단계를 진행해보겠다. 이 단계는 그리 어렵지 않고 그냥 써 있는대로 하면 된다.



My Home이나 My Dashboard 아무거나 누르고, 우측에 New Worksheet 버튼을 누르면 새로운 worksheet이 만들어진다
새로 만든 worksheet은 아래와 같다.


None은 worksheet의 타이틀로 클릭하여 수정할 수 있다.

2단계에 써져 있는 것처럼 우측의 Upload 버튼을 눌러 predictions.json(test data에 대해 답을 예측한 파일)을 업로드 한다.


업로드하면 위와 같이 worksheet에 파일이 추가된다.

3단계에 나온 것처럼 화면 위의 web interface에 명령어를 입력하여 업로드한 predictions.json에 대한 평가를 진행한다. 참고로 worksheet에 생성되는 객체(entity, object, instance 등..)을 bundle이라고 부른다.

명령어를 실행하면 아래와 같은 실행 결과에 대한 bundle이 생성된다.



여기서 보이는 점수는 local 환경에서 평가한 점수랑 동일한 점수이다. 실제로 leaderboard에 점수를 등록하기 위해서는 내 컴퓨터에서 dev set에 대해 예측한 predictions.json 파일이 아니라, 훈련시킨 모델을 업로드하고 codalab 상에서 비공개된 test set에 대한 평가를 진행하는 작업이 필요하다.

여기까지 진행하는 데는 사실 이 글을 읽을 필요가 없다. 그냥 KorQuAD codalab 페이지의 Dev set 평가 방법만 보고 하면 된다. 이 글을 쓰게 된 이유는 Test set을 평가하기 위해서는 안내 사항 외에 알아야 할 게 더 있기 때문이다.

---------------------------------------------------------------------------------------------------

Test set 평가 단계



안내 사항에 써 있듯 우리는 "Codalab에서의 파일 업로드 및 명령 실행에 익숙"한 상태가 되어야 한다.



일단, 훈련된 모델의 소스 폴더를 업로드하라고 하는데 웹 페이지 상에 있는 Upload 버튼으로는 폴더 또는 여러 개의 파일을 올리는 것이 불가능하다.

실제로 이 단계를 수행하기 위해서는 Codalab을 사용하기 위한 Command Line Interface가 필요하다. CLI를 설치하기 위해서는 여기에 가서 2. Install the CLI에 나온대로 따라 하면 된다.


이제 cli를 이용해 폴더를 업로드할 수 있다. 위에 링크된 페이지에 3. Uploading files 부분을 참조하면 된다.

편의를 위해 "cl upload 폴더 -n 이름" 처럼 뒤에 -n 옵션을 붙여서 업로드하면 로컬 폴더가 복잡한 이름으로 되어 있을 경우 짧게 바꿀 수 있다. 그 외에도 파일/폴더를 올린 뒤에 클릭하고(화면에서 파란색처럼 선택된 게 보임) 오른쪽 name을 누르면 bundle의 이름을 수정할 수 있다. 위의 이미지에서 src는 로컬 환경의 폴더를 업로드한 bundle 이름이다.



또한 위의 1단계 안내 사항을 보면 실행 명령이 "python 스크립트파일 input-data-file prediction-json-file" 이렇게 되어야 한다고 명시되어 있다. 이에 맞춰 소스를 수정해주어야 한다.

기본적으로 github에서 다운받은 상태의 소스는 모두 "--option 설정값" 이런 식으로 인자를 주어야 한다. 옵션으로 설정하는 input-data-file, prediction-json-file을 args[1], args[2] 이렇게 인자로 받을 수 있도록 수정해준다.


그리고 config_file, vocab_file, checkpoint_file을 한 bundle 안에 묶어서 upload하는 게 편하다. pre-trained만 된 checkpoint_file은 올리지 않아도 된다. 하지만 로컬에서 한 폴더 안에 있지 않다면 따로따로 upload하며 각각 bundle을 만든 후 위의 이미지에서 run-predictions 번들의 summary에 써 있는 것처럼 bundle 이름과 그 안의 파일을 지정하여 실행할 수도 있다.

위의 이미지를 기준으로 소스 파일들은 bert(run_squad.py), pre trained 모델은 multi-cased-base(vocab, config file), fine-tuned 모델은 squad_trained_models bundle(init_checkpoint)에 각각 저장되어 있다. 따라서 옵션으로 파일을 지정할 때 --vocab_file bundle_name/file_name 이런 식으로 지정하면 된다.



이제 마지막으로 필요한 평가 파일(dev set)을 추가하기 위해 위의 명령어를 web interface 상에서 실행한다.

실제 수행해야 할 명령은 아래와 같다.



이 때 -n bundle_name에서 지정한 이름대로(이미지 상에서 run-prediction) bundle이 생성되고 그 안에 predictions.json 파일이 생성된다. 그리고 이미지 상에서 :KorQuAD_v1.0_dev.json, :src은 번들 이름을 말하는데 꼭 안 써도 되는 것 같기도 하다. 명령어 안에 번들이름/필요파일 이렇게만 써도 되는 것 같다.


또하나 중요한 점은, 이 작업을 gpu로 수행시켜야한다는 점이다. 안 그러면 수행 시간이 엄청나게 길어질 것이다. 위의 명령어는 docker 상에서 수행되며 docker의 타입이 gpu를 지원해주는 버젼이어야 한다.

그래서 명령어 뒤에 추가적으로 --request-docker-image tensorflow/tensorflow:1.12.0-gpu-py3(Tensorflow버전과 python 버전에 맞게), --request-gpus 1 --request-memory 8g(기본 세팅인 2g는 너무 작아 프로세스가 죽을 수 있다. 넉넉하게 세팅한다.)을 넣어서 실행한다.


최종 명령어는 cl run "python 소스번들/run_squad.py --필요옵션들 필요번들/필요파일들 dev.json파일 predictions.json" -n 만들어질번들이름 --request-docker-image 도커이미지이름 --request-gpus 1 --request-memory 8g 이다.


이제 -n으로 지정한 번들이 생길 것이다. 번들을 클릭하여 상태를 보면 실행 중인지, 실행이 끝났는지 알 수 있다.  그리고 실행이 끝나면 번들 안에 predictions.json 파일이 생성된 것을 볼 수 있다.

이제 다음 단계를 수행한다.


위 작업은 run_squad.py를 수행한 번들 안의 predictions.json을 따로 빼서 독립된 번들로 만들고, 그 파일에 대해 평가하는 과정을 설명한다. 두 명령어를 다 실행하면 업로드한 predictions.json을 평가할 때처럼 점수를 표시해주는 번들이 새로 생긴다.

첫번째 명령어에서 run-prediction만 -n으로 지정한 번들 이름으로 변경해주면 된다. {MODEL-NAME}은 원하는 대로 지정한다.

이제 마지막 3단계:제출 부분에 써 있는대로 하면 제출이 완료된다.

끄읕!
---------------------------------------------------------------------------------------------------

처음 제출할 때만 해도 baseline 모델과 naver에서 만든 모델 2개 밖에 없었다. 하지만 내가 제출한 모델의 결과가 leaderboard에 반영되었을 때 다른 2개의 모델이 한꺼번에 같이 업데이트 되어 그 때 당시의 naver 모델보다 더 좋은 결과를 냈지만 3등이 됐다... ㅜㅜ
메일이 저렇게 왔다. ㅋㅋㅋ

어짜피 이후 네이버도 더 좋은 모델을 만들고 카카오도 참전하고... 해서 더 순위는 내려갔지만...

1등 언제 찍어보지 ㅜㅜ