基于深度学习的新闻摘要⽣成算法实现与详解(Encoder-
Decoder框架模型)
⽬录
摘要:
摘要是⽂本的主要内容和核⼼思想的最⼩化表达,从海量⽂本数据中快速寻有价值的信息具有重要意义。利⽤深度神经⽹络Encoder-Decoder基本框架,通过引⼊注意⼒模型,本次将尝试实现应⽤LSTM+attention算法⾃动⽣成新闻摘要。⾸选利⽤LSTM神经⽹络编码出中间语义特征,最后利⽤注意⼒模型与LSTM神经⽹络解码出中间语义特征,最终实现⾃动⽣成新闻摘要。本次实现算法模型采⽤keras神经⽹络编程框架,数据集为英⽂数据,由于数据量稍微有点⼤,这次只运⾏个demo结果。
⽂本摘要⽣成概述:
⽬前主流的⽂本摘要⾃动⽣成有两种⽅式,⼀种是抽取式(extractive),另⼀种是⽣成式 (abstractive)。
抽取式顾名思义,就是按照⼀定的权重,从原⽂中寻跟中⼼思想最接近的⼀条或⼏条句⼦。⽽⽣成式则是计算机通读原⽂后,在理解整篇⽂章意思的基础上,按⾃⼰的话⽣成流畅的翻译。
抽取式摘要是⼀种⽐较成熟的⽅案,其中Text rank排序算法以其简洁、⾼效的特点被⼯业界⼴泛运⽤。⼤体思想是先去除⽂章中的⼀些停⽤词,之后对句⼦的相似度进⾏度量,计算每⼀句相对另⼀句的相似度得分,迭代传播,直到误差⼩于0.0001。再对上述得到的关键语句进⾏排序,便能得到想要的摘要。抽取式摘要主要考虑单词词频,并没有过多的语义信息,像“猪⼋戒”,“孙悟空”这样的词汇都会被独⽴对待,⽆法建⽴⽂本段落中的完整语义信息。
抽取式的摘要⽬前已经⽐较成熟,但是抽取质量及内容流畅度均差强⼈意。伴随着深度学习的研究,⽣成式摘要的质量和流畅度都有很⼤的提升,但⽬前也受到原⽂本长度过长、抽取内容不佳等的限制。
⽣成式⽂本摘要主要依靠深度神经⽹络结构实现,2014年由Google Brain团队提出的Sequence-to-Sequence序列(Sequence-to-Sequence⼜称为编、解码器(Encoder、Decoder)架构),开启了NLP中端到端⽹络的⽕热研究。因此,便采⽤次⽅法进⾏摘要的⾃动⽣成。
Encoder-Decoder模式思想:
Encoder-Decoder架构是针对序列预测问题组织循环神经⽹络的⼀种⽅式,它具有可变数⽬的输⼊、输出,或是输⼊和输出。该架构涉及两个组件:⼀个编码器和⼀个解码器:
编码器:编码器读取整个输⼊序列,并将其编码为⼀种中间表⽰,通常是⼀个被称为上下⽂向量的定长向量。对应本⽂所⽰的⽣成摘要来说即是Encoder负责把原⽂编码为⼀个向量C;
解码器:解码器从编码器读取编码输⼊序列,并⽣成输出序列。对应本⽂所⽰的⽣成摘要来说:Decoder负责从这个向量C中提取信息,获取语义,⽣成⽂本摘要。
我看了不少博客及源码解析,个⼈认为Encoder-Decoder模式,在代码实现及问题解决上我感觉类似于M个输⼊时间步长去预测输出N 个时间步长(many-to-many)的序列预测问题,只是我们采⽤Encoder-Decoder模式解决⽂本到⽂本的输出或者图像到⽂本的输出,其输出可能不是定长。即是输⼊输出⽂本长度可能在变,例如我们输⼊⼀段很长(长短不⼀)的⽂本,⾃动⽣成很短(长短不⼀)的摘要。在代码实现上,采⽤传统的LSTM⽅法很难实现这种⽅式。因为,LSTM预测输出为预先定义
好的固定长度。所以我认为采⽤编码和解码其实就是通过实现多个神经⽹络层之间的权值参数的共享,进⾏输出变长序列(标签)。我认为这种思想和迁移学习冻结神经⽹络层有点像?额也不确定?
数据集描述:
本数据集为⽹上的英⽂⽂章及摘要数据集(类似新闻,但是不是那种简报的形式,所以输⼊较长)。共有6335条样本。其中
max_input_seq_length: 500
max_target_seq_length: 50
模型构建与代码描述(LSTM+Attention)
代码结构:
模型结构图:
核⼼代码(带注释):
def encoder_decoder(data):
print('Encoder_')
"""# 定义训练编码器"""
encoder_inputs = Input(shape=en_shape)#定义输⼊,n_input表⽰特征这⼀维(维的⼤⼩即特征的数⽬)
encoder_LSTM = LSTM(hidden_units,dropout_U=0.2,dropout_W=0.2,return_sequences=True,return_state=True)#定义编码器的,hidden_units即神经元单元数 encoder_LSTM_rev=LSTM(hidden_units,return_state=True,return_sequences=True,dropout_U=0.05,dropout_W=0.05,go_backwards=True)#反向LSTM,定义
encoder_outputs, state_h, state_c = encoder_LSTM(encoder_inputs)# 取出正向LSTM输⼊⽣成的隐藏状态和细胞状态,作为解码器的隐藏状态和细胞状态的初始 encoder_outputsR, state_hR, state_cR = encoder_LSTM_rev(encoder_inputs)# 取出反向LSTM输⼊⽣成的隐藏状态和细胞状态,
作为解码器的隐藏状态和细胞状
state_hfinal=Add()([state_h,state_hR])
state_cfinal=Add()([state_c,state_cR])
encoder_outputs_final = Add()([encoder_outputs,encoder_outputsR])#综合为BiLSTM输出
encoder_states = [state_hfinal,state_cfinal]#BiLSTM取出反向LSTM输⼊⽣成的隐藏状态和细胞状态
"""定义解码器"""
decoder_inputs = Input(shape=(None,de_shape[1]))#解码器输⼊,n_output:输出响应序列的特征维的⼤⼩。
decoder_LSTM = LSTM(hidden_units,return_sequences=True,dropout_U=0.2,dropout_W=0.2,return_state=True)##因解码器⽤编码器的隐藏状态和细胞状态, decoder_outputs, _, _ = decoder_LSTM(decoder_inputs,initial_state=encoder_states)# # 这个解码层在后⾯推断中会被共享!!
#注意⼒机制
attention = TimeDistributed(Dense(1, activation = 'tanh'))(encoder_outputs_final)#编码输出作为输⼊
attention = Flatten()(attention)
attention = Multiply()([decoder_outputs, attention])#点乘注意⼒,decoder_outputs输出与attention点乘
attention = Activation('softmax')(attention)
attention = Permute([2, 1])(attention)
decoder_dense = Dense(de_shape[1],activation='softmax')# 这个full层在后⾯推断中会被共享
decoder_outputs = decoder_dense(attention)#具有注意⼒机制的特征作为输⼊,进⾏输出,
model= Model(inputs=[encoder_inputs,decoder_inputs], outputs=decoder_outputs)# 定义模型。得到以输⼊序列和⽬标序列作为输⼊,以⽬标序列的移位为输出的 print(model.summary())
rmsprop = RMSprop(lr=learning_rate,clipnorm=clip_norm)
modelpile(loss='categorical_crossentropy',optimizer=rmsprop,metrics=['accuracy'])
x_train,x_test,y_train,y_test=tts(data["article"],data["summaries"],test_size=0.20)
history= model.fit(x=[x_train,y_train],
y=y_train,
validation框架batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=([x_test,y_test], y_test))
print(model.summary())
#定义推断解码器,由于循环⽹络的性质,由输⼊状态(前)推理出输出状态(后)
encoder_model_inf = Model(encoder_inputs,encoder_states)
decoder_state_input_H = Input(shape=(en_shape[0],))
decoder_state_input_C = Input(shape=(en_shape[0],))
decoder_state_inputs = [decoder_state_input_H, decoder_state_input_C]
decoder_outputs, decoder_state_h, decoder_state_c = decoder_LSTM(decoder_inputs,
initial_state=decoder_state_inputs)
decoder_states = [decoder_state_h, decoder_state_c]
decoder_outputs = decoder_dense(decoder_outputs)
decoder_model_inf= Model([decoder_inputs]+decoder_state_inputs,
[decoder_outputs]+decoder_states)
scores = model.evaluate([x_test,y_test],y_test, verbose=1)
return model,encoder_model_inf,decoder_model_inf,history
模型训练LOSS函数图像为:
虽然曲线还⾏,但是输出了⼀下,⽣成的摘要并不是很好,所以不在展⽰。可能是我们的⽂本太长,数据集不⾏。
总结:
此次算是初探了Encoder-Decoder架构进⾏实现⽂本摘要的⾃动⽣成。但⽂本摘要⾃动⽣成依然还有很多难题,⽐如如果段落太长,那么机器对段落的理解时间就要很长,⽽过长的时间会导致机器对段落信息的记忆的损失。因此,训练出的模型其结果并不怎么好。因此,我打算下⼀步⼀些好的语料进⾏测试,以补齐结果展⽰。接着,试下中⽂的摘要⽣成。总的来说,⽂本摘要⾃动⽣成是个⾮常具有前景但也⾮常具有挑战性的技术。
参考⽂献:
Bahdanau, Dzmitry, Kyunghyun Cho, and Yoshua Bengio. Neural machine translation by jointly learning to align and translate
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论