BPE (Byte Pair Encoding)
BPE (Byte -Pair Encoding)을 이용하여 최근에는 tokenizer 처럼 사용하는 것 같음. BERT 논문이나 , GPT-2논문 볼 때도 BPE를 사용하는 등 알아봐야할 듯 싶어서 찾아보았다.
이것을 사용하면 rare word에 잘 대처할 수 있고, OOV 등에 대한 문제점을 극복할 수 있다고 함. GPT-2논문에서도 UNK 같은 것을 대처할 수 있는 등의 장점을 말한다.
사실 character embedding 논문을 생각해보면, unit의 단위가 character 단위가 되기 때문에 rare word에 잘 대처할 수 있다.
하지만 character 단위는 너무 의미를 담고 있지 않고, 자주 빈번하는 쌍? 즉 bi-gram(or k-gram)와 같이 자주 만나는 character끼리 붙여서 하나의 unit으로 만들어 줌으로써 character과 word level 중간 정도의 단계로 최소한의 의미를 가지는 unit을 가져가는 느낌이다.
(논문을 읽어보지는 않았지만 논문에 좀 더 자세한 설명이 있지 않을까 싶음. 더욱 자세히 알려면 읽어 보시는게.. )
(korea bpe로 검색되는 https://github.com/hkhpub/nmt_data_process 깃허브가 있다. 여기를 참고하면, 실제 적용 단에서 진행 방식을 알 지 않을까 싶음. 영어의 character을 한국어의 음절 단위로 시작하는 거 같음.)
블로그만 봐서는 정확하게 진행 방식이 이해가 안되었다.(느낌만 이해갔음)
그래서 예시를 들어서 한 번 해봤는데 맞는 거겠지?
논문 및 참고자료 2에 나온 예시를 한 번 해보자.
현재 vocab은 다음과 같은 상태라고 하자.
융합할 것: low
Step 6
이것을 사용하면 rare word에 잘 대처할 수 있고, OOV 등에 대한 문제점을 극복할 수 있다고 함. GPT-2논문에서도 UNK 같은 것을 대처할 수 있는 등의 장점을 말한다.
사실 character embedding 논문을 생각해보면, unit의 단위가 character 단위가 되기 때문에 rare word에 잘 대처할 수 있다.
하지만 character 단위는 너무 의미를 담고 있지 않고, 자주 빈번하는 쌍? 즉 bi-gram(or k-gram)와 같이 자주 만나는 character끼리 붙여서 하나의 unit으로 만들어 줌으로써 character과 word level 중간 정도의 단계로 최소한의 의미를 가지는 unit을 가져가는 느낌이다.
(논문을 읽어보지는 않았지만 논문에 좀 더 자세한 설명이 있지 않을까 싶음. 더욱 자세히 알려면 읽어 보시는게.. )
(korea bpe로 검색되는 https://github.com/hkhpub/nmt_data_process 깃허브가 있다. 여기를 참고하면, 실제 적용 단에서 진행 방식을 알 지 않을까 싶음. 영어의 character을 한국어의 음절 단위로 시작하는 거 같음.)
블로그만 봐서는 정확하게 진행 방식이 이해가 안되었다.(느낌만 이해갔음)
그래서 예시를 들어서 한 번 해봤는데 맞는 거겠지?
논문 및 참고자료 2에 나온 예시를 한 번 해보자.
현재 vocab은 다음과 같은 상태라고 하자.
vocab = {'l o w </w>' : 5,
'l o w e r </w>' : 2,
'n e w e s t </w>':6,
'w i d e s t </w>':3
}
즉 실제 적용할 땐, 데이터 세트 전체를 가지고 하면 될듯. 마치 word embedding할 때, 많은 빈도수의 word만 가지고 사용하는데 그 개념이라고 보면 될 듯.
즉 만약 I am a student. I want to become a smart student. 라는 것이 있다면
I: 2
a m: 1
a: 2
s t u d e n t: 2
w a n t: 1
t o: 1
b e c o m e: 1
s m a r t: 1
이런 것인 듯. 즉 띄어쓰기로 일단 단어를 구분하고 단어의 character을 한 개씩 띄어쓰기로 구분을 해두면 된다.
어쨌든, 이렇게 하고 단어 뒤에 </w> 기호를 붙이고 character을 점점 merge를 하면 된다.
다시 예제로 돌아가서 시작해보자. 병합의 방법은 bigram으로 가장 많은 빈도로 발생한 것 부터 merge를 하면 된다. 참고자료 2 블로그에서 10번에 해당하는 것을 코드로 설명했지만, 이것을 직접 해보면 다음과 같이 될 것이다.
Step 1
5번 l o w </w> → lo ow w</w>
2번 l o w e r</w> → lo ow we er r</w>
6번 n e w e s t </w> → ne ew we es st t</w>
3번 w i d e s t </w> → wi id de es st t</w>
9번 es st
8번 we
7번 lo ow
6번 ne ew t</w>
5번 w</w>
3번 wi id de t</w>
2번 er r</w>
융합할 것: es
Step 2
5 l o w </w> lo ow w</w>
2 l o w e r </w> lo ow we er r</w>
6 n e w [es] t</w> ne ew wes est t</w>
3 w i d [es] t</w> wi id des est t</w>
9 est
7 lo ow
6 ne ew wes t</w>
5 w</w>
3 wi id des t</w>
2 we er r</w>
융합할 것: est
Step 3 (귀찮아서 step 3부터는 띄어쓰기는 안했음)
5 low</w> lo ow w</w>
2 lower</w> lo ow we er r</w>
6 new[est]</w> ne ew west est</w>
3 wid[est]</w> wi id dest est</w>
9 est</w>
7 lo ow
6 ne ew west
5 w</w>
3 wi id dest
2 we er r</w>
융합할 것: est</w>
Step 4
5 low</w> lo ow w</w>
2 lower</w> lo ow we er r</w>
6 new[est</w>] ne ew west</w>
3 wid[est</w>] wi id dest</w>
7 lo ow
6 ne ew west</w>
5 w</w>
3 wi id dest</w>
2 we er r</w>
융합할 것: lo
Step 5
5 [lo]w</w> low w</w>
2 [lo]wer</w> low we er r</w>
6 new[est</w>] ne ew west</w>
3 wid[est</w>] wi id dest</w>
7 low
6 ne ew west</w>
5 w</w>
3 wi id dest</w>
2 we er r</w>
Step 6
5 [low]</w> low</w>
2 [low]er</w> lowe er r</w>
6 new[est</w>] ne ew west</w>
3 wid[est</w>] wi id dest</w>
6 ne ew west</w>
5 low</w>
3 wi id dest</w>
2 lowe er r</w>
융합할 것: ne
Step 7
5 [low]</w> low</w>
2 [low]er</w> lowe er r</w>
6 [ne]w[est</w>] new west</w>
3 wid[est</w>] wi id dest</w>
6 new west</w>
5 low</w>
3 wi id dest</w>
2 lowe er r</w>
융합할 것: new
Step 8
5 [low]</w> low</w>
2 [low]er</w> lowe er r</w>
6 [new][est</w>] newest</w>
3 wid[est</w>] wi id dest</w>
6 newest</w>
5 low</w>
3 wi id dest</w>
2 lowe er r</w>
융합할 것 newest</w>
Step 9
5 [low]</w> low</w>
2 [low]er</w> lowe er r</w>
6 [newest</w>]
3 wid[est</w>] wi id dest</w>
5 low</w>
3 wi id dest</w>
2 lowe er r</w>
융합할 것: low</w>
Step 10
5 [low</w>]
2 [low]er</w> lowe er r</w>
6 [newest</w>]
3 wid[est</w>] wi id dest</w>
3 wi id dest</w>
2 lowe er r</w>
융합할 것: wi
Final merge 결과
5 [low</w>]
2 [low] e r </w>
6 [newest</w>]
3 [wi] d [est</w>]
즉 이렇게 merge 가 되서 하나의 단위가 되는 것이다. 즉 띄어쓰기로 unit을 구별하면 다음과 같은 결론이 나온다.
{'low</w>': 5,
'low': 2,
'e': 2,
'r': 2,
'</w>': 2,
'newest</w>': 6,
'wi': 3,
'd': 3,
'est</w>': 3}
Reference
- 논문: http://www.aclweb.org/anthology/P16-1162
- 참고자료1: https://kh-kim.gitbook.io/natural-language-processing-with-pytorch/00-cover-3/06-bpe
- 참고자료2: https://lovit.github.io/nlp/2018/04/02/wpm/
댓글
댓글 쓰기