上一次提到了不错的学习聊天机器人的资源,不知道小伙伴们有没有去学习呢。

自己动手做聊天机器人教程

我最近每天都会学一点,拿出解读来和大家分享一下。

本文结构:

聊天机器人的架构简图

用 TensorFlow 实现 Chatbot 的模型

如何准备 chatbot 的训练数据

Chatbot 源码解读

1. 聊天机器人的架构简图

聊天机器人的工作流程大体为:提问-检索-答案抽取。

提问:就是要分析主人的问句中关键词,提问类型,还有真正想知道的东西。

检索:根据前一步的分析,去找答案。

答案抽取:找到的答案,并不能直接应用,还要整理成真正有用的,可以作为答案的回答。

涉及到的关键技术如图中所示。

看不清图的话,就是酱紫:

问句解析:

中文分词、词性标注、实体标注、概念类别标注、句法分析、语义分析、逻辑结构标注、指代消解、关联关系标注、问句分类、答案类别确定;

海量文本知识表示:

网络文本资源获取、机器学习方法、大规模语义计算和推理、知识表示体系、知识库构建

答案生成与过滤:

候选答案抽取、关系推演、吻合程度判断、噪声过滤

2. 用 TensorFlow 实现 Chatbot 的模型

之前有根据 Siraj 的视频写过一篇《自己动手写个聊天机器人吧》,

文章里只写了主函数的简单过程:Data-Model-Training,是用 Lua 实现的,详细的代码可以去他的 github 上学习

下面这篇文章是用 TensorFlow + tflearn 库 实现,在 建模, 训练 和 预测 等环节可以学到更多细节:

两篇的共同点是都用了 Seq2Seq 来实现。

LSTM的模型结构为:

细节的话可以直接去看上面那篇原文,这里 po 出建立模型阶段简要的流程图和过程描述:

先将原始数据 300w chat 做一下预处理,即 切词,分为 问答对。

然后用 word2vec 训练出词向量,生成二进制的词向量文件。

作为 Input data X 传入下面流程:

question 进入 LSTM 的 encoder 环节,answer 进入 decoder 环节,

分别生成 output tensor。

其中 decoder 是一个词一个词的生成结果,将所有结果加入到一个 list 中。

最后和 encoder 的输出,一起做为下一环节 Regression 的输入,并传入 DNN 网络。

3. 如何准备 chatbot 的训练数据

训练数据的生成过程如下:

首先在 input file 里读取每一行,并根据 ‘|’ 拆分成 question 和 answer 句子。

每个句子,都将 word 通过 word2vec 转化成词向量。

每一句的向量序列都转化成相同维度的形式:self.word_vec_dim * self.max_seq_len

最后 answer 构成了 y 数据,question+answer 构成了 xy 数据,再被投入到 model 中去训练:

model.fit(trainXY, trainY, n_epoch=1000, snapshot_epoch=False, batch_size=1)

代码如下:

def init_seq(input_file):

"""读取切好词的文本文件,加载全部词序列

"""

file_object = open(input_file, 'r')

vocab_dict = {}

while True:

question_seq = []

answer_seq = []

line = file_object.readline()

if line:

line_pair = line.split('|')

line_question = line_pair[0]

line_answer = line_pair[1]

for word in line_question.decode('utf-8').split(' '):

if word_vector_dict.has_key(word):

question_seq.append(word_vector_dict[word])

for word in line_answer.decode('utf-8').split(' '):

if word_vector_dict.has_key(word):

answer_seq.append(word_vector_dict[word])

else:

break

question_seqs.append(question_seq)

answer_seqs.append(answer_seq)

file_object.close()

def generate_trainig_data(self):

xy_data = []

y_data = []

for i in range(len(question_seqs)):

question_seq = question_seqs[i]

answer_seq = answer_seqs[i]

if len(question_seq) < self.max_seq_len and len(answer_seq) < self.max_seq_len:

sequence_xy = [np.zeros(self.word_vec_dim)] * (self.max_seq_len-len(question_seq)) + list(reversed(question_seq))

sequence_y = answer_seq + [np.zeros(self.word_vec_dim)] * (self.max_seq_len-len(answer_seq))

sequence_xy = sequence_xy + sequence_y

sequence_y = [np.ones(self.word_vec_dim)] + sequence_y

xy_data.append(sequence_xy)

y_data.append(sequence_y)

return np.array(xy_data), np.array(y_data)

4. Chatbot 源码解读

提炼出步骤如下:

其中 2. 准备数据, 3. 建立模型 就是上文着重说的部分。

引入包

准备数据

建立模型

训练

预测

1. 引入包

import sys

import math

import tflearn

import tensorflow as tf

from tensorflow.python.ops import rnn_cell

from tensorflow.python.ops import rnn

import chardet

import numpy as np

import struct

2. 准备数据

def load_word_set()

将 3000 万语料,分成 Question 和 Answer 部分,提取出 word。

def load_word_set():

file_object = open('./segment_result_lined.3000000.pair.less', 'r')

while True:

line = file_object.readline()

if line:

line_pair = line.split('|')

