本文转载自:王尔古详细代码阅读原文
对于中文文本数据,我们每天都在为腾讯贡献着聊天记录,或者为百度贡献着搜索记录。而中文文本数据最大的入口,我觉得其实是搜狗输入法。这些年看上去,搜狗已经基本统治了中文输入法。PC,Mac,iPhone,安卓都装上了搜狗输入法,甚至码农朋友们装上ubuntu后的第一反应也是去装个linux版本的SougouInput(虽然很多bug)。搜狗输入法真的好用,而且越用越顺手,背后一定是数据驱动的算法。
然而我对于把我的所有输入数据,包括各种密码,都不知不觉贡献给了搜狗还是觉得不舒服。搜狗完全有能力在我输入我复杂的前半部分密码的时候自动跳出和推荐我的后半部分密码。貌似现在只有iPhone的iOS系统能在识别出用户输入密码的时候自动跳转成为苹果自己的(我们窃以为安全的)输入法键盘。
Github上有一个韩国哥们的projectKyubyong/neural_chinese_transliterator,用seq2seq训练自己的中文拼音输入法。这是这篇博客的主题。我们的代码完全基于这个开源项目,加入了交互式的拼音测试环境。感谢韩国大神!而未来是希望能将这个偏research的项目做成一个真正可用的产品,一个模型和数据本地化(别把数据上传云端)、根据输入内容手动甚至自动选择预训练模型(想象正在B站发弹幕或者在写毕业论文的不同场景)、根据用户输入数据不断更新越来越好用的拼音输入法。我把它暂且叫做“搜喵输入法”。
seq2seq模型拼音输入的本质上就是一个序列到序列的模型:输入拼音序列,输出汉字序列。所以天然适合用在诸如机器翻译的seq2seq模型上。
模型初始输入是一个随机采样的拼音字母的characterembedding,经过一个CBHG的模型,输出是五千个汉字对应的label。
这里使用的CBHG模块是state-of-art的seq2seq模型,用在Google的机器翻译和语音合成中,结构如下:
图片来自Tacotron:TowardsEnd-to-EndSpeechSynthesis
值得注意的几点:
1.模型先使用一系列的一维卷积网络,有一系列的filter,filter_size从1到K,形成一个Conv1DBank。这样的作用相当于使用了一系列的unigrams,bigrams直到K-grams,尽可能多的拿到输入序列从local到context的完整信息。其实这样的模型,与之前我们提到过的IDCNN(IteratedDilatedConvolutionaryNerualNetwork)有异曲同工之妙。而IDCNN相比较起来有更少的参数,不知道如果把CBHG的Conv1DBank换成IDCNN是怎样的效果。
2.模型在最终的BiGRU之前加入了多层的HighwayLayers,用来提取更高层次的特征。HighwayLayers可以理解为加入了本来不相邻层之间的“高速公路”,可以让梯度更好地向前流动;同时又加入一个类似LSTM中门的机制,自动学习这些高速公路的开关和流量。HighwayNetworks和ResidualNetworks、DenseNetworks都是想拉近深度网络中本来相隔很远的层与层之间的距离,使很深的网络也可以比较容易地学习。
3.模型中还使用了BatchNormalization(继ReLU之后大家公认的DL训练技巧),ResidualConnection(减少梯度的传播距离),Stride=1的Max-pooling(保证Conv的局部不变性和时间维度的粒度)以及一个时髦的BiGRU。Tacotron:TowardsEnd-to-EndSpeechSynthesis这篇文章发表在年4月,最潮的DL技术用到了很多。
语料获取理论上所有的中文文本语料,我们都可以通过xpinyin这样的工具转化为拼音数据。这相当于只要有中文文本,我们就有了带标注的训练数据。
Kyubyong/neural_chinese_transliterator中使用了德国一个研究所的-的中文新闻语料。我们也可以使用中文维基百科dump和百度百科这样的语料。
再开脑洞,我们可以用所有中文的研究论文作为语料,训练学术版搜喵输入法;
用所有文言古文作为语料,训练文言文版搜喵输入法;
用所有Bilibili弹幕作为语料,训练网络鬼畜版搜喵输入法;
用所有自己的聊天记录作为语料,训练准确吻合自己语气的搜喵输入法;
等等等等。
模型训练