当前位置:   article > 正文

python+TensorFlow聊天机器人_聊天机器人及模型 持久化

聊天机器人及模型 持久化

一、遇到的问题解决

1.jieba分词的cut()方法:是一个生成器,返回一个列表,可以遍历查看。

精准模式

全模式:lists= [word for word in jieba.cut(s,cut_all=True)]
               ['我', '是', '张', '三', ',', '今天', '今天天气', '天天', '天气', '真好']

2.运行报错

readlines():

UnicodeDecodeError: 'gbk' codec can't decode byte 0x86 in position 22: illegal multibyte sequence

解决:            with open(file, 'r') as file_object:改为            with open(file, 'r',encoding='UTF-8') as file_object:

二、流程

1.reset_default_graph清除当前线程默认图形堆栈,重置全局默认图形

2.训练模型

1)构造训练集

  读取问题与回答的数据,进行结巴分词,为每个词形成id,词和对应id保存在两个集合中。

  为答案的句子添加'<EOS>'用来指示decoder什么时候停止预测。

           训练集为:问题向量,答案向量

2)构造模型

设置学习率、优化方法等参数

3)模型训练

训练让loss变小,

训练10000次结果:

4)保存模型

3.reset_default_graph清除当前线程默认图形堆栈,重置全局默认图形

4.模型预测

1)加载模型

2)输入问题,对数据进行处理

3)输出结果

三、代码

  1. def get_model(feed_previous=False):
  2. """构造模型
  3. """
  4. learning_rate = tf.Variable(float(init_learning_rate), trainable=False, dtype=tf.float32)
  5. learning_rate_decay_op = learning_rate.assign(learning_rate * 0.9)
  6. encoder_inputs = []
  7. decoder_inputs = []
  8. target_weights = []
  9. for i in range(input_seq_len):
  10. encoder_inputs.append(tf.placeholder(tf.int32, shape=[None], name="encoder{0}".format(i)))
  11. for i in range(output_seq_len + 1):
  12. decoder_inputs.append(tf.placeholder(tf.int32, shape=[None], name="decoder{0}".format(i)))
  13. for i in range(output_seq_len):
  14. target_weights.append(tf.placeholder(tf.float32, shape=[None], name="weight{0}".format(i)))
  15. # decoder_inputs左移一个时序作为targets
  16. targets = [decoder_inputs[i + 1] for i in range(output_seq_len)]
  17. cell = tf.contrib.rnn.BasicLSTMCell(size)
  18. # 这里输出的状态我们不需要
  19. outputs, _ = seq2seq.embedding_attention_seq2seq(
  20. encoder_inputs,
  21. decoder_inputs[:output_seq_len],
  22. cell,
  23. num_encoder_symbols=num_encoder_symbols,
  24. num_decoder_symbols=num_decoder_symbols,
  25. embedding_size=size,
  26. output_projection=None,
  27. feed_previous=feed_previous,
  28. dtype=tf.float32)
  29. # 计算加权交叉熵损失
  30. loss = seq2seq.sequence_loss(outputs, targets, target_weights)
  31. # 使用自适应优化器
  32. opt = tf.train.AdamOptimizer(learning_rate=learning_rate)
  33. # 优化目标:让loss最小化
  34. update = opt.apply_gradients(opt.compute_gradients(loss))
  35. # 模型持久化
  36. saver = tf.train.Saver(tf.global_variables())
  37. return encoder_inputs, decoder_inputs, target_weights, outputs, loss, update, saver, learning_rate_decay_op, learning_rate
  38. def train():
  39. """
  40. 训练过程
  41. """
  42. train_set = get_train_set()
  43. with tf.Session() as sess:
  44. encoder_inputs, decoder_inputs, target_weights, outputs, loss, update, saver, learning_rate_decay_op, learning_rate = get_model()
  45. # 全部变量初始化
  46. sess.run(tf.global_variables_initializer())
  47. # 训练很多次迭代,每隔100次打印一次loss,可以看情况直接ctrl+c停止
  48. previous_losses = []
  49. for step in range(10000):
  50. sample_encoder_inputs, sample_decoder_inputs, sample_target_weights = get_samples(train_set, 1000)
  51. input_feed = {}
  52. for l in range(input_seq_len):
  53. input_feed[encoder_inputs[l].name] = sample_encoder_inputs[l]
  54. for l in range(output_seq_len):
  55. input_feed[decoder_inputs[l].name] = sample_decoder_inputs[l]
  56. input_feed[target_weights[l].name] = sample_target_weights[l]
  57. input_feed[decoder_inputs[output_seq_len].name] = np.zeros([len(sample_decoder_inputs[0])], dtype=np.int32)
  58. [loss_ret, _] = sess.run([loss, update], input_feed)
  59. if step % 100 == 0:
  60. print( 'step=', step, 'loss=', loss_ret, 'learning_rate=', learning_rate.eval())
  61. if len(previous_losses) > 5 and loss_ret > max(previous_losses[-5:]):
  62. sess.run(learning_rate_decay_op)
  63. previous_losses.append(loss_ret)
  64. # 模型持久化
  65. saver.save(sess, output_dir)
  66. def predict():
  67. """
  68. 预测过程
  69. """
  70. with tf.Session() as sess:
  71. encoder_inputs, decoder_inputs, target_weights, outputs, loss, update, saver, learning_rate_decay_op, learning_rate = get_model(feed_previous=True)
  72. saver.restore(sess, output_dir)
  73. sys.stdout.write("> ")
  74. sys.stdout.flush()
  75. input_seq=input()
  76. while input_seq:
  77. input_seq = input_seq.strip()
  78. input_id_list = get_id_list_from(input_seq)
  79. if (len(input_id_list)):
  80. sample_encoder_inputs, sample_decoder_inputs, sample_target_weights = seq_to_encoder(' '.join([str(v) for v in input_id_list]))
  81. input_feed = {}
  82. for l in range(input_seq_len):
  83. input_feed[encoder_inputs[l].name] = sample_encoder_inputs[l]
  84. for l in range(output_seq_len):
  85. input_feed[decoder_inputs[l].name] = sample_decoder_inputs[l]
  86. input_feed[target_weights[l].name] = sample_target_weights[l]
  87. input_feed[decoder_inputs[output_seq_len].name] = np.zeros([2], dtype=np.int32)
  88. # 预测输出
  89. outputs_seq = sess.run(outputs, input_feed)
  90. # 因为输出数据每一个是num_decoder_symbols维的,因此找到数值最大的那个就是预测的id,就是这里的argmax函数的功能
  91. outputs_seq = [int(np.argmax(logit[0], axis=0)) for logit in outputs_seq]
  92. # 如果是结尾符,那么后面的语句就不输出了
  93. if EOS_ID in outputs_seq:
  94. outputs_seq = outputs_seq[:outputs_seq.index(EOS_ID)]
  95. outputs_seq = [wordToken.id2word(v) for v in outputs_seq]
  96. print(" ".join(outputs_seq))
  97. else:
  98. print("WARN:词汇不在服务区")
  99. sys.stdout.write("> ")
  100. sys.stdout.flush()
  101. input_seq = input()
  102. if __name__ == "__main__":
  103. tf.reset_default_graph()
  104. train()
  105. tf.reset_default_graph()
  106. predict()

四、结果


 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/337151
推荐阅读
相关标签
  

闽ICP备14008679号