line_question = line_pair[0]

line_answer = line_pair[1]

for word in line_question.decode('utf-8').split(' '):

word_set[word] = 1

for word in line_answer.decode('utf-8').split(' '):

word_set[word] = 1

else:

break

file_object.close()

def load_vectors(input)

从 vectors.bin 加载词向量,返回一个 word_vector_dict 的词典,key 是词,value 是200维的向量。

def init_seq(input_file)

将 Question 和 Answer 中单词对应的词向量放在词向量序列中 question_seqs, answer_seqs。

def init_seq(input_file):

"""读取切好词的文本文件,加载全部词序列

"""

file_object = open(input_file, 'r')

vocab_dict = {}

while True:

question_seq = []

answer_seq = []

line = file_object.readline()

if line:

line_pair = line.split('|')

line_question = line_pair[0]

line_answer = line_pair[1]

for word in line_question.decode('utf-8').split(' '):

if word_vector_dict.has_key(word):

question_seq.append(word_vector_dict[word])

for word in line_answer.decode('utf-8').split(' '):

if word_vector_dict.has_key(word):

answer_seq.append(word_vector_dict[word])

else:

break

question_seqs.append(question_seq)

answer_seqs.append(answer_seq)

file_object.close()

def vector_sqrtlen(vector)

用来求向量的长度。

def vector_sqrtlen(vector):

len = 0

for item in vector:

len += item * item

len = math.sqrt(len)

return len

def vector_cosine(v1, v2)

用来求两个向量间的距离。

def vector_cosine(v1, v2):

if len(v1) != len(v2):

sys.exit(1)

sqrtlen1 = vector_sqrtlen(v1)

sqrtlen2 = vector_sqrtlen(v2)

value = 0

for item1, item2 in zip(v1, v2):

value += item1 * item2

return value / (sqrtlen1*sqrtlen2)

def vector2word(vector)

给定一个词向量,去 word-vector 字典中查找与此向量距离最近的向量,并记忆相应的单词,返回单词和 cosine 值。

def vector2word(vector):

max_cos = -10000

match_word = ''

for word in word_vector_dict:

v = word_vector_dict[word]

cosine = vector_cosine(vector, v)

if cosine > max_cos:

max_cos = cosine

match_word = word

return (match_word, max_cos)

3. 建立模型

class MySeq2Seq(object)

在前两篇笔记中单独写了这两块。

def generate_trainig_data(self)

由 question_seqs, answer_seqs 得到 xy_data 和 y_data 的形式。

def model(self, feed_previous=False)

用 input data 生成 encoder_inputs 和带GO头的 decoder_inputs。

将 encoder_inputs 传递给编码器,返回一个输出(预测序列的第一个值)和一个状态(传给解码器)。

在解码器中,用编码器的最后一个输出作为第一个输入,预测过程用前一个时间序的输出作为下一个时间序的输入。

4. 训练

def train(self)

用 generate_trainig_data() 生成 X y 数据,传递给 上面定义的 model,并训练 model.fit,再保存。

def train(self):

trainXY, trainY = self.generate_trainig_data()

model = self.model(feed_previous=False)

model.fit(trainXY, trainY, n_epoch=1000, snapshot_epoch=False, batch_size=1)

model.save('./model/model')

return model

5. 预测

用 generate_trainig_data() 生成数据,用 model.predict 进行预测,predict 结果的每一个 sample 相当于一句话的词向量序列,每个 sample 中的每个 vector 在 word-vector 字典中找到与其最近的向量,并返回对应的 word,及二者间的 cosine。

if __name__ == '__main__':

phrase = sys.argv[1]

if 3 == len(sys.argv):

my_seq2seq = MySeq2Seq(word_vec_dim=word_vec_dim, max_seq_len=max_seq_len, input_file=sys.argv[2])

else:

my_seq2seq = MySeq2Seq(word_vec_dim=word_vec_dim, max_seq_len=max_seq_len)

if phrase == 'train':

my_seq2seq.train()

else:

model = my_seq2seq.load()

trainXY, trainY = my_seq2seq.generate_trainig_data()

predict = model.predict(trainXY)

for sample in predict:

print "predict answer"

for w in sample[1:]:

(match_word, max_cos) = vector2word(w)

#if vector_sqrtlen(w) < 1:

# break

print match_word, max_cos, vector_sqrtlen(w)

我是 不会停的蜗牛 Alice

85后全职主妇

喜欢人工智能,行动派

创造力,思考力,学习力提升修炼进行中

欢迎您的喜欢,关注和评论!

