一步步构建对话机器人

—一步步构建对话机器人
title: 一步步构建对话机器人
tags: 新建,模板,小书匠

grammar_cjkRuby: true

本文基于斯坦福大学CS 20SI: “TensorFlow for Deep Learning Research”,训练语料为Cornell Movie-Dialogs Corpus

一、数据处理

1.数据结构

语料关键是下面两个文件,一个包含了所有文本,一个包含了文本之间的关系

  • movie_lines.txt

    • 包含每个表达(utterance)的实际文本
    • fields:
      • lineID
      • characterID (who uttered this phrase)
      • movieID
      • character name
      • text of the utterance
        前面5个样本:
        L1045 +++ +++u0+++ +++ m0 +++ +++BIANCA+++ +++ They do not!
        L1044 +++ +++u2+++ +++ m0 +++ +++CAMERON+++ +++ They do to!
        L985 +++ +++u0+++ +++ m0 +++ +++BIANCA+++ +++ I hope so.
        L984 +++ +++u2+++ +++ m0 +++ +++CAMERON+++ +++ She okay?
        L925 +++ +++u0+++ +++ m0 +++ +++BIANCA+++ +++ Let’s Go.
  • movie_conversations.txt

    • 对话的结构-
    • fields

      • characterID of the first character involved in the conversation 对话中的第一个角色的ID
      • characterID of the second character involved in the conversation 对话中的第二个角色的ID
      • movieID of the movie in which the conversation occurred 对话所属电影的ID

      • list of the utterances that make the conversation, in chronological
        order: [‘lineID1’,’lineID2’,?’lineIDN’]
        has to be matched with movie_lines.txt to reconstruct the actual content
        对话中以时间顺序的各个表达的列表,
        order: [‘lineID1’,’lineID2’,?’lineIDN’]必须和movie_lines.txt匹配以便于重构实际内容
        前面5个样本:
        u0 +++ +++u2+++ +++ m0 +++ +++[L194,L195,L196,L197]u0+++ +++ u2 +++ +++m0+++ +++ [‘L198’, ‘L199’]
        u0 +++ +++u2+++ +++ m0 +++ +++[L200,L201,L202,L203]u0+++ +++ u2 +++ +++m0+++ +++ [‘L204’, ‘L205’, ‘L206’]
        u0 +++ +++u2+++ +++ m0 +++$+++ [‘L207’, ‘L208’]
        因此我们需要对这两个文件分别清洗后进行匹配,获取对话内容

2.Bucketing

sequences长度是RNN网络数据预处理要考虑的重要问题,通常而言,我们要处理的序列长度都不是固定的。我们需要将其-padding成固定
长度的序列进行处理,具体而言就是在序列中添加0等标记进行填充。但这些padding的值会改变输出的loss值,影响真正的梯度,会对我们的结果
造成很大的影响。
解决方案通常有两个:一是进行掩码处理,将真实值设为TRUE,padded值设为FALSE,在loss计算时只计算真实值;二是采用dynamic_rnn等模型设定
真实序列长度,使模型只预测真实值。
另外,为降低padding带来的影响,本次聊天机器人,在数据处理时,还将语料具有相似长度的序列进行group,划分为多个buckets,对每个bucket分别构建子图进行
处理。

二、模型

1.函数

主要使用tensorflow的3个函数:
(1)损失函数采用sampled_softmax_loss
如果每次predict,都要对整个dic进行规范因子计算,无疑计算量太大,为降低计算量,采用sampled_softmax,这样每次只需要更新一小部分词典就可以了。
但若采用sampled_softmax,首先要构建output_projection,这样decode时每一stepe输出的词作为下一step输入时,使用output_projection映射到具体的词,就能顺利
获得对应的词向量

sampled_softmax_loss(
    weights, #定义的output_projection的权重 w
    biases,#定义的output_projection的权重b
    labels,#真实词
    inputs,#输入词
    num_sampled,,#每次更新采样的数目
    num_classes,#字典的数目
    num_true=1,#每个训练样本对应类别个数,默认一个训练样本一个真实类别
    sampled_values=None,#采样规则
    remove_accidental_hits=True,#采样规则
    partition_strategy='mod',#采样规则
    name='sampled_softmax_loss'
)

(2)整体构架采用embedding_attention_seq2seq

embedding_attention_seq2seq(encoder_inputs,# encoder端输入
                                decoder_inputs,,# decoder端输入
                                cell,# 本次采用GRU Cell
                                num_encoder_symbols,# encoder字典数目
                                num_decoder_symbols,,# decoder字典数目
                                embedding_size,,# decoder字典数目
                                num_heads=1,# attention读取次数
                                output_projection=None,#前面说的输出映射(w,b)
                                feed_previous=False,#是否采用上一次输出作为本时刻的输入,这是设置为True
                                dtype=None,
                                scope=None,
                                initial_state_attention=False)

(3)如上所述,我们对语料进行buckets分类,因此最后要将上述两个函数嵌入到model_with_buckets函数

model_with_buckets(encoder_inputs,
                       decoder_inputs,
                       targets,
                       weights,
                       buckets,
                       seq2seq,#前面定义的embedding_attention_seq2seq
                       softmax_loss_function=None,#前面定义的sampled_softmax_loss
                       per_example_loss=False,
                       name=None):

三、训练

模型构建完成后,下一步就是进行训练,这没什么好说的,记得做好断点保存就行

四、测试

激动人心的时刻来了,看下效果如何:
这里写图片描述
这里写图片描述

可以看到,很多话都没有任何意义的,但也有几句还是有些感觉的。
但我感觉还是不错的,毕竟训练语料不大,而且还有以下提升的地方:
1.采用词嵌入应该会好些,以后有机会再试试
2.训练时间只有6个小时左右,应该还有提升的空间
3.模型encode-decode每次只是一轮对话内容,但如何实现多轮对话训练?也许encode端输入前几轮对话内容?或者增加记忆功能
4.decoder解码本次采用的是greedy算法,也许采用Beam Search会更好一些
5.最后,加深模型,增加新词发现能力,可能会更好些
最终代码在这:别忘了点个赞哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值