导读部分
对话系统最核心的部分是什么,seq2seq,现在tensorflow已经提供seq2seq封装的调用方法,相对方便,但是理解seq2seq内部原理,自己动手写的话是对模型设计思路的梳理,加深对原设计的理解。长期来说,有益。
那么seq2seq里面最核心的部分呢,编码和解码过程都是用LSTM网络结构来完成的。所以上篇咱们剖析了对话系统seq2seq+attention的内部原理(聊天机器人专辑《一》),从本篇开始,《智能客服聊天机器人专辑二代码篇》正式开始了。打算分为三个核心部分,循序渐进:
1.理解seq2seq编码过程,核心用到的网络结构LSTM,手把手搭建LSTM模型,代码实战。
2.完成咱们第一部分LSTM的网络搭建后,下面我们可以更递进进入两个LSTM的搭建,也就是完整的seq2seq模型了。为什么会用到两个LSTM呢,复习下《聊天机器人专辑一》聊天机器人Seq2Seq模型+attention(理论篇-图文详解)的原理部分就知道,seq2seq是编码和解码两个过程组合的,编码用到一个LSTM,解码用到一个LSTM网络。所以跟着完成第一部分,第二部分完整的seq2seq也可以打牢基础,更理解深刻地写出来seq2seq完整的网络了。
3.Transformer代码部分的实现。主要是实现咱们专辑一的注意力机制,把翻译的语句捋顺,润滑,避免颠倒次序,譬如‘我在编程‘翻译成’’‘编程在我’。当然这一块已经业内用BERT+LSTM+Transformer了。所以考虑要不要衍生4出来。(BERT完美解决文本词向量特征这块)
好,咱们《聊天机器人专辑二》之2.1篇 ——核心网络LSTM实战搭建开始。
《聊天机器人专辑二——seq2seq核心网络模型LSTM搭建》
LSTM的搭建包含三个核心点:
1.文本数据预处理,另外为了灌入网络模型LSTM,将原有的文本数据按照LSTM输入数据规格来组合,注意LSTM要求输入三维的数据。必须将之前的预处理的文本按照LSTM input_shape的要求,进行reshape或者Embedding 起来。(这一部分本文略过,中文文本数据预处理之前的博文里已经贴出代码讲过案例,请自行点蓝色标题对照复习补全,穿越到本博客AI工匠:
《文本分类NLP豆瓣电影短评中文文本分类实战代码Jieba+sklearn》
2完成预处理后,开始基于Keras搭建网络模型LSTM (本文重点)
3.基于Keras如何自动调整学习率,找到最优模型参数组合。(本文代码包含)
以上就是本文的数据流处理过程,简单理解1准备食材,洗的洗,摘的摘,切好放盘里——2烧菜流程模拟一遍,先小火热油,大火爆炒,小火慢炖收汁——3调节盐糖鸡精等调味品的参素,组合做出最美味的佳肴。
准备食材,文本预处理过程包含1去除停用词,2去除非中文字符,3分词,4词向量化表示。
至于2和3烧菜和调味这两部分,本文重点围绕LSTM模型构建的关键点,以实例代码说明。也是上一篇智能聊天机器人对话系统中编译模型LSTM的核心实现部分。
下面直接上代码:
import os
import keras
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score
from keras.models import Model
from keras.layers import Dense, LSTM
from keras.layers import Dropout,Activation
from keras.models import Sequential
from keras.utils import to_categorical
import utils
def main():
df=utils.prepare_data()
train_data,test_data=train_test_split(df,test_size=0.25,random_state=0)
#特征工程
train_X,test_X,lib_a,lib_b=utils.do_feature_engineering(train_data,test_data)
print(train_X.shape)
print(test_X.shape)
print('tfidf.vocabulary:')
print({k:lib_a[k] for k in list(lib_a.keys())[0:100]})
print('count.vocabulary:')
print({k:lib_b[k] for k in list(lib_b.keys())[0:100]})
#标签处理
train_y=np.array(train_data['label'].values)
train_y=to_categorical(train_y)
test_y=np.array(test_data['label'].values)
test_y=to_categorical(test_y)
#LSTM输入数据格式转换
train_X = np.reshape(train_X, (n_train_samples,steps,features_number))#(样本数,步长,特征数)
test_X = np.reshape(test_X, (n_test_samples,steps,features_number))
#LSTM网络搭建
model=Sequential()
model.add(LSTM(input_shape=(steps,features_number)))
model.add(LSTM(100,dropout=0.2, recurrent_dropout=0.2,Activation='relu',return_sequence=False)
model.add(Dense(14, activation='softmax')
model.compile(loss='categorical_crossentropy',
optimizer=keras.optimizers.Adam(),
metrics=['accuracy'])
print(model.summary())
#Keras设置学习率动态减少
from keras.callbacks import ReduceLROnPlateau
reduce_lr = ReduceLROnPlateau(monitor='val_loss', patience=10, mode='auto')#(监测目标='val_loss',patience=10调整频率每10个epoch看下目标loss)
model.fit(train_X, train_y, batch_size=32, epochs=500,validation_split=0.1,callbacks=[reduce_lr])
score = model.evaluate(test_X, test_y,batch_size=128, verbose=1)
if __name__ == '__main__':
main()
-----------------------------------------------------
##注意3Keras设置学习率动态减少,还有另外一种方式,下面附上代码:
import keras.backend as K
from keras.callbacks import LearningRateScheduler
def scheduler(epoch):# 每隔100个epoch,学习率减小为原来的1/10
if epoch % 100 == 0 and epoch != 0:
lr = K.get_value(model.optimizer.lr)
K.set_value(model.optimizer.lr, lr * 0.1)
print("lr changed to {}".format(lr * 0.1))
return K.get_value(model.optimizer.lr)
reduce_lr = LearningRateScheduler(scheduler)
model.fit(train_x, train_y, batch_size=32, epochs=5, callbacks=[reduce_lr])
《AI工匠BOOK》持续更新AI算法与最新应用,如果您感兴趣,欢迎关注AI工匠(AI算法与最新应用前沿研究)。