tensorflow聊天机器人python实现_用 TensorFlow 做个聊天机器人相关推荐

  1. 机器人编程python代码_自己动手开发智能聊天机器人完全指南(附python完整源码)...

    一.前言 人工智能时代,开发一款自己的智能问答机器人,一方面提升自己的AI能力,另一方面作为转型AI的实战练习.在此把学习过程记录下来,算是自己的笔记. 二.正文 2.1 下载pyaiml 下载pya ...

  2. tensorflow对应的numpy版本_版本更新 | TensorFlow 2.4.0 候选版本发布

    主要功能改进 tf.distribution 通过 tf.distribution.experimental.ParameterServerStrategy API 引入了对 Keras 模型异步训练 ...

  3. tensorflow画损失函数的代码_使用TensorFlow编写您的第一个神经网络

    介绍 神经网络是受生物神经网络启发而产生的一套特殊的机器学习算法,它们彻底改变了机器学习.简单地说,它们是通用的函数近似,可以应用于几乎任何关于学习从输入到输出空间的复杂映射的机器学习问题. 神经网络 ...

  4. python枪_大疆机甲大师教育机器人Python API中文化之一:枪亮枪暗

    之前开始整理机甲的Python API,但纸上得来终觉浅,而且发现有些API与即使官方qq群的教程文档也有少许出入,于是打算逐个测试.这一系列将附上真机运行视频,以便以后直观看到最终演示效果. 先从灯 ...

  5. 煮饭的机器人作文_【会做家务的机器人】作文(八篇)

    "做家务不用手!思维混乱吧,不用手怎么做家务?"可能有人会这样说.哈哈,你out啦!不用手怎么就不能做家务,不用手照样能做家务!每个母亲都有共同的心愿,让家变成"世外桃源 ...

  6. 机器人车间气管_汽车消声器生产中的焊接机器人应用与工艺流程

    龙源期刊网 http://www.qikan.com.cn 汽车消声器生产中的焊接机器人应用与工艺 流程 作者:孙祥超 来源:<中国化工贸易 · 中旬刊> 2018 年第 03 期 摘 要 ...

  7. 易方机器人教育怎么样_定州3岁以上儿童机器人教学多少钱

    定州3岁以上儿童机器人教学多少钱 b6dtw6h 定州3岁以上儿童机器人教学多少钱 编程课是针对岁的学生推出的一门课程.当孩子编程的时候,他们在中扮演主角,不仅能享受,而且会创造.编程是世纪的必备技能 ...

  8. 六轴机器人光机_烂大街的六轴机器人

    刚开始写公众号的时候,就有朋友问我什么时候也讲讲六轴.我说行,等把SCARA跟DELTA讲完了我就讲.现在SCARA跟DELTA的基本介绍终于写完了,但是想要写六轴却不知怎么写好.无法像之前那些做盘点 ...

  9. 六轴机器人光机_六款小型六轴机器人性能数据大比拼

    [原创]六款小型六轴机器人性能数据大比拼 文章来源自:高工机器人网 2018-04-27 09:06:44 阅读:44963 摘要从全球机器人应用由汽车向3C等其它行业扩散的趋势来看,为3C制造而生的 ...

  10. 智能语音的扫地机器人介简_岚豹激光智能扫地机器人之语音控制

    01岚豹智能扫地机语音控制 想必大家都看过复仇者联盟电影,都羡慕钢铁侠妮妮有一个无所不能.聪明智能的Jarvis管家,有什么需求一句话就能搞定.现在大家不用再羡慕,只要你开口指令,我也能闻声启动,这就 ...

最新文章

  1. [cocos2dx UI] CCLabelAtlas 为什么不显示最后一个字
  2. linux开机自动执行命令或自动启动程序(rc.local)
  3. WinAPI: GetSystemPowerStatus - 获取系统电源状态的信息
  4. 构建高性能.NET应用之配置高可用IIS服务器-第二篇 IIS请求处理模型
  5. [vue] 你有写过自定义组件吗?
  6. srand(设置随机数种子)
  7. C++/C--字符串分割函数 --strtok()
  8. Jafka来源分析——文章
  9. 动态规划之回文串问题
  10. 内置炊具行业调研报告 - 市场现状分析与发展前景预测
  11. jsp 页面之${fn:}内置函数列表
  12. 开张第一天,一年之际在于春
  13. 钉钉日志范文100篇_关于公司各岗位钉钉日志撰写标准
  14. html制作朋友圈素材,微信朋友圈图文素材
  15. 分页查询优化方案总结
  16. 优云系统提供哪些服务器,优云服务器异常
  17. 我推荐阅读的微信公众号-IT类
  18. 每天学习一个Android中的常用框架——0.目录
  19. C语言的按位取反符号~(详解)
  20. 群晖python套件包_群晖中给Python3安装pip工具以安装扩展包

热门文章

  1. 饥荒模块显示检查工作室订阅服务器,为什么我的饥荒主界面mod点进去就显示检查 – 手机爱问...
  2. OpenGL——EGL
  3. Centos下增加swap空间
  4. 2022年天猫超市春节不打烊活动时间规定
  5. [管理新思维]社会化管理和开放式创新|裂变式创业
  6. 华为荣耀8青春版手机无限重启,系统修复后, 与usb有关的奇怪问题
  7. html中删除代码怎么写,Word删除html代码怎么写
  8. 【Unity破事水】如何实现线上试卷选择题的选项
  9. 天天炫斗服务器维修,天天炫斗连接服务器超时怎么办|天天炫斗连接服务器超时解决方法_好特教程...
  10. 计算机毕业设计之java+springboot基于vue的网上图书商城系统