TensorFlow2.0(十二)--实现简单RNN与LSTM网络

•TensorFlow2.0 专栏收录该内容
12 篇文章 7 订阅

前言

上篇博文TensorFlow2.0(十一)–理解LSTM网络我们详细解释了LSTM的工作原理与结构,这篇博文我们通过IMDB数据集来实现简单的RNN与LSTM网络对文本进行分类。

1. 导入相应的库

首先我们需要导入相应的python库

# matplotlib 用于绘图
import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib inline
# 处理数据的库
import numpy as np
import sklearn
import pandas as pd
# 系统库
import os
import sys
import time
# TensorFlow的库
import tensorflow as tf
from tensorflow import keras

2. 加载与构建数据集

2.1 加载数据集

本次加载的数据集为IMDB,是一个电影评分数据集,标签有两种,positive和negative

# IMDB:一个电影评分数据集,有两类,positive与negative
imdb = keras.datasets.imdb
vocab_size = 10000
index_from = 3
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(
                                                       num_words = vocab_size,  # 数据中词表的个数,根据词出现的频次,前10000个会被保留,其余当做特殊字符处理
                                                       index_from = index_from) # 词表的下标从3开始计算

我们来看一下数据是什么样的:

print(train_data[0],train_labels[0])
print(train_data.shape, train_labels.shape)   # 每个训练样本都是变长的
print(len(train_data[0]), len(train_data[1])) # 比如第一个样本的长度是218,第二个样本的长度就是189
print(test_data.shape, test_labels.shape) 

在这里插入图片描述

2.2 构建词表

首先我们要获取词表:

word_index = imdb.get_word_index() # 获取词表
print(len(word_index)) # 打印词表长度
print(list(word_index.items())[:50])  # 打印词表的前50个 key:value形式

输出结果为:
在这里插入图片描述
可以看到我们的词表是字典形式的,key为单词,value是对应的ID。下面我们生成id到word的映射:

"""
更改词表ID
因为我们读取词表的时候是从下标为3的时候开始计算的,所以此时要加3
使词表坐标偏移的目的是为了增加一些特殊字符
"""
word_index = {k:(v+3) for k, v in word_index.items()} 

word_index['<PAD>'] = 0      # padding时用来填充的字符
word_index['<START>'] = 1    # 每个句子开始之前的字符
word_index['<UNK>'] = 2      # 无法识别的字符
word_index['<END>'] = 3      # 每个句子结束时的字符

# id->word的索引
reverse_word_index = dict(
    [(value, key) for key, value in word_index.items()])

def decode_review(text_ids):
    return ' '.join(
        [reverse_word_index.get(word_id, "<UNK>") for word_id in text_ids]) # 没有找到的id默认用<UNK>代替
# 打印train_data[0]中ID对应的语句
decode_review(train_data[0])

我们来看一下转化之后的样本是怎么样的:
在这里插入图片描述

2.3 处理数据

因为我们的样本是不等长的,每个评论的长度都不一样,所以我们需要对数据进行处理,规定一个样本长度,对于长度不足的样本进行补齐,对于长度超出的样本进行截断。

max_length = 500 # 句子的长度,长度低于500的句子会被padding补齐,长度低于500的句子会被截断

"""
利用keras.preprocessing.sequence.pad_sequences对训练集与测试集数据进行补齐和截断
"""
# 处理训练集数据
train_data = keras.preprocessing.sequence.pad_sequences(
    train_data,                   # 要处理的数据
    value = word_index['<PAD>'],  # 要填充的值
    padding = 'post',             # padding的顺序:post指将padding放到句子的后面, pre指将padding放到句子的前面
    maxlen = max_length)          # 最大的长度

# 处理测试集数据
test_data = keras.preprocessing.sequence.pad_sequences(
    test_data,                    # 要处理的数据
    value = word_index['<PAD>'],  # 要填充的值
    padding = 'post',             # padding的顺序:post指将padding放到句子的后面, pre指将padding放到句子的前面
    maxlen = max_length)          # 最大的长度

print(train_data[0])

输出结果为:
在这里插入图片描述

3. 构建简单的RNN模型

3.1 单向RNN模型

首先我们构建一个单向的RNN模型:

embedding_dim = 16  # 每个word embedding成一个长度为16的向量
batch_size = 512    # 每个batch的长度

"""
单层单向的RNN
"""
model = keras.models.Sequential([
    """
    embedding层的作用
    1. 定义一个矩阵 matrix: [vocab_size, embedding_dim] ([10000, 16])
    2. 对于每一个样本[1,2,3,4..],将其变为 max_length * embedding_dim维度的数据,即每一个词都变为长度为16的向量
    3. 最后的数据为三维矩阵:batch_size * max_length * embedding_dim
    """
    keras.layers.Embedding(vocab_size,                  # 词表的长度
                           embedding_dim,               # embedding的长度
                           input_length = max_length),  # 输入的长度
    # units:输出空间维度
    # return_sequences: 布尔值。是返回输出序列中的最后一个输出,还是全部序列。
    keras.layers.SimpleRNN(units = 64, return_sequences = False),
    # 全连接层
    keras.layers.Dense(64, activation = 'relu'),
    keras.layers.Dense(1, activation='sigmoid'),
])
model.summary()

我们来看一下单向SimpleRNN的结构:
在这里插入图片描述

3.2 双向RNN模型

如果单向的RNN模型效果不好的话,可以将单向的RNN模型变为双向的,利用keras.layers.Bidirectional()模块即可:

embedding_dim = 16
batch_size = 512

