TASK05-机器翻译

Quinta ·
更新时间:2024-09-21
· 980 次阅读

@[TOC](机器相关及相关技术)
机器翻译(MT):将一段文本从一种语言自动翻译为另一种语言,用神经网络解决这个问题通常称为神经机器翻译(NMT)。主要特征为:输出是单词序列而不是单个单词。输出序列的长度可能与源序列的长度不同。

BPE(byte pair encoding ):词表压缩 NMT 系统为了能够控制计算的复杂度,有 着一个固定大小的词汇表,通常会将词汇表限制在 30k 到 80k 之间,这就导致了其在翻译未登录词时有着严重的不足。由于限定词汇表的大小,对于未出现在该词汇表中的词,NMT 系统用 UNK 标记来替代。结果,NMT 系统不仅无法将它们翻译准确,而且破坏了句子的 结构特征。为了解决 NMT 系统中存在的这一问题, Sennrich 和 Haddow(2016)提出了 一种 BPE 编码的解决方法。该方法将训练语料中单词拆分成更为常见的小部分,这里把 它叫做子字单元。通过这种方法,我们假设在同样将词汇表设置成 30k 的情况下,由于很多单词拆解的子字部分是相同的,所以 30k 的子字单元实际上可以表示出远远超出 30k 的以单 词为基础的词汇表。这样,对于绝大多数未登录词,就可以通过子字单元的组合表示出翻译 的结果。 思想

BPE 的思想是将单词拆解为更小更常见的子字单元。对于原本不在词表中的单词,NMT 系统一般会用 UNK 标示符替代。BPE 方法将其拆解为常见的子字,通过翻译子字部分将原有的 UNK 单词进行了翻译,从而极大地保存了句子的结构特征和流畅性。

算法步骤

算法步骤如下:

初始化符号词表。将所有的字符加入到符号词表中。对所有单词的末尾加入特殊标记,如-。翻译后恢复原始的标记。
迭代对所有符号进行计数,找出次数最多的(A, B),用AB代替。
每次合并,会产生一个新的符号,代表着n-gram字符
常见的n-grams字符(或者whole words),最终会被合并到一个符号

代码实现 '''把单词分割成最小的符号,并且加上结尾符号''' vocabs = {} for word, count in words.items(): # 在正则式自身内,加上空格,abc——>a b c word = re.sub(r'([a-zA-Z])', r' \1', word) word += ' ' + endtag vocabs[word] = count return vocabs def get_symbol_pairs(vocabs): ''' 获得词汇中所有的字符pair,连续长度为2,并统计出现次数 Args: vocabs: 单词dict,(word, count)单词的出现次数。单词已经分割为最小的字符 Returns: pairs: ((符号1, 符号2), count) ''' pairs = dict() for word, freq in vocabs.items(): # 单词里的符号 symbols = word.split() for i in range(len(symbols) - 1): p = (symbols[i], symbols[i + 1]) pairs[p] = pairs.get(p, 0) + freq return pairs def merge_symbols(symbol_pair, vocabs): '''把vocabs中的所有单词中的'a b'字符串用'ab'替换 Args: symbol_pair: (a, b) 两个符号 vocabs: 用subword(symbol)表示的单词,(word, count)。其中word使用subword空格分割 Returns: vocabs_new: 替换'a b'为'ab'的新词汇表 ''' vocabs_new = {} raw = ' '.join(symbol_pair) merged = ''.join(symbol_pair) # 非字母和数字字符做转义 bigram = re.escape(raw) p = re.compile(r'(?<!\S)' + bigram + r'(?!\S)') for word, count in vocabs.items(): word_new = p.sub(merged, word) vocabs_new[word_new] = count return vocabs_new raw_words = {"low":5, "lower":2, "newest":6, "widest":3} vocabs = process_raw_words(raw_words) num_merges = 10 print (vocabs) for i in range(num_merges): pairs = get_symbol_pairs(vocabs) # 选择出现频率最高的pair symbol_pair = max(pairs, key=pairs.get) vocabs = merge_symbols(symbol_pair, vocabs) print (vocabs)

操作次数是算法唯一的超参数。


作者:中古传奇



机器翻译

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章
Grace 2020-02-04
737