实现简单RNN与LSTM网络

  • 前言
  • 1. 导入相应的库
  • 2. 加载与构建数据集
    • 2.1 加载数据集
    • 2.2 构建词表
    • 2.3 处理数据
  • 3. 构建简单的RNN模型
    • 3.1 单向RNN模型
    • 3.2 双向RNN模型
  • 4. 构建LSTM模型
    • 4.1 单向LSTM模型
    • 4.1 双向LSTM模型
  • 5. 模型编译与训练

前言

上篇博文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 = 512model = 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_dimkeras.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_dimkeras.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)

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

  1. [Python人工智能] 十二.循环神经网络RNN和LSTM原理详解及TensorFlow编写RNN分类案例

    从本专栏开始,作者正式开始研究Python深度学习.神经网络及人工智能相关知识.前一篇讲解了TensorFlow如何保存变量和神经网络参数,通过Saver保存神经网络,再通过Restore调用训练好的 ...

  2. Android开发本地及网络Mp3音乐播放器(十二)创建NetMusicListAdapter、SearchResult显示网络音乐列表

    转载请注明出处:http://blog.csdn.net/iwanghang/article/details/51290181 觉得博文有用,请点赞,请留言,请关注,谢谢!~ 实现功能: 实现NetM ...

  3. [深度学习]理解RNN, GRU, LSTM 网络

    Recurrent Neural Networks(RNN) 人类并不是每时每刻都从一片空白的大脑开始他们的思考.在你阅读这篇文章时候,你都是基于自己已经拥有的对先前所见词的理解来推断当前词的真实含义 ...

  4. 使用RNNs进行机器翻译——介绍RNN和LSTM网络及其应用

    https://www.toutiao.com/a6667024196603740685/ 循环神经网络 RNNs是一种特殊类型的神经网络,具有允许信息在网络中的不同步骤中持续存在的循环. 循环神经网 ...

  5. salesforce 零基础学习(四十二)简单文件上传下载

    项目中,常常需要用到文件的上传和下载,上传和下载功能实际上是对Document对象进行insert和查询操作.本篇演示简单的文件上传和下载,理论上文件上传后应该将ID作为操作表的字段存储,这里只演示文 ...

  6. (十二) 简单使用 Dockerfile 保留字指令,尝试自定义centos镜像

         需求 自己使用Dockerfile构建一个自己自定义的centos 镜像.自定义的centos镜像中中可以使用 vim 命令 (精简版的centos镜像中是没有vim的). 一.查看dock ...

  7. Scrapy笔记十二:简单爬取苏宁书籍网站

    文章目录 简单爬取苏宁书籍网站 参考网址: 整个爬取过程思路: 未解决的问题: 代码如下: 简单爬取苏宁书籍网站 参考网址: 网址1:https://book.suning.com/ 网址2:http ...

  8. 设计界面的十二条简单的原则

    误区:除了游戏等少数需要炫耀外观的软件之外,大多数软件的界面设计其实并不等同于通常意义上的平面设计. 应当说,要描述和展现用户界面设计方案,最直观的方法就是把界面的样子画出来(类似 Visio里的用户 ...

  9. (十二)简单说一说drop、delete与truncate的区别

    SQL中的drop.delete.truncate都表示删除,但是三者有一些差别: Delete用来删除表的全部或者一部分数据行,执行delete之后,(操作会记录在日志中)用户需要提交(commmi ...

最新文章

  1. C语言拾零(to be continued)
  2. hdu3697(贪心+暴力)
  3. Linux的secureCRT设置字体大小
  4. 关于 SAP Spartacus CSR fallback 之后,是否仍然会继续进行 SSR 的处理
  5. SpringSocial业务系统与社交网站的绑定与解绑
  6. Markdown语法(一)标题段落分割线
  7. django迁移数据库错误
  8. 用vue实时监听多个用户扫描二维码
  9. 思维导图——线性代数知识点总结
  10. Python贝叶斯决策面计算及仿真
  11. 全国火车高铁站及车次数据爬虫(内含100W+数据,免费领取!)
  12. mysql odbc 免安装_MySQL免安装版配置
  13. [水]关于web地图
  14. 一个简单的税利计算器(网页版)
  15. Neo4j 查询语法入门
  16. SpringBoot使用Freemarker导出word模板(OpenXML)
  17. python-web-下载所有xkcd漫画
  18. 微信支付APP支付服务商模式
  19. 源程序管理软件与项目管理软件
  20. AI神经网络流水线MLOps machine learning pipline 华为和深信服 等公司的落地 QCon 大会2022

热门文章

  1. android企业手机安全软件开发,基于Android的手机安全管理软件的设计与实现毕业论文.doc...
  2. Docker 容器遇到的乱码问题
  3. Log4j、Log4j 2、JUL、JCL 、SFL4J 、Logback 与 Lombok 的使用
  4. cpu时间片 linux,能讲一下在Linux系统中时间片是怎么分配的还有优先级的具体算法是...
  5. allure-pytest 测试报告分享给大家
  6. Java的反射(二)
  7. 数据结构(六) 排序
  8. php输出echo、print、print_r、printf、sprintf、var_dump比较
  9. [转自李战博客]悟透JavaScript
  10. Javascript设计模式(四)-- 建造者模式