本文目录一览:
- 1、c++版本word2vec源代码怎么使用
- 2、文本分类方法有哪些
- 3、自然语言处理基础知识
- 4、word2vec 相比之前的 Word Embedding 方法好在什么地方
- 5、分层softmax
- 6、如何利用深度学习技术训练聊天机器人语言模型
c++版本word2vec源代码怎么使用
这是vs2008的文件,不知道你的vc是什么版本的?如果是2008直接打开ImageEditor.sln就好了, 如果不是2008的话,你就先打开VC,然后选打开工程,打开ImageEditor.vcproj,他会问你要不要转换,你都点确定就好了
文本分类方法有哪些
文本分类问题: 给定文档p(可能含有标题t),将文档分类为n个类别中的一个或多个
文本分类应用: 常见的有垃圾邮件识别,情感分析
文本分类方向: 主要有二分类,多分类,多标签分类
文本分类方法: 传统机器学习方法(贝叶斯,svm等),深度学习方法(fastText,TextCNN等)
本文的思路: 本文主要介绍文本分类的处理过程,主要哪些方法。致力让读者明白在处理文本分类问题时应该从什么方向入手,重点关注什么问题,对于不同的场景应该采用什么方法。
文本分类的处理大致分为 文本预处理 、文本 特征提取 、 分类模型构建 等。和英文文本处理分类相比,中文文本的预处理是关键技术。
针对中文文本分类时,很关键的一个技术就是中文分词。特征粒度为词粒度远远好于字粒度,其大部分分类算法不考虑词序信息,基于字粒度的损失了过多的n-gram信息。下面简单总结一下中文分词技术:基于字符串匹配的分词方法、基于理解的分词方法和基于统计的分词方法 [1]。
1,基于字符串匹配的分词方法:
过程:这是 一种基于词典的中文分词 ,核心是首先建立统一的词典表,当需要对一个句子进行分词时,首先将句子拆分成多个部分,将每一个部分与字典一一对应,如果该词语在词典中,分词成功,否则继续拆分匹配直到成功。
核心: 字典,切分规则和匹配顺序是核心。
分析:优点是速度快,时间复杂度可以保持在O(n),实现简单,效果尚可;但对歧义和未登录词处理效果不佳。
2, 基于理解的分词方法:基于理解的分词方法是通过让计算机模拟人对句子的理解 ,达到识别词的效果。其基本思想就是在分词的同时进行句法、语义分析,利用句法信息和语义信息来处理歧义现象。它通常包括三个部分:分词子系统、句法语义子系统、总控部分。在总控部分的协调下,分词子系统可以获得有关词、句子等的句法和语义信息来对分词歧义进行判断,即它模拟了人对句子的理解过程。这种分词方法需要使用大量的语言知识和信息。由于汉语语言知识的笼统、复杂性,难以将各种语言信息组织成机器可直接读取的形式,因此目前基于理解的分词系统 还处在试验阶段 。
3,基于统计的分词方法:
过程:统计学认为分词是一个 概率最大化问题 ,即拆分句子,基于语料库,统计 相邻的字组成的词语出现的概率 ,相邻的词出现的次数多,就出现的概率大, 按照概率值进行分词 ,所以一个完整的语料库很重要。
主要的统计模型有: N元文法模型(N-gram),隐马尔可夫模型(Hidden Markov Model ,HMM),最大熵模型(ME),条件随机场模型(Conditional Random Fields,CRF)等。
1, 分词 : 中文任务分词必不可少,一般使用jieba分词,工业界的翘楚。
2, 去停用词:建立停用词字典 ,目前停用词字典有2000个左右,停用词主要包括一些副词、形容词及其一些连接词。通过维护一个停用词表,实际上是一个特征提取的过程,本质 上是特征选择的一部分。
3, 词性标注 : 在分词后判断词性(动词、名词、形容词、副词…),在使用jieba分词的时候设置参数就能获取。
文本分类的核心都是如何从文本中抽取出能够体现文本特点的关键特征,抓取特征到类别之间的映射。 所以特征工程很重要,可以由四部分组成:
1,基于词袋模型的特征表示:以词为单位(Unigram)构建的词袋可能就达到几万维,如果考虑二元词组(Bigram)、三元词组(Trigram)的话词袋大小可能会有几十万之多,因此基于词袋模型的特征表示通常是极其稀疏的。
(1)词袋特征的方法有三种:
(2)优缺点:
2,基于embedding的特征表示: 通过词向量计算文本的特征。(主要针对短文本)
4,基于任务本身抽取的特征:主要是针对具体任务而设计的,通过我们对数据的观察和感知,也许能够发现一些可能有用的特征。有时候,这些手工特征对最后的分类效果提升很大。举个例子,比如对于正负面评论分类任务,对于负面评论,包含负面词的数量就是一维很强的特征。
5,特征融合:对于特征维数较高、数据模式复杂的情况,建议用非线性模型(如比较流行的GDBT, XGBoost);对于特征维数较低、数据模式简单的情况,建议用简单的线性模型即可(如LR)。
6,主题特征:
LDA(文档的话题): 可以假设文档集有T个话题,一篇文档可能属于一个或多个话题,通过LDA模型可以计算出文档属于某个话题的概率,这样可以计算出一个DxT的矩阵。LDA特征在文档打标签等任务上表现很好。
LSI(文档的潜在语义): 通过分解文档-词频矩阵来计算文档的潜在语义,和LDA有一点相似,都是文档的潜在特征。
这部分不是重点,传统机器学习算法中能用来分类的模型都可以用,常见的有:NB模型,随机森林模型(RF),SVM分类模型,KNN分类模型,神经网络分类模型。
这里重点提一下贝叶斯模型,因为工业用这个模型用来识别垃圾邮件[2]。
1,fastText模型: fastText 是word2vec 作者 Mikolov 转战 Facebook 后16年7月刚发表的一篇论文: Bag of Tricks for Efficient Text Classification [3]。
模型结构:
改进:注意力(Attention)机制是自然语言处理领域一个常用的建模长时间记忆机制,能够很直观的给出每个词对结果的贡献,基本成了Seq2Seq模型的标配了。实际上文本分类从某种意义上也可以理解为一种特殊的Seq2Seq,所以考虑把Attention机制引入近来。
过程:
利用前向和后向RNN得到每个词的前向和后向上下文的表示:
词的表示变成词向量和前向后向上下文向量连接起来的形式:
模型显然并不是最重要的: 好的模型设计对拿到好结果的至关重要,也更是学术关注热点。但实际使用中,模型的工作量占的时间其实相对比较少。虽然再第二部分介绍了5种CNN/RNN及其变体的模型,实际中文本分类任务单纯用CNN已经足以取得很不错的结果了,我们的实验测试RCNN对准确率提升大约1%,并不是十分的显著。最佳实践是先用TextCNN模型把整体任务效果调试到最好,再尝试改进模型。
理解你的数据: 虽然应用深度学习有一个很大的优势是不再需要繁琐低效的人工特征工程,然而如果你只是把他当做一个黑盒,难免会经常怀疑人生。一定要理解你的数据,记住无论传统方法还是深度学习方法,数据 sense 始终非常重要。要重视 badcase 分析,明白你的数据是否适合,为什么对为什么错。
超参调节: 可以参考 深度学习网络调参技巧 - 知乎专栏
一定要用 dropout: 有两种情况可以不用:数据量特别小,或者你用了更好的正则方法,比如bn。实际中我们尝试了不同参数的dropout,最好的还是0.5,所以如果你的计算资源很有限,默认0.5是一个很好的选择。
未必一定要 softmax loss: 这取决与你的数据,如果你的任务是多个类别间非互斥,可以试试着训练多个二分类器,也就是把问题定义为multi lable 而非 multi class,我们调整后准确率还是增加了1%。
类目不均衡问题: 基本是一个在很多场景都验证过的结论:如果你的loss被一部分类别dominate,对总体而言大多是负向的。建议可以尝试类似 booststrap 方法调整 loss 中样本权重方式解决。
避免训练震荡: 默认一定要增加随机采样因素尽可能使得数据分布iid,默认shuffle机制能使得训练结果更稳定。如果训练模型仍然很震荡,可以考虑调整学习率或 mini_batch_size。
知乎的文本多标签分类比赛,给出第一第二名的介绍网址:
NLP大赛冠军总结:300万知乎多标签文本分类任务(附深度学习源码)
2017知乎看山杯 从入门到第二
自然语言处理基础知识
NLP 是什么?
NLP 是计算机科学领域与 人工智能 领域中的一个重要方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。自然语言处理是一门融语言学、计算机科学、数学于一体的学科。NLP 由两个主要的技术领域构成:自然语言理解和自然语言生成。
自然语言理解方向,主要目标是帮助机器更好理解人的语言,包括基础的词法、句法等语义理解,以及需求、篇章、情感层面的高层理解。
自然语言生成方向,主要目标是帮助机器生成人能够理解的语言,比如文本生成、自动文摘等。
NLP 技术基于大数据、知识图谱、 机器学习 、语言学等技术和资源,并可以形成机器翻译、深度问答、对话系统的具体应用系统,进而服务于各类实际业务和产品。
NLP在金融方面
金融行业因其与数据的高度相关性,成为人工智能最先应用的行业之一,而NLP与知识图谱作为人工智能技术的重要研究方向与组成部分,正在快速进入金融领域,并日益成为智能金融的基石。舆情分析舆情主要指民众对社会各种具体事物的情绪、意见、价值判断和愿望等。
事件(Event ):在特定时间、特定地点发生的事情。主题(Topic):也称为话题,指一个种子事件或活动以及与它直接相关的事件和活动。专题(Subject):涵盖多个类似的具体事件或根本不涉及任何具体事件。需要说明的是,国内新闻网站新浪、搜狐等所定义的“专题”概念大多数等同于我们的“主题”概念。热点:也可称为热点主题。热点和主题的概念比较接近,但有所区别。
1. 词干提取
什么是词干提取?词干提取是将词语去除变化或衍生形式,转换为词干或原型形式的过程。词干提取的目标是将相关词语还原为同样的词干,哪怕词干并非词典的词目。
2. 词形还原
什么是词形还原? 词形还原是将一组词语还原为词源或词典的词目形式的过程。还原过程考虑到了POS问题,即词语在句中的语义,词语对相邻语句的语义等。
3. 词向量化什么是词向量化?词向量化是用一组实数构成的向量代表自然语言的叫法。这种技术非常实用,因为电脑无法处理自然语言。词向量化可以捕捉到自然语言和实数间的本质关系。通过词向量化,一个词语或者一段短语可以用一个定维的向量表示,例如向量的长度可以为100。
4. 词性标注
什么是词性标注?简单来说,词性标注是对句子中的词语标注为名字、动词、形容词、副词等的过程。
5. 命名实体消歧
什么是命名实体消岐?命名实体消岐是对句子中的提到的实体识别的过程。例如,对句子“Apple earned a revenue of 200 Billion USD in 2016”,命名实体消岐会推断出句子中的Apple是苹果公司而不是指一种水果。一般来说,命名实体要求有一个实体知识库,能够将句子中提到的实体和知识库联系起来。
6. 命名实体识别
体识别是识别一个句子中有特定意义的实体并将其区分为人名,机构名,日期,地名,时间等类别的任务。
7. 情感分析
什么是情感分析?情感分析是一种广泛的主观分析,它使用自然语言处理技术来识别客户评论的语义情感,语句表达的情绪正负面以及通过语音分析或书面文字判断其表达的情感等等。
8. 语义文本相似度
什么是语义文本相似度分析?语义文本相似度分析是对两段文本的意义和本质之间的相似度进行分析的过程。注意,相似性与相关性是不同的。
9.语言识别
什么是语言识别?语言识别指的是将不同语言的文本区分出来。其利用语言的统计和语法属性来执行此任务。语言识别也可以被认为是文本分类的特殊情况。
10. 文本摘要
什么是文本摘要?文本摘要是通过识别文本的重点并使用这些要点创建摘要来缩短文本的过程。文本摘要的目的是在不改变文本含义的前提下最大限度地缩短文本。
11.评论观点抽取
自动分析评论关注点和评论观点,并输出评论观点标签及评论观点极性。目前支持 13 类产品用户评论的观点抽取,包括美食、酒店、汽车、景点等,可帮助商家进行产品分析,辅助用户进行消费决策。
11.DNN 语言模型
语言模型是通过计算给定词组成的句子的概率,从而判断所组成的句子是否符合客观语言表达习惯。在机器翻译、拼写纠错、语音识别、问答系统、词性标注、句法分析和信息检索等系统中都有广泛应用。
12.依存句法分析
利用句子中词与词之间的依存关系来表示词语的句法结构信息 (如主谓、动宾、定中等结构关系),并用树状结构来表示整句的的结构 (如主谓宾、定状补等)。
1、NLTK
一种流行的自然语言处理库、自带语料库、具有分类,分词等很多功能,国外使用者居多,类似中文的 jieba 处理库
2、文本处理流程
大致将文本处理流程分为以下几个步骤:
Normalization
Tokenization
Stop words
Part-of-speech Tagging
Named Entity Recognition
Stemming and Lemmatization
下面是各个流程的具体介绍
Normalization
第一步通常要做就是Normalization。在英文中,所有句子第一个单词的首字母一般是大写,有的单词也会全部字母都大写用于表示强调和区分风格,这样更易于人类理解表达的意思。
Tokenization
Token是"符号"的高级表达, 一般值具有某种意义,无法再拆分的符号。在英文自然语言处理中,Tokens通常是单独的词,因此Tokenization就是将每个句子拆分为一系列的词。
Stop Word
Stop Word 是无含义的词,例如’is’/‘our’/‘the’/‘in’/'at’等。它们不会给句子增加太多含义,单停止词是频率非常多的词。 为了减少我们要处理的词汇量,从而降低后续程序的复杂度,需要清除停止词。
Named Entity
Named Entity 一般是名词短语,又来指代某些特定对象、人、或地点 可以使用 ne_chunk()方法标注文本中的命名实体。在进行这一步前,必须先进行 Tokenization 并进行 PoS Tagging。
Stemming and Lemmatization
为了进一步简化文本数据,我们可以将词的不同变化和变形标准化。Stemming 提取是将词还原成词干或词根的过程。
3、Word2vec
Word2vec是一种有效创建词嵌入的方法,它自2013年以来就一直存在。但除了作为词嵌入的方法之外,它的一些概念已经被证明可以有效地创建推荐引擎和理解时序数据。在商业的、非语言的任务中。
### 四、NLP前沿研究方向与算法
1、MultiBERT
2、XLNet
3、bert 模型
BERT的全称是Bidirectional Encoder Representation from Transformers,即双向Transformer的Encoder,因为decoder是不能获要预测的信息的。模型的主要创新点都在pre-train方法上,即用了Masked LM和Next Sentence Prediction两种方法分别捕捉词语和句子级别的representation。
BERT提出之后,作为一个Word2Vec的替代者,其在NLP领域的11个方向大幅刷新了精度,可以说是近年来自残差网络最优突破性的一项技术了。BERT的主要特点以下几点:
使用了Transformer作为算法的主要框架,Trabsformer能更彻底的捕捉语句中的双向关系;
使用了Mask Language Model(MLM)和 Next Sentence Prediction(NSP) 的多任务训练目标;
使用更强大的机器训练更大规模的数据,使BERT的结果达到了全新的高度,并且Google开源了BERT模型,用户可以直接使用BERT作为Word2Vec的转换矩阵并高效的将其应用到自己的任务中。
BERT的本质上是通过在海量的语料的基础上运行自监督学习方法为单词学习一个好的特征表示,所谓自监督学习是指在没有人工标注的数据上运行的监督学习。在以后特定的NLP任务中,我们可以直接使用BERT的特征表示作为该任务的词嵌入特征。所以BERT提供的是一个供其它任务迁移学习的模型,该模型可以根据任务微调或者固定之后作为特征提取器。
模型结构: 由于模型的构成元素Transformer已经解析过,就不多说了,BERT模型的结构如下图最左:
对比OpenAI GPT(Generative pre-trained transformer),BERT是双向的Transformer block连接;就像单向rnn和双向rnn的区别,直觉上来讲效果会好一些。
优点: BERT是截至2018年10月的最新state of the art模型,通过预训练和精调横扫了11项NLP任务,这首先就是最大的优点了。而且它还用的是Transformer,也就是相对rnn更加高效、能捕捉更长距离的依赖。对比起之前的预训练模型,它捕捉到的是真正意义上的bidirectional context信息。
缺点: MLM预训练时的mask问题
[MASK]标记在实际预测中不会出现,训练时用过多[MASK]影响模型表现
每个batch只有15%的token被预测,所以BERT收敛得比left-to-right模型要慢(它们会预测每个token)
BERT火得一塌糊涂不是没有原因的:
使用Transformer的结构将已经走向瓶颈期的Word2Vec带向了一个新的方向,并再一次炒火了《Attention is All you Need》这篇论文;
11个NLP任务的精度大幅提升足以震惊整个深度学习领域;
无私的开源了多种语言的源码和模型,具有非常高的商业价值。
迁移学习又一次胜利,而且这次是在NLP领域的大胜,狂胜。
BERT算法还有很大的优化空间,例如我们在Transformer中讲的如何让模型有捕捉Token序列关系的能力,而不是简单依靠位置嵌入。BERT的训练在目前的计算资源下很难完成,论文中说的训练需要在64块TPU芯片上训练4天完成,而一块TPU的速度约是目前主流GPU的7-8倍。
word2vec 相比之前的 Word Embedding 方法好在什么地方
个人认为核心还是作者在发论文的同时直接提供了一个简单可用的word2vec源码实现,那篇论文的公式部分其实写的有些乱,后来好像还有人写论文把推导过程写的更易读。
分层softmax
中文名叫霍夫曼树/霍夫曼编码,是个二叉树(注意 不是 二叉搜索树),这部分内容比较简单, 维基百科 上也说的非常清楚, 下面搬运一下维基百科上的例子 :
示例:
霍夫曼树常处理符号编写工作。根据整组数据中符号出现的频率高低,决定如何给符号编码。 如果符号出现的频率越高,则给符号的码越短,相反符号的号码越长 。假设我们要给一个英文单字"F O R G E T"进行霍夫曼编码,而每个英文字母出现的频率分别列在Fig.1。
演算过程:
(一)进行霍夫曼编码前,我们先创建一个霍夫曼树。
最后产生的树状图就是霍夫曼树,参考Fig.2。
(二)进行编码
word2vec Parameter Learning Explained这篇论文中介绍了 Continuous Bag-of-Word Model(连续词袋模型)和skip-gram model(跳字模型),分别对应了词向量的两种训练方法:利用context预测中心词以及利用中心词去预测context。对于连续词袋模型(CBOW)来说,一般的做法(如下图所示)是先对每个单词进行one-of-N编码(one-hot encoded),作为训练网络的输入,接着构建一层hidden layer,最后构建输出层,这一层是一个softmax层,每个context单词到中心单词的事件都被认为是 独立的 ,所以将这些事件发生的 概率相乘 ,最后构建损失函数,即:将输出概率分布和实际选中的词概率分布进行Corss Entropy计算,接下来使用SGD对参数进行更新。这里,hidden layer的训练结果就是最终的 word vector 了。
上述方法看起来是没毛病的,问题是计算量有点大,尤其是进行反向传播更新参数的时候:
式(1)说明,参数更新的时候,对于每一个单词每一次迭代都 至少 有 的计算量,如此大的计算量是由于softmax引用了词典中的所有单词。
在skip-gram模型中也是一样的:
为了减少计算量,作者提出了两种近似计算方法,第一种叫做 Negative Sampling (负采样),该方法就是对词典中的特定属性的单词进行特定分布的采样,将计算的数据量降低了(详见论文);第二种就是 Hierarchical Softmax (分层softmax/层次softmax),该方法将 softmax层 替换成了 分层softmax层 。
分层softmax 的计算过程如下图所示:
图片来自 这里
从图中可以看出,hidden layer到output layer的连接原本是一个简单的softmax,有 V个神经元 和所有的hidden layer两两连接,现在变成了一个树,有 V-1个神经元 和所有的hidden layer两两连接。计算概率的方法也发生了变化:
其中,当 时,中括号内为1,否则为-1,这是用到了一个sigmoid函数的小trick: 。所以式(2)的意思就是从根节点到目标单词,有且仅有一条路径可以到达,在这条路径上往左走的概率是 ,往右走的概论自然就是 , 逻辑回归 那篇也介绍过,sigmoid函数是用来做二分类的,在这里正好合适;当路径上的所有二分类的概率都连乘后,得到的就是预测单词的概率,可以证明,词典中所有单词被预测到的概率和为1。这也是这个方法被叫做分层softmax的原因了。
如此一来,计算某个单词被预测的概率就仅仅和该单词到hidden layer的神经元连接的唯一路径相关了,更新参数的时候计算量一下子降到了O(log(n))。
关于这方面的源码编写可以参考 这个美国老哥的博客 。
如何利用深度学习技术训练聊天机器人语言模型
数据预处理
模型能聊的内容也取决于选取的语料。如果已经具备了原始聊天数据,可以用SQL通过关键字查询一些对话,也就是从大库里选取出一个小库来训练。从一些论文上,很多算法都是在数据预处理层面的,比如Mechanism-Aware Neural Machine for Dialogue Response Generation就介绍了,从大库中抽取小库,然后再进行融合,训练出有特色的对话来。
对于英语,需要了解NLTK,NLTK提供了加载语料,语料标准化,语料分类,PoS词性标注,语意抽取等功能。
另一个功能强大的工具库是CoreNLP,作为 Stanford开源出来的工具,特色是实体标注,语意抽取,支持多种语言。
下面主要介绍两个内容:
中文分词
现在有很多中文分词的SDK,分词的算法也比较多,也有很多文章对不同SDK的性能做比较。做中文分词的示例代码如下。
# coding:utf8
'''
Segmenter with Chinese
'''
import jieba
import langid
def segment_chinese_sentence(sentence):
'''
Return segmented sentence.
'''
seg_list = jieba.cut(sentence, cut_all=False)
seg_sentence = u" ".join(seg_list)
return seg_sentence.strip().encode('utf8')
def process_sentence(sentence):
'''
Only process Chinese Sentence.
'''
if langid.classify(sentence)[0] == 'zh':
return segment_chinese_sentence(sentence)
return sentence
if __name__ == "__main__":
print(process_sentence('飞雪连天射白鹿'))
print(process_sentence('I have a pen.'))
以上使用了langid先判断语句是否是中文,然后使用jieba进行分词。
在功能上,jieba分词支持全切分模式,精确模式和搜索引擎模式。
全切分:输出所有分词。
精确:概率上的最佳分词。
所有引擎模式:对精确切分后的长句再进行分词。
jieba分词的实现
主要是分成下面三步:
1、加载字典,在内存中建立字典空间。
字典的构造是每行一个词,空格,词频,空格,词性。
上诉书 3 n
上诉人 3 n
上诉期 3 b
上诉状 4 n
上课 650 v
建立字典空间的是使用python的dict,采用前缀数组的方式。
使用前缀数组的原因是树结构只有一层 - word:freq,效率高,节省空间。比如单词"dog", 字典中将这样存储:
{
"d": 0,
"do": 0,
"dog": 1 # value为词频
}
字典空间的主要用途是对输入句子建立有向无环图,然后根据算法进行切分。算法的取舍主要是根据模式 - 全切,精确还是搜索。
2、对输入的语句分词,首先是建立一个有向无环图。
有向无环图, Directed acyclic graph (音 /ˈdæɡ/)。
【图 3-2】 DAG
DAG对于后面计算最大概率路径和使用HNN模型识别新词有直接关系。
3、按照模式,对有向无环图进行遍历,比如,在精确模式下,便利就是求最大权重和的路径,权重来自于在字典中定义的词频。对于没有出现在词典中的词,连续的单个字符也许会构成新词。然后用HMM模型和Viterbi算法识别新词。
精确模型切词:使用动态规划对最大概率路径进行求解。
最大概率路径:求route = (w1, w2, w3 ,.., wn),使得Σweight(wi)最大。Wi为该词的词频。
更多的细节还需要读一下jieba的源码。
自定义字典
jieba分词默认的字典是:1998人民日报的切分语料还有一个msr的切分语料和一些txt小说。开发者可以自行添加字典,只要符合字典构建的格式就行。
jieba分词同时提供接口添加词汇。
Word embedding
使用机器学习训练的语言模型,网络算法是使用数字进行计算,在输入进行编码,在输出进行解码。word embedding就是编解码的手段。
【图 3-3】 word embedding, Ref. #7
word embedding是文本的数值化表示方法。表示法包括one-hot,bag of words,N-gram,分布式表示,共现矩阵等。
Word2vec
近年来,word2vec被广泛采用。Word2vec输入文章或者其他语料,输出语料中词汇建设的词向量空间。详细可参考word2vec数学原理解析。
使用word2vec
安装完成后,得到word2vec命令行工具。
word2vec -train "data/review.txt" /
-output "data/review.model" /
-cbow 1 /
-size 100 /
-window 8 /
-negative 25 /
-hs 0 /
-sample 1e-4 /
-threads 20 /
-binary 1 /
-iter 15
-train "data/review.txt" 表示在指定的语料库上训练模型
-cbow 1 表示用cbow模型,设成0表示用skip-gram模型
-size 100 词向量的维度为100
-window 8 训练窗口的大小为8 即考虑一个单词的前八个和后八个单词
-negative 25 -hs 0 是使用negative sample还是HS算法
-sample 1e-4 采用阈值
-threads 20 线程数
-binary 1 输出model保存成2进制
-iter 15 迭代次数
在训练完成后,就得到一个model,用该model可以查询每个词的词向量,在词和词之间求距离,将不同词放在数学公式中计算输出相关性的词。比如:
vector("法国") - vector("巴黎) + vector("英国") = vector("伦敦")"
对于训练不同的语料库,可以单独的训练词向量模型,可以利用已经训练好的模型。
其它训练词向量空间工具推荐:Glove。
Seq2Seq
2014年,Sequence to Sequence Learning with Neural Networks提出了使用深度学习技术,基于RNN和LSTM网络训练翻译系统,取得了突破,这一方法便应用在更广泛的领域,比如问答系统,图像字幕,语音识别,撰写诗词等。Seq2Seq完成了【encoder + decoder - target】的映射,在上面的论文中,清晰的介绍了实现方式。
【图 3-4】 Seq2Seq, Ref. #1
也有很多文章解读它的原理。在使用Seq2Seq的过程中,虽然也研究了它的结构,但我还不认为能理解和解释它。下面谈两点感受:
a. RNN保存了语言顺序的特点,这和CNN在处理带有形状的模型时如出一辙,就是数学模型的设计符合物理模型。
【图 3-5】 RNN, Ref. #6
b. LSTM Cell的复杂度对应了自然语言处理的复杂度。
【图 3-6】 LSTM, Ref. #6
理由是,有人将LSTM Cell尝试了多种其它方案传递状态,结果也很好。
【图 3-7】 GRU, Ref. #6
LSTM的一个替代方案:GRU。只要RNN的Cell足够复杂,它就能工作的很好。
使用DeepQA2训练语言模型
准备工作,下载项目:
git clone
cd DeepQA2
open README.md # 根据README.md安装依赖包
DeepQA2将工作分成三个过程:
数据预处理:从语料库到数据字典。
训练模型:从数据字典到语言模型。
提供服务:从语言模型到RESt API。
预处理
DeepQA2使用Cornell Movie Dialogs Corpus作为demo语料库。
原始数据就是movie_lines.txt 和movie_conversations.txt。这两个文件的组织形式参考README.txt
deepqa2/dataset/preprocesser.py是将这两个文件处理成数据字典的模块。
train_max_length_enco就是问题的长度,train_max_length_deco就是答案的长度。在语料库中,大于该长度的部分会被截断。
程序运行后,会生成dataset-cornell-20.pkl文件,它加载到python中是一个字典:
word2id存储了{word: id},其中word是一个单词,id是int数字,代表这个单词的id。
id2word存储了{id: word}。
trainingSamples存储了问答的对话对。
比如 [[[1,2,3],[4,5,6]], [[7,8,9], [10, 11, 12]]]
1,2,3 ... 12 都是word id。
[1,2,3] 和 [4,5,6] 构成一个问答。 [7,8,9] 和 [10, 11, 12] 构成一个问答。
开始训练
cp config.sample.ini config.ini # modify keys
python deepqa2/train.py
config.ini是配置文件, 根据config.sample.ini进行修改。训练的时间由epoch,learning rate, maxlength和对话对的数量而定。
deepqa2/train.py大约100行,完成数据字典加载、初始化tensorflow的session,saver,writer、初始化神经元模型、根据epoch进行迭代,保存模型到磁盘。
session是网络图,由placeholder, variable, cell, layer, output 组成。
saver是保存model的,也可以用来恢复model。model就是实例化variable的session。
writer是查看loss fn或者其他开发者感兴趣的数据的收集器。writer的结果会被saver保存,然后使用tensorboard查看。
Model
Model的构建要考虑输入,状态,softmax,输出。
定义损耗函数,使用AdamOptimizer进行迭代。
最后,参考一下训练的loop部分。
每次训练,model会被存储在 save路径下,文件夹的命名根据机器的hostname,时间戳生成。
提供服务
在TensorFlow中,提供了标准的serving模块 - tensorflow serving。但研究了很久,还专门看了一遍 《C++ Essentials》,还没有将它搞定,社区也普遍抱怨tensorflow serving不好学,不好用。训练结束后,使用下面的脚本启动服务,DeepQA2的serve部分还是调用TensorFlow的python api。
cd DeepQA2/save/deeplearning.cobra.vulcan.20170127.175256/deepqa2/serve
cp db.sample.sqlite3 db.sqlite3
python manage.py runserver 0.0.0.0:8000
测试
POST /api/v1/question HTTP/1.1
Host: 127.0.0.1:8000
Content-Type: application/json
Authorization: Basic YWRtaW46cGFzc3dvcmQxMjM=
Cache-Control: no-cache
{"message": "good to know"}
response
{
"rc": 0,
"msg": "hello"
}
serve的核心代码在serve/api/chatbotmanager.py中。
使用脚本
scripts/start_training.sh 启动训练
scripts/start_tensorboard.sh 启动Tensorboard
scripts/start_serving.sh 启动服务
对模型的评价
目前代码具有很高的维护性,这也是从DeepQA项目进行重构的原因,更清晰的数据预处理、训练和服务。有新的变更可以添加到deepqa2/models中,然后在train.py和chatbotmanager.py变更一下。
有待改进的地方
a. 新建models/rnn2.py, 使用dropout。目前DeepQA中已经使用了Drop.
b. tensorflow rc0.12.x中已经提供了seq2seq network,可以更新成tf版本.
c. 融合训练,目前model只有一个库,应该是设计一个新的模型,支持一个大库和小库,不同权重进行,就如Mechanism-Aware Neural Machine for Dialogue Response Generation的介绍。
d. 代码支持多机多GPU运行。
e. 目前训练的结果都是QA对,对于一个问题,可以有多个答案。
f. 目前没有一个方法进行accuracy测试,一个思路是在训练中就提供干扰项,因为当前只有正确的答案,如果提供错误的答案(而且越多越好),就可以使用recall_at_k方法进行测试。
机器人家上了解到的,希望对你有用