model = keras.models.Sequential([
    # 1. define matrix: [vocab_size, embedding_dim]
    # 2. [1,2,3,4..], max_length * embedding_dim
    # 3. batch_size * max_length * embedding_dim
    keras.layers.Embedding(vocab_size, embedding_dim,
                           input_length = max_length),
    keras.layers.Bidirectional(
        keras.layers.SimpleRNN(
            units = 64, return_sequences = True)),
    keras.layers.Dense(64, activation = 'relu'),
    keras.layers.Dense(1, activation='sigmoid'),
])

model.summary()
model.compile(optimizer = 'adam',
              loss = 'binary_crossentropy',
              metrics = ['accuracy'])

4. 构建LSTM模型

4.1 单向LSTM模型

与构建RNN一样,构建LSTM的步骤几乎一致,只需要将keras.layers.SimpleRNN()层更改为keras.layers.LSTM()即可:

embedding_dim = 16  # 每个word embedding成一个长度为16的向量
batch_size = 512    # 每个batch的长度

"""
单层单向的LSTM
"""
model = keras.models.Sequential([
    """
    embedding层的作用
    1. 定义一个矩阵 matrix: [vocab_size, embedding_dim] ([10000, 16])
    2. 对于每一个样本[1,2,3,4..],将其变为 max_length * embedding_dim维度的数据,即每一个词都变为长度为16的向量
    3. 最后的数据为三维矩阵:batch_size * max_length * embedding_dim
    """
    keras.layers.Embedding(vocab_size,                  # 词表的长度
                           embedding_dim,               # embedding的长度
                           input_length = max_length),  # 输入的长度
    # units:输出空间维度
    # return_sequences: 布尔值。是返回输出序列中的最后一个输出,还是全部序列。
    keras.layers.LSTM(units = 64, return_sequences = False),
    keras.layers.Dense(64, activation = 'relu'),
    keras.layers.Dense(1, activation='sigmoid'),
])

model.summary()
model.compile(optimizer = 'adam',
                         loss = 'binary_crossentropy',
                         metrics = ['accuracy'])
4.1 双向LSTM模型

双向LSTM模型与双向RNN模型几乎一致,只需要将keras.layers.SimpleRNN()层更改为keras.layers.LSTM()即可:

embedding_dim = 16
batch_size = 512
"""
双向双层的LSTM
"""
model = keras.models.Sequential([
    # 1. define matrix: [vocab_size, embedding_dim]
    # 2. [1,2,3,4..], max_length * embedding_dim
    # 3. batch_size * max_length * embedding_dim
    keras.layers.Embedding(vocab_size, embedding_dim,
                           input_length = max_length),
    keras.layers.Bidirectional(
        keras.layers.LSTM(
            units = 64, return_sequences = True)),
    keras.layers.Dense(64, activation = 'relu'),
    keras.layers.Dense(1, activation='sigmoid'),
])

model.summary()
model.compile(optimizer = 'adam',
              loss = 'binary_crossentropy',
              metrics = ['accuracy'])

5. 模型编译与训练

对于构建好的model,我们就可以进行编译和训练了:

single_rnn_model.compile(optimizer = 'adam',
                         loss = 'binary_crossentropy',
                         metrics = ['accuracy'])
history_single_rnn = single_rnn_model.fit(
    train_data, train_labels,
    epochs = 30,
    batch_size = batch_size,
    validation_split = 0.2)
  • 3
    点赞
  • 0
    评论
  • 19
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

打赏
文章很值,打赏犒劳作者一下
相关推荐
<ul style="color:rgba(0,0,0,.560784);font-size:14px;background-color:#FFFFFF;"> <li> <span>Tensorflow2.0介绍:</span> </li> </ul> <p style="color:rgba(0,0,0,.560784);font-size:14px;background-color:#FFFFFF;"> tensorflow是GOOGLE在2015年底发布的一款深度学习框架,也是目前全世界用得最多,发展最好的深度学习框架。2019年3月8日,GOOGLE发布最新tensorflow2版本。新版本的tensorflow有很多新特征,更快更容易使用更人性化。但是老版的tensorflow程序在新版本中几乎都无法继续使用,所以我们有必要学习新版tensorflow2的新用法。 </p> <ul style="color:rgba(0,0,0,.560784);font-size:14px;background-color:#FFFFFF;"> <li> <span>课程介绍:</span> </li> </ul> <p style="color:rgba(0,0,0,.560784);font-size:14px;background-color:#FFFFFF;"> 我们的这门课程适合小白学习,也适合有基础的同学学习。课程会从0开始学习,从python环境安装,python入门,numpy,pandas,matplotlib使用,深度学习基础,一直讲到tensorflow基础,进阶,项目实战。不管你是0基础小白,想进入AI行业,还是有一定基础,想学习最新的tensorflow2的使用,都适合我们这门课程。 </p> <ul style="color:rgba(0,0,0,.560784);font-size:14px;background-color:#FFFFFF;"> <li> <span>讲师介绍:</span> </li> </ul> <p style="color:rgba(0,0,0,.560784);font-size:14px;background-color:#FFFFFF;"> 覃秉丰,物理系毕业转AI行业,想转行同学可以找我聊聊。机器学习、深度学习神经网络领域多年研究开发授课经验,精通算法原理与编程实践;曾完成过多项图像识别、目标识别、语音识别等企业项目,一线实战经验丰富;长期为多家包括世界五百强在内的大型企业总部做人工智能技术内训服务(中国移动、中国银行,华夏银行,中国太平洋,国家电网、中海油等)。上课特点:公式尽量一个一个符号推,代码尽量一行一行讲,希望所有人都能学有所得。 </p>
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页

打赏

爱吃骨头的猫、

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值