import tensorflow as tf
from nlpia.loaders import get_data
from keras.models import Model,load_model
from keras.layers import Input,LSTM,Dense
import os
import numpy as np
#为训练准备语料库
df=get_data('moviedialog')
input_texts,target_texts=[],[]#数组保存从语料文库中读取输入文本和目标文本
input_vocabulary=set()#这个集合保存输入文本和目标文本中出现的字符
output_vocabulary=set()
start_token='\t' #目标序列用startstop词条进行注释
stop_token='\n'
max_training_samples=min(25000,len(df)-1) #定义了训练使用的行数
for input_text,target_text in zip(df.statement,df.reply):
target_text=start_token+target_text\
+stop_token
input_texts.append(input_text)
target_texts.append(target_text)
for char in input_text:
if char not in input_vocabulary:
input_vocabulary.add(char)
for char in target_text:
if char not in output_vocabulary:
output_vocabulary.add(char)
#建立字符字典
#将字符集装换为排序后的字符列表
input_vocabulary=sorted(input_vocabulary)
output_vocabulary=sorted(output_vocabulary)
input_vocab_size=len(input_vocabulary)
output_vocab_size=len(output_vocabulary)
max_encoder_seq_length=max([len(txt) for txt in input_texts])
max_decoder_seq_length=max([len(txt) for txt in target_texts])
input_token_index=dict([(char,i)for i,char in enumerate(input_vocabulary)])#创建查找字典,用于生成独热向量
target_token_index=dict(
[(char,i) for i,char in enumerate(output_vocabulary)]);
reverse_input_char_index=dict((i,char)for char,i in input_token_index.items());#创建反向查询表
reverse_target_char_index=dict((i,char)for char,i in target_token_index.items());
#生成独热码训练集
encoder_input_data=np.zeros((len(input_texts),max_encoder_seq_length,input_vocab_size),dtype='float32');
decoder_input_data=np.zeros((len(input_texts),max_decoder_seq_length,output_vocab_size),dtype='float32');
decoder_target_data=np.zeros((len(input_texts),max_decoder_seq_length,output_vocab_size),dtype='float32');
#将每个时刻字符索引设置为1
for i,(input_text,target_text) in enumerate(
zip(input_texts,target_texts)):
for t,char in enumerate(input_text):
encoder_input_data[i,t,input_token_index[char]]=1.
for t,char in enumerate(target_text):
decoder_input_data[
i,t,target_token_index[char]
]=1.
if t>0:
decoder_target_data[i,t-1,target_token_index[char]]=1;
#训练序列到序列聊天机器人
batch_size=64;
epochs=10;
num_neurons=256;
encoder_inputs = Input(shape=(None, input_vocab_size))
encoder = LSTM(num_neurons, return_state=True)
encoder_outputs, state_h, state_c = encoder(encoder_inputs)
encoder_states = [state_h, state_c]
decoder_inputs = Input(shape=(None, output_vocab_size))
decoder_lstm = LSTM(num_neurons, return_sequences=True, return_state=True)
decoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state=encoder_states)
decoder_dense = Dense(output_vocab_size, activation='softmax')
decoder_outputs = decoder_dense(decoder_outputs);
model = Model([encoder_inputs, decoder_inputs], decoder_outputs);
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['acc'])
cp_callback=tf.keras.callbacks.ModelCheckpoint(filepath='模型参数.h5',
save_weights_only=False,save_best_only=True)
model.fit([encoder_input_data,decoder_input_data],
decoder_target_data,batch_size=batch_size,epochs=epochs,
validation_split=0.1,callbacks=[cp_callback])
#组装序列生成模型
encoder_model=Model(encoder_inputs,encoder_states);
thought_input=[Input(shape=(num_neurons,)),Input(shape=(num_neurons,))];
decoder_outputs,state_h,state_c=decoder_lstm(decoder_inputs,initial_state=thought_input)
decoder_states=[state_h,state_c]
decoder_outputs=decoder_dense(decoder_outputs)
decoder_model=Model(inputs=[decoder_inputs]+thought_input,
outputs=[decoder_outputs]+decoder_states)
#预测输出序列
def decode_sequence(input_seq):
thought=encoder_model.predict(input_seq)#生成思想向量作为解码器的输入
target_seq=np.zeros((1,1,output_vocab_size)) #与训练相反,target_seq一开始是一个零张量
target_seq[0,0,target_token_index[stop_token]]=1.
stop_condition=False
generated_sequence=''
while not stop_condition:
output_tokens,h,c=decoder_model.predict([target_seq]+thought) #将已生成的词条和最新的状态传递给解码器,以预测下一个序列元素
generated_token_idx=np.argmax(output_tokens[0,-1:1])
generated_char=reverse_target_char_index[generated_token_idx]
generated_sequence+=generated_char
if(generated_char==stop_token or len(generated_sequence)>max_decoder_seq_length):
stop_condition=True
target_seq=np.zeros((1,1,output_vocab_size))#更新目标序列,并使用最后生成的词条作为下一生成步骤的输入
target_seq[0,0,generated_token_idx]=1.
thought=[h,c] #更新思想状态
return generated_sequence
#生成回复
def response(input_text):
input_seq=np.zeros((1,max_encoder_seq_length,input_vocab_size),dtype='float32')
for t,char in enumerate(input_text): #对输入文本的每个字符进行循环遍历
input_seq[0,t,input_token_index[char]]=1.
decoded_sentence=decode_sequence(input_seq)
print('Bot Reply(Decoded sentence):',decoded_sentence)
response("who are you?")
seq2seq实现聊天机器人(代码)
最新推荐文章于 2023-04-24 09:07:03 发布