Skip to content

Latest commit

 

History

History
229 lines (167 loc) · 18.7 KB

Построение системы перевода за считанные минуты.md

File metadata and controls

229 lines (167 loc) · 18.7 KB

Построение системы перевода за считанные минуты

Последовательность за последовательностью (seq2seq)[1] - это универсальная структура, способная на многие вещи (языковой перевод, суммирование текста [2], субтитры [3] и т. д.). Для краткого введения в seq2seq, вот несколько хороших сообщений: [4] [5] .

Sean Robertson’s tutorial notebook[6] а также Jeremy Howard’s лекции [6] [7] являются отличной отправной точкой, чтобы получить четкое представление о технических деталях seq2seq. Тем не менее, я постараюсь избежать реализации всех этих деталей самостоятельно, когда имею дело с реальными проблемами. Изобретать колесо, как правило, не очень хорошая идея, особенно если вы новичок в этой области. Я обнаружил, что проект OpenNMT очень активен, имеет хорошую документацию и может быть использован "из коробки":

OpenNMT - Open-Source Neural Machine Translation
OpenNMT is an industrial-strength, open-source (MIT) neural machine translation system utilizing the Torch/ PyTorch… opennmt.net

Существуют также более общие рамки (например, [8]), но, возможно, потребуется некоторая настройка, чтобы она работала над вашей конкретной проблемой.

Существует две официальные версии OpenNMT:

OpenNMT-Lua (a.k.a. OpenNMT): основной проект, разработанный с помощью LuaTorch. Оптимизированный и стабильный код для производственных и масштабных экспериментов.

OpenNMT-py : облегченная версия OpenNMT с использованием PyTorch .
Первоначально созданная исследовательской группой Facebook AI в качестве примера проекта для PyTorch, эта версия проще в расширении и подходит для исследовательских целей, но не включает в себя все функции.

Мы собираемся использовать версию PyTorch в следующих разделах. Мы проведем вас через шаги, необходимые для создания очень простой системы перевода с набором данных среднего размера.

Шаг 1 Получить OpenNMT-py

Клонируйте репозиторий OpenNMT-py git на Github в локальную папку:

OpenNMT/OpenNMT-py
OpenNMT-py - Open-Source Neural Machine Translation in PyTorch http://opennmt.net/ github.com

Возможно, вы захотите раскошелиться на Github, если вы планируете настроить или расширить его позже. Также предлагается в README:

Codebase приближается к стабильной версии 0.1. В настоящее время мы рекомендуем разветвить, если вы хотите стабильный код.

Шаг 2: Загрузите набор данных

Здесь мы собираемся использовать набор данных из AI Challenger - English-китайский конкурс машинного перевода. Это набор данных с 10 миллионами англо-китайских пар предложений. Английская копора - это разговорный английский, извлеченный из веб-сайтов по изучению английского языка и субтитров к фильмам. Насколько я понимаю, большая часть перевода представлена энтузиастами, а не профессионалами. Переведенные китайские предложения проверяются аннотаторами-людьми.

English-Chinese Machine Translation - AI Challenger
English-Chinese Machine Translation - Prize:¥300,000 - Improve the performance of English-Chinese machine translation… challenger.ai

Для загрузки набора данных требуется регистрация учетной записи и, возможно, проверка идентификатора (не могу вспомнить, является ли последний обязательным). Если это проблема для вас, вы можете попробовать datasets from WMT17 .

У набора данных AI Challenger есть некоторые проблемы: 1. Качество перевода не соответствует. 2. Поскольку многие предложения взяты из субтитров фильма, перевод часто зависит от контекста (относится к предыдущему или следующему предложению). Однако в наборе данных нет контекстной информации.

Давайте посмотрим, как стандартная модель работает с этим набором данных. Из-за ограничений памяти я сократил набор данных до 1 миллиона предложений.

«Предположим, что вы поместили intofolder набора данных challenger в корневой каталог OpenNMT».

Шаг 3. Преобразование набора данных в простые тексты.

