【NLP】Seq2Seq模型与实战(Tensoflow2.x、Keras)

一、从RNN到Seq2Seq

根据输出和输入序列不同数量rnn可以有多种不同的结构,不同结构自然就有不同的引用场合。如下图,
在这里插入图片描述

  • one to one 结构,仅仅只是简单的给一个输入得到一个输出,此处并未体现序列的特征,例如图像分类场景。
  • one to many 结构,给一个输入得到一系列输出,这种结构可用于生产图片描述的场景。
  • many to one 结构,给一系列输入得到一个输出,这种结构可用于文本情感分析,对一些列的文本输入进行分类,看是消极还是积极情感。
  • many to many 结构,给一些列输入得到一系列输出,这种结构可用于翻译或聊天对话场景,对输入的文本转换成另外一些列文本。
  • 同步 many to many 结构,它是经典的rnn结构,前一输入的状态会带到下一个状态中,而且每个输入都会对应一个输出,我们最熟悉的就是用于字符预测了,同样也可以用于视频分类,对视频的帧打标签。

1.1 Seq2Seq

在 many to many 的两种模型中,上图可以看到第四和第五种是有差异的,经典的rnn结构的输入和输出序列必须要是等长,它的应用场景也比较有限。而第四种它可以是输入和输出序列不等长,这种模型便是seq2seq模型,即Sequence to Sequence。它实现了从一个序列到另外一个序列的转换,比如google曾用seq2seq模型加attention模型来实现了翻译功能,类似的还可以实现聊天机器人对话模型。经典的rnn模型固定了输入序列和输出序列的大小,而seq2seq模型则突破了该限制。
在这里插入图片描述
其实对于seq2seq的decoder,它在训练阶段和预测阶段对rnn的输出的处理可能是不一样的,比如在训练阶段可能对rnn的输出不处理,直接用target的序列作为下时刻的输入,预测阶段会将rnn的输出当成是下一时刻的输入。

1.2 encoder-decoder结构

01、encoder

编码器的作用是把一个不定⻓的输入序列变换成一个定⻓的背景变量c,并在该背景变量中编码输入序列信息。常用的编码器是循环神经网络。
用函数f 表达循环神经网络隐藏层的变换:在这里插入图片描述
编码器通过自定义函数q将各个时间步的隐藏状态变换为背景变量:
在这里插入图片描述
获取语义向量最简单的方式就是直接将最后一个输入的隐状态作为语义向量C。也可以对最后一个隐含状态做一个变换得到语义向量,还可以将输入序列的所有隐含状态做一个变换得到语义变量。

02、decoder

decoder则负责根据语义向量生成指定的序列,这个过程也称为解码。
在输出序列的时间步t′ ,解码器将上一时间步的输出y(t′−1) 以及背景变量c作为输入,并将它们与上一时间步的隐藏状态s(t′−1) 变换为当前时 间步的隐藏状态s(t′) 。因此,我们可以用函数g表达解码器隐藏层的变换:
在这里插入图片描述
基于当前时间步的解码器隐藏状态 s(t′) 、上一时间步的输出y(t′ −1) 以及背景 变量c来计算当前时间步输出y(t′) 的概率分布。
在这里插入图片描述

最简单的方式是将encoder得到的语义变量作为初始状态输入到decoder的rnn中,得到输出序列。可以看到上一时刻的输出会作为当前时刻的输入,而且其中语义向量C只作为初始状态参与运算,后面的运算都与语义向量C无关。

1.3 模型训练

根据最大似然估计,我们可以最大化输出序列基于输入序列的条件概率:
在这里插入图片描述
并得到该输出序列的损失:
在这里插入图片描述
在模型训练中,所有输出序列损失的均值通常作为需要最小化的损失函数。

一般我们需要将解码器在上一个时间步的输出作为当前时间步的输入:

在这里插入图片描述

在训练中也可以将标签序列(训练集的真实输出序列)在上一个时间步的标签作为解码器在当前时间步的输入。这叫作强制教学(teacher forcing)。

二、 实战

实战项目参考:
1、时序数据预测,来源于google在kaggle上公开的一个项目Web Traffic Time Series Forecasting。数据量600M+。
https://github.com/JEddy92/TimeSeries_Seq2Seq
2、时序数据预测:https://github.com/Olliang/Time-Series-Forcasting
3、图像生成:https://github.com/timsainb/tensorflow2-generative-models
4、文本摘要:https://www.kaggle.com/sandeepbhogaraju/text-summarization-with-seq2seq-model/comments#728381
5、机器翻译:https://www.kaggle.com/bachrr/seq2seq-for-english-arabic-translation-in-keras/comments#741129
6、字符级别的翻译:https://github.com/ktoulgaridis/char-seq2seq-translate
7、聊天机器人:https://github.com/tensorlayer/seq2seq-chatbot

实践地6个项目如下:

# Imports Cell
from __future__ import print_function
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, LSTM, Dense
import numpy as np

2.1超参数设置

设置batch大小、训练重复次数、编码向量维度、数据路径等

# Basic Parameters
batch_size = 64  # Batch size for training.
epochs = 10  # Number of epochs to train for.
latent_dim = 256  # Latent dimensionality of the encoding space.
num_samples = 10000  # Number of samples to train on.
# Path to the data txt file on disk.
data_path = './ell.txt'

2.2数据的预处理

从txt文件中读取数据;
input_texts存储英文输入;
target_texts存储翻译后成希腊语的单词;
input_characters表示英文中无重复的字符;
target_characters表示希腊语中对应的无重复字符。

解码的时候需要起始字符和结束字符,这里分别用制表符’\t’和回车符’\n’来表示

# Vectorize the data.
input_texts = []
target_texts = []
input_characters = set()
target_characters = set()
with open(data_path, 'r', encoding='utf-8') as f:
    lines = f.read().split('\n')
for line in lines[: min(num_samples, len(lines) - 1)]:
    input_text, target_text, _ = line.split('\t')
    # We use "tab" as the "start sequence" character
    # for the targets, and "\n" as "end sequence" character.
    target_text = '\t' + target_text + '\n'
    input_texts.append(input_text)
    target_texts.append(target_text)
    for char in input_text:
        if char not in input_characters:
            input_characters.add(char)
    for
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值