深度学习之Encoder-Decoder架构

标签:#Encoder-Decoder##RNN##Seq2Seq##深度学习# 时间:2019/03/19 11:19:04 作者:小木

[TOC]

一、背景简介

深度学习中Sequence to Sequence (Seq2Seq) 模型的目标是将一个序列转换成另一个序列。包括机器翻译(machine translate)、会话识别(speech recognition)和时间序列预测(time series forcasting)等任务都可以理解成是Seq2Seq任务。RNN(Recurrent Neural Networks)是深度学习中最基本的序列模型。

Seq2Seq最基本的特点是输入数据和输出数据的长度并不是固定的,例如对于翻译来说,中文可能是“很 高兴 见 到 你”,而英文是“Nice to meet you”,这种情况就是输入和输出的长度不一样。同时,换一个例句之后,其输入和输出的长度也会变化。因此,一般的深度学习网络是无法处理这个问题的。

但是,基础RNN模型(以及相关的变种模型如GRU神经网络LSTM神经网络)虽然可以处理序列数据,然而就精度而言并不是很好(论文的对比试验结论)。为此,在2014年有很多研究者在几乎同一时间都提出了Encoder-Decoder的深度学习架构来处理Seq2Seq的问题。

Sutskever et al., Sequence to Sequence Learning with Neural Networks. NIPS. 2014

Cho et al., Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation. arXiv. 2014

Cho et al., On the Properties of Neural Machine Translation: Encoder–Decoder Approaches. arXiv. 2014

Bahdanau et al., Neural machine translation by jointly learning to align and translate. arXiv. 2014

Encoder-Decoder网络架构的一般思想是整个网络结构中使用两个网络来处理Seq2Seq任务。第一个网络将输入的Seq转换成一个固定长度的内部表示向量,第二个网络则是将该向量作为输入,用以预测输出的序列。两个网络之间的连接就是中间的一个向量。

二、问题描述

在这里,我们以Cho的论文(Sequence to Sequence Learning with Neural Networks)为例,描述一下问题。

假设我们有个原始序列:

\{x_1,\cdots,x_T\}

目标是转换成对应的序列:

\{y_1,\cdots,y_{T'}\}

注意,这里的两个序列并不一定是等长的。那么,一般我们可以构造如下形式的RNN Encoder-Decoder模型:


我们第一步先构造一个RNN,将原始序列作为输入,产生一个向量C。也就是说,我们第一步是要把原始序列转换成一个固定长度的向量,这里可以理解为一个特征抽取过程,即将原始不定长序列转换成一组固定长度的特征向量。其实,这里的结构可以是基本的RNN模型、GRU网络或者是LSTM,或者是Bi-RNN、Bi-LSTM(双向)。这个阶段就是Encoding阶段。

下一个阶段就是Decoding阶段,其目标是将特征向量C转换成目标序列\{y_1,\cdots,y_{T` }\}。这两个阶段的目标是最大化如下的条件概率:

\max_{\theta} \frac{1}{N} \sum_{n=1}^N\log p_\theta(\bold{y}_n|\bold{x}_n)

这里的\theta就是模型的参数集合,每一个(\bold{x}_n,\bold{y}_n)对都是一个训练集。模型的求解可以使用梯度下降。

三、Encoder-Decoder代码示例

假设我们要构造的Enocder-Decoder模型结构如下:

那么上述模型的代码结构如下:

vocab_size = ...
src_txt_length = ...
sum_txt_length = ...
# encoder input model
inputs = Input(shape=(src_txt_length,))
encoder1 = Embedding(vocab_size, 128)(inputs)
encoder2 = LSTM(128)(encoder1)
encoder3 = RepeatVector(sum_txt_length)(encoder2)
# decoder output model
decoder1 = LSTM(128, return_sequences=True)(encoder3)
outputs = TimeDistributed(Dense(vocab_size, activation='softmax'))(decoder1)
# tie it together
model = Model(inputs=inputs, outputs=outputs)
model.compile(loss='categorical_crossentropy', optimizer='adam')
欢迎大家关注DataLearner官方微信,接受最新的AI技术推送