Набор данных для проверки и тестирования поставляется в формате XML. Нам нужно преобразовать его в простые текстовые файлы, где строка состоит из одного предложения. Простой способ сделать это - использовать BeautifulSoup. Вот пример кода:

with open(input_file, "r") as f:  
    soup = BeautifulSoup(f.read(), "lxml")  
    lines = [  
      (int(x["id"]), x.text.strip()) for x in soup.findAll("seg")]  
    # Ensure the same order  
    lines = sorted(lines, key=lambda x: x[0])

Шаг 4: токенизируйте английские и китайские предложения

Входное предложение должно быть маркировано токенами через пробел.

Для английского есть несколько токенизаторов на выбор. Одним из примеров является nltk.tokenize.word_tokenize:

with open(output_file, "w") as f:  
    f.write(  
        "\\n".join([  
             " ".join(word\_tokenize(l[1]))  
             for l in lines  
        ])  
    )

Получается “It’s a neat one — two. Walker to Burton.” в “It ‘s a neat one — two . Walker to Burton .”.

Для китайского языка мы используем простейший токенизация на уровне символов, то есть каждый символ рассматривается как токен:

with open(output_file, "w") as f:  
    f.write(  
        "\\n".join([  
            " ".join([c if c != " " else "<s>" for c in l[1]])  
            for l in lines  
        ])  
    )

Получается “我就一天24小时都得在她眼皮子底下。” в “我 就 一 天 2 4 小 时 都 得 在 她 眼 皮 子 底 下 。”. (Обратите внимание, поскольку токен разделен пробелом, нам нужен специальный токен «<s>» для представления символов пробела.)

(Я не предоставил полный код для шага 3 и шага 4, потому что это действительно программирование на Python начального уровня. Вы должны быть в состоянии выполнить эти задачи самостоятельно.)

Шаг 5: Предварительная обработка набора данных

Просто запустите следующую команду в корневом каталоге:

python preprocess.py -train_src challenger/train.en.sample \  
      -train_tg challenger/train.zh.sample \  
      -valid_src challenger/valid.en \  
      -valid_tgt challenger/valid.zh  \  
      -save_data challenger/opennmt -report_every 10000

Скрипт предварительной обработки будет проходить через набор данных, отслеживать частоты токенов и составлять список слов. У меня возникла проблема с памятью, и мне пришлось уменьшить выборку обучающего набора данных до 1 миллиона строк, но я думаю, что необработанный набор данных должен уместиться в 16 ГБ памяти с некоторой оптимизацией.

Шаг 6: Тренируйте модель

python train.py -data challenger/opennmt \  
    -save_model models/baseline -gpuid 0 \  
    -learning_rate 0.001 -opt adam -epochs 20

Он будет использовать ваш первый графический процессор для обучения модели. Структура модели по умолчанию:

NMTModel (  
  (encoder): RNNEncoder (  
    (embeddings): Embeddings (  
      (make\_embedding): Sequential (  
        (emb\_luts): Elementwise (  
          (0): Embedding(50002, 500, padding\_idx=1)  
        )  
      )  
    )  
    (rnn): LSTM(500, 500, num\_layers=2, dropout=0.3)  
  )  
  (decoder): InputFeedRNNDecoder (  
    (embeddings): Embeddings (  
      (make\_embedding): Sequential (  
        (emb\_luts): Elementwise (  
          (0): Embedding(6370, 500, padding\_idx=1)  
        )  
      )  
    )  
    (dropout): Dropout (p = 0.3)  
    (rnn): StackedLSTM (  
      (dropout): Dropout (p = 0.3)  
      (layers): ModuleList (  
        (0): LSTMCell(1000, 500)  
        (1): LSTMCell(500, 500)  
      )  
    )  
    (attn): GlobalAttention (  
      (linear\_in): Linear (500 -> 500)  
      (linear\_out): Linear (1000 -> 500)  
      (sm): Softmax ()  
      (tanh): Tanh ()  
    )  
  )  
  (generator): Sequential (  
    (0): Linear (500 -> 6370)  
    (1): LogSoftmax ()  
  )  
)

