[Week 9- Day 4] 회고
2022. 3. 18. 00:02ㆍAbout Me/AI Tech
# Byte Pair Encoding (BPE)
from typing import List
from collections import Counter
from itertools import chain
# 단어 끝을 나타내는 문자
WORD_END = '_'
def build_bpe(
corpus: List[str],
max_vocab_size: int
) -> List[int]:
""" BPE Vocab 만들기
Byte Pair Encoding을 통한 Vocab 생성을 구현하세요.
단어의 끝은 '_'를 사용해 주세요.
이때 id2token을 서브워드가 긴 길이 순으로 정렬해 주세요.
Note: 만약 모든 단어에 대해 BPE 알고리즘을 돌리게 되면 매우 비효율적입니다.
왜냐하면 대부분의 단어는 중복되기 때문에 중복되는 단어에 대해서는 한번만 연산할 수 있다면 매우 효율적이기 때문입니다.
따라서 collections 라이브러리의 Counter를 활용해 각 단어의 빈도를 구하고,
각 단어에 빈도를 가중치로 활용하여 BPE를 돌리면 시간을 획기적으로 줄일 수 있습니다.
물론 이는 Optional한 요소입니다.
Arguments:
corpus -- Vocab을 만들기 위한 단어 리스트
max_vocab_size -- 최대 vocab 크기
Return:
id2token -- 서브워드 Vocab. 문자열 리스트 형태로 id로 token을 찾는 매핑으로도 활용 가능
"""
### YOUR CODE HERE
### ANSWER HERE ###
vocab = list(set(chain.from_iterable(corpus)) | {WORD_END})
corpus = {' '.join(word + WORD_END): count for word, count in Counter(corpus).items()}
while len(vocab) < max_vocab_size:
counter = Counter()
for word, word_count in corpus.items():
word = word.split()
counter.update({
pair: count * word_count
for pair, count in Counter(zip(word, word[1:])).items()
})
if not counter:
break
pair = counter.most_common(1)[0][0]
vocab.append(''.join(pair))
corpus = {
word.replace(' '.join(pair), ''.join(pair)): count
for word, count in corpus.items()
}
id2token = sorted(vocab, key=len, reverse=True)
return id2token
def encode(
sentence: str,
id2token: List[str]
) -> List[int]:
""" BPE 인코더
문장을 받아 BPE 토큰화를 통하여 고유 id의 수열로 바꿉니다.
문장은 공백으로 단어단위 토큰화되어있다고 가정하며, Vocab은 sentence의 모든 문자를 포함한다고 가정합니다.
찾을 수 있는 가장 긴 토큰부터 바꿉니다.
Note: WORD_END를 빼먹지 마세요.
Arguments:
sentence -- 인코드하고자 하는 문장
id2token -- build_bpe를 통해 만들어진 Vocab
Return:
token_ids -- 인코드된 토큰 id 수열
"""
### YOUR CODE HERE
### ANSWER HERE ###
def recursive(word: str):
if not word:
return []
for token_id, token in enumerate(id2token):
index = word.find(token)
if index != -1:
break
else:
raise Exception("토큰을 찾을 수 없습니다!")
return recursive(word[:index]) + [token_id] + recursive(word[index+len(token):])
token_ids = list(chain.from_iterable(recursive(word + WORD_END) for word in sentence.split()))
return token_ids
# Bucketing
bucket_dict = defaultdict(list)
for index, (src_length, trt_length) in enumerate(sentence_length):
bucket_dict[(src_length // max_pad_len, trt_length // max_pad_len)].append(index)
batch_indices_list = [bucket[start:start+batch_size] for bucket in bucket_dict.values() for start in range(0, len(bucket), batch_size)]
## 피어 세션
수다 떠느라 Further Question을 내일 다 하기로 하고, 멘토링 시간을 갖었다.
오피스 아워 때, 논문을 읽고 이해한 것을 구현하는 것을 추천하였다. 만약 아직 그렇게 하기 힘들다면, 허깅페이스에서 만든 transformer 코드를 잘 뜯어보거나 남이 만든 Simple model을 많이 보는 것이 좋다고 한다.
멘토링 시간에는 실수가 결국은 장애물이 될 수 있도록 하라는 얘기를 잠시 했다. 또 대회를 시작하기 전에 꼭 Task와 관련된 논문을 찾아보라고 하셨다. 요새 needs가 많은 Task에 대해 질문을 했었는데, 검색/ 음성 인식/ 합성을 추천하였다.
반응형
'About Me > AI Tech' 카테고리의 다른 글
[Week 10- Day 1] 회고 (0) | 2022.03.22 |
---|---|
[Week 9- Day 5] 회고 (0) | 2022.03.18 |
[Week 9- Day 3] 회고 (0) | 2022.03.17 |
[Week 9- Day 2] 회고 - 깃허브 특강 (0) | 2022.03.15 |
[Week 9- Day 1] 회고 (0) | 2022.03.15 |