Объясните bpe (кодирование пары байтов) примерами?
Может ли кто-нибудь помочь объяснить основную концепцию модели bpe? За исключением этой статьи, пока нет так много объяснений по этому поводу.
До сих пор я знал, что он позволяет трансляцию модели NMT в открытом словаре, кодируя редкие и неизвестные слова в виде последовательностей единиц подслов.
Но я хочу получить общее представление о том, как это работает, не просматривая бумаги.
2 ответа
BPE - один из трех алгоритмов для решения проблемы неизвестного слова автоматическим способом: кодирование пар байтов, моделирование языка униграммы, WordPiece и схема токенизации BPE состоит из двух частей: обучающего токена и сегментатора токена.
Обучающий токен берет необработанный обучающий корпус (иногда предварительно разделенный на слова, например, пробелами) и вводит словарь, набор токенов. Сегментатор токенов берет исходное тестовое предложение и разбивает его на токены в словаре.
В алгоритме есть параметр k, который означает, что k объединяет или k новых символов в окончательном словаре.
Давайте обучим BPE, используя эту строку:
Pen Penapple Apple Pen
адаптированы из PPAP и показывают, как неизвестные / редкие «слова» и
applepen
в тестовых данных можно автоматически преобразовать в известные подсловные единицы.
Учусь
Во-первых, после некоторой предварительной обработки (отображение регистра, токенизация на основе регулярных выражений и добавление символа конца слова _) мы получаем следующие строки C(как наш корпус) и их частоты (частота: строка):
2: p e n _
1: p e n a p p l e _
1: a p p l e _
Словарь V - это [_, p, e, n, a, l]
Теперь давайте запустим первый раунд цикла for в приведенном выше псевдокоде:
p, e <- most frequent pair in {(p, e): 3, (e, n): 3, (n, _): 2, (a, p): 2, (p, p): 2, (p, l): 2, (l, e): 2, (e, _): 2, (n, a): 1}
pe <- p + e
[_, p, e, n, a, l, pe] <- [_, p, e, n, a, l] + pe
C becomes this:
2: pe n _
1: pe n a p p l e _
1: a p p l e _
Запустим второе слияние следующим образом:
p, e <- most frequent pair in {(pe, n): 3, (n, _): 2, (a, p): 2, (p, p): 2, (p, l): 2, (l, e): 2, (e, _): 2, (n, a): 1}
pen <- pe + n
[_, p, e, n, a, l, pe, pen] <- [_, p, e, n, a, l, pe] + pen
C becomes this:
2: pen _
1: pen a p p l e _
1: a p p l e _
И вот следующие слияния, если мы возьмем k как N>= 9:
Merge Current V
(pen, _) [_, p, e, n, a, l, pe, pen, pen_]
(a, p) [_, p, e, n, a, l, pe, pen, pen_, ap]
(ap, p) [_, p, e, n, a, l, pe, pen, pen_, ap, app]
(app, l) [_, p, e, n, a, l, pe, pen, pen_, ap, app, appl]
(appl, e) [_, p, e, n, a, l, pe, pen, pen_, ap, app, appl, apple]
(apple, _) [_, p, e, n, a, l, pe, pen, pen_, ap, app, appl, apple, apple_]
(pen, apple_) [_, p, e, n, a, l, pe, pen, pen_, ap, app, appl, apple, apple_, penapple_]
Мы видим, что после 9 итераций слияния в C. нет соседних пар.
Парсинг
Парсер токенов просто выполняет слияния с тестовыми данными, которые мы извлекли из обучающих данных, жадно, в том порядке, в котором мы их изучили. (Таким образом, частоты в тестовых данных не играют роли, только частоты в обучающих данных).
На этом этапе мы тестируем парсер, используя это предложение:
Applepen PenapplePen
. Как обычно, мы выполняем предварительную обработку, которую сделали на этапе обучения, и получаем:
a p p l e p e n _
p e n a p p l e p e n _
и следуйте порядку слияния:
(p, e), (pe, n), (pen, _), (a, p), (ap, p), (app, l), (appl, e), (apple, _), (pen, apple_)
Во-первых, (p, e). Объединяем p и e в тестовых данных и получаем:
a p p l e pe n _
pe n a p p l e pe n _
Во-вторых, (pe, n) и получаем:
a p p l e pen _
pen a p p l e pen _
.....
После всех 9 ходов слияния мы получаем (если k <= 9, мы просто применяем первые k слияний на этом шаге; если k равно 2, обратитесь к этому ответу ):
apple pen_
pen apple pen_
И последнее токенизированное тестовое предложение - [яблоко, перо_, перо, яблоко, перо_] и неизвестное (невидимое в обучающих данных) слово
penapplepen
также можно разделить.
Ссылки:
Кодирование пар байтов в NLP является промежуточным решением для уменьшения размера словаря по сравнению с токенами на основе слов и для покрытия как можно большего количества часто встречающихся последовательностей символов в одном токене без использования токенов на основе длинных знаков.
Первоначально каждый символ обозначается токеном, а количество операций слияния является гиперпараметром для построения словаря BPE.
Рассмотрим предложение:
«у него был кот» и «кот сидит на циновке»
Мы можем составить словарный запас персонажей следующим образом:
['a', 'c', 'd', 'e', 'g', 'h', 'i', 'm', 'n', 'o', 's', 't']
Теперь мы можем перечислить пары и их вхождения:
he: 3 (he, the*2)
ha: 1 (had)
ad: 1 (had)
ca: 2 (cat*2)
at: 3 (cat*2, mat)
th: 2
is: 1
si: 1
it: 1
ti: 1
in: 1
ng: 1
on: 1
ma: 1
Поскольку пары «он» и «at» чаще всего встречаются в словаре, их можно объединить (операция слияния) и добавить в словарь.
Обновленный словарь: ['a', 'c', 'd', 'e', 'g', 'h', 'i', 'm', 'n', 'o', 's', 't ', 'высокая температура']
Теперь, если более длинные части слов, которые встречаются в словаре, могут быть упомянуты с использованием одного токена, то есть «он» или «at» упоминается с использованием одиночных токенов вместо двух символьных токенов.
Таким образом: предложения:
- «у него был кот» и 2. «кот сидит на циновке»
можно токенизировать следующим образом:
- [, 'h', 'a', 'd', 'a', 'c',]
- ['t' ,, 'c' ,, 'i', 's', 's', 'i', 't', 't', 'i', 'n', 'g', 'o' , 'n', 't',, 'm',]
Кроме того, эту обработку можно повторить, определив наиболее часто встречающиеся пары:
ha: 1 (had)
ad: 1 (had)
c'at': 2 (cat*2)
th: 2
is: 1
si: 1
it: 1
ti: 1
in: 1
ng: 1
on: 1
m'at': 1
Поскольку слово
c'at'
, встречается наиболее часто, его можно объединить, чтобы сформировать новый словарь, как показано ниже:
['a', 'c', 'd', 'e', 'g', 'h', 'i', 'm', 'n', 'o', 's', 't', ' он ',' у ',' кот ']
Таким образом, новая токенизация:
- [, 'h', 'a', 'd', 'a',]
- ['t' ,,
'cat'
, 'i', 's', 's', 'i', 't', 't', 'i', 'n', 'g', 'o', 'n', 't','he'
, 'м','at'
]
Таким образом, с увеличением количества операций слияния размер словаря увеличивается, но количество токенов, используемых для представления данного текста, уменьшается.