Размер словаря исходных и целевых корпусов составляет 50,002 и 6370 соответственно. Исходный словарь явно урезан до 50000. Целевой словарь относительно невелик, потому что не так много распространенных китайских иероглифов.

Шаг 7: Переведите предложения теста / проверки

python translate.py \  
    -model models/baseline_acc_58.79_ppl_7.51_e14  \  
    -src challenger/valid.en -tgt challenger/valid.zh \  
    -output challenger/valid_pred.58.79 -gpu 0 -replace_unk

Замените models/baseline_acc_58.79_ppl_7.51_e14 своей собственной моделью. Наименование модели должно быть очевидным: это модель после 14 эпох обучения, с 58,79 точностью и 7,51 недоумением при проверке набора.

Вы также можете рассчитать балл BLEU с помощью следующего:

$ wget https://raw.githubusercontent.com/moses-smt/mosesdecoder/master/scripts/generic/multi-bleu.perl 

$ perl multi-bleu.perl challenger/valid.zh \  
     < challenger/valid_pred.58.79

Теперь у вас есть работающая система перевода!

Шаг 8: (Необязательно) Снять и преобразовать выходные данные

Если вы хотите отправить перевод в AI Challenger, вам нужно отменить шаг 4, а затем шаг 3. Опять же, они должны быть довольно просты в реализации.

Some examples

English: You knew it in your heart you haven’t washed your hair
Chinese(pred): 你心里清楚你没洗头发
Chinese(gold): 你心里知道你压根就没洗过头

English: I never dreamed that one of my own would be going off to a University, but here I stand,
Chinese(pred): 我从来没梦到过我的一个人会去大学,但是我站在这里,
Chinese(gold): 我从没想过我的孩子会上大学,但我站在这,

English: We just don’t have time to waste on the wrong man.
Chinese(pred): 我们只是没时间浪费人。
Chinese(gold): 如果找错了人我们可玩不起。

Вышеприведенные три примера: сверху вниз, семантически правильные, частично правильные и совершенно непонятные. Изучив несколько примеров, я обнаружил, что большинство машинно-переведенных предложений были частично правильными, и было удивительное количество семантически правильных. Неплохой результат, учитывая, как мало усилий мы приложили до сих пор.

Следующий шаг

Если вы отправите результат, вы должны обойти .22 BLEU. Текущий максимальный балл BLEU .33, так что есть много возможностей для улучшения. Вы можете проверить opts.py в корневой папке для большего количества встроенных параметров модели. Или углубиться в кодовую базу, чтобы выяснить, как все работает и где можно улучшить.

Другие способы включают в себя применение сегментации слов к китайским предложениям, добавление распознавания именованных сущностей, использование словаря произношения [\ 10] для угадывания перевода. невидимые английские имена и т. д.

(Обновление от 2017/10/14: если вы используете jieba и jieba.cut с настройками по умолчанию для токенизации предложения на китайском языке, вы получите возможность обойти .20 BLEU на общественном leaderboad. Одна из возможных причин для падения оценки является намного больше китайского размером словаря. Вы можете сказать, из числа <УНК> на выходе.)

Рекомендации:

  1. Sutskever, I., Vinyals, O., & Le, Q. V. (2014). Sequence to Sequence Learning with Neural Networks .
  2. Nallapati, R., Zhou, B., dos Santos, C., & Xiang, B. (2016). Abstractive Text Summarization using Sequence-to-sequence RNNs and Beyond.
  3. Venugopalan, S., Rohrbach, M., Donahue, J., Mooney, R., Darrell, T., & Saenko, K. (2015). Sequence to Sequence
  4. Sequence to sequence model: Introduction and concepts
  5. seq2seq: the clown car of deep learning
  6. Practical PyTorch: Translation with a Sequence to Sequence Network and Attention
  7. Cutting Edge Deep Learning For Coders, Part 2, Lecture 12 — Attention Models
  8. Cutting Edge Deep Learning For Coders, Part 2, Lecture 13 — Neural Translation
  9. Google/seq2seq: A general-purpose encoder-decoder framework for Tensorflow
  10. The CMU Pronouncing Dictionary

NMT Нейронный машинный перевод OpenNMT