使用TensorFlow调用PTB文本数据集

TensorFlow已经封装好使用PTB数据集的库函数,调用即可。以下代码为获取PTB数据集中的训练集、验证集以及测试集。新版TensorFlow中不能直接import reader,想要快速调用reader模块,可见在tensorflow中直接import reader。PTB数据集可在此下载,代码中只需data文件夹下内容。

import tensorflow as tf
import reader# 存放数据的路径
DATA_PATH = "\data"
train_data, valid_data, test_data, _ = reader.ptb_raw_data(DATA_PATH)
print(len(train_data))
print(train_data[:50])

输出结果为:

929589
[9970, 9971, 9972, 9974, 9975, 9976, 9980, 9981, 9982, 9983, 9984, 9986, 9987, 9988, 9989, 9991, 9992, 9993, 9994, 9995, 9996, 9997, 9998, 9999, 2, 9256, 1, 3, 72, 393, 33, 2133, 0, 146, 19, 6, 9207, 276, 407, 3, 2, 23, 1, 13, 141, 4, 1, 5465, 0, 3081]

注:PTB数据集中,每一句话结束的标志即为字符2

在使用PTB数据集训练RNN时,句子需要被截断,TensorFlow也提供了函数可以直接截断并且组成batch,代码如下:

# 将训练数据按5个词截断,4组为一个batch
# x为截断数据,y为x对应的序列输出,即每一个单词对应的输出是该单词后面的一个单词
x, y = reader.ptb_producer(train_data, 4, 5)
# 创建会话,读取一个batch
with tf.Session() as sess:coord = tf.train.Coordinator()threads = tf.train.start_queue_runners(sess=sess, coord=coord)x, y = sess.run([x, y])print(x)print(y)coord.request_stop()coord.join(threads)

输出结果为:

[[9970 9971 9972 9974 9975][ 332 7147  328 1452 8595][1969    0   98   89 2254][   3    3    2   14   24]]
[[9971 9972 9974 9975 9976][7147  328 1452 8595   59][   0   98   89 2254    0][   3    2   14   24  198]]

搭建基于LSTM的PTB语言模型

在TensorFlow框架中,使用两层LSTM结构搭建出PTB自然语言模型,代码如下:

import numpy as np
import tensorflow as tf
import reader# 存放数据的路径
DATA_PATH = "/Users/gaoyue/文档/Program/tensorflow_google/chapter8/simple-examples/data"
hidden_size = 200    # 隐藏层,用于记忆和储存过去状态的节点个数
num_layers = 2  # LSTM结构的层数为2层,前一层的LSTM的输出作为后一层的输入
vocab_size = 10000  # 词典大小,可以存储10000个learning_rate = 1.0  # 初始学习率
train_batch_size = 20  # 训练batch大小
train_num_step = 35  # 一个训练序列长度
num_epoch = 2
keep_prob = 0.5  # 节点保存50%
max_grad_norm = 5  # 用于控制梯度膨胀(误差对输入层的偏导趋于无穷大)# 在测试时不用限制序列长度
eval_batch_size = 1
eval_num_step = 1class PTBModel(object):   # 类要使用camelcase格式def __init__(self, is_training, batch_size, num_steps):  # 初始化属性self.batch_size = batch_sizeself.num_steps = num_steps# 定义输入层,输入层维度为batch_size * num_stepsself.input_data = tf.placeholder(tf.int32, [batch_size, num_steps])# 定义正确输出self.targets = tf.placeholder(tf.int32, [batch_size, num_steps])# 定义lstm结构lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(hidden_size)if is_training:# 使用dropoutlstm_cell = tf.nn.rnn_cell.DropoutWrapper(lstm_cell, output_keep_prob=keep_prob)cell = tf.nn.rnn_cell.MultiRNNCell([lstm_cell] * num_layers)    # 实现多层LSTM# 将lstm中的状态初始化为全0数组,BasicLSTMCell提供了zero_state来生成全0数组# batch_size给出了一个batch的大小self.initial_state = cell.zero_state(batch_size, tf.float32)# 生成单词向量,单词总数为10000,单词向量维度为hidden_size200,所以词嵌入总数embedding为embedding = tf.get_variable("embedding", [vocab_size, hidden_size])# lstm输入单词为batch_size*num_steps个单词,则输入维度为batch_size*num_steps*hidden_size# embedding_lookup为将input_data作为索引来搜索embedding中内容,若input_data为[0,0],则输出为embedding中第0个词向量inputs = tf.nn.embedding_lookup(embedding, self.input_data)# 在训练时用dropoutif is_training:inputs = tf.nn.dropout(inputs, keep_prob)# 输出层outputs = []# state为不同batch中的LSTM状态,初始状态为0state = self.initial_statewith tf.variable_scope("RNN"):for time_step in range(num_steps):if time_step > 0:# variables复用tf.get_variable_scope().reuse_variables()# 将当前输入进lstm中,inputs输入维度为batch_size*num_steps*hidden_sizecell_output, state = cell(inputs[:, time_step, :], state)# 输出队列outputs.append(cell_output)# 输出队列为[batch, hidden_size*num_steps],在改成[batch*num_steps, hidden_size]# [-1, hidden_size]中-1表示任意数量的样本output = tf.reshape(tf.concat(outputs, 1), [-1, hidden_size])# lstm的输出经过全连接层得到最后结果,最后结果的维度是10000,softmax后表明下一个单词的位置(概率大小)weight = tf.get_variable("weight", [hidden_size, vocab_size])bias = tf.get_variable("bias", [vocab_size])logits = tf.matmul(output, weight) + bias  # 预测的结果# 交叉熵损失,tensorflow中有sequence_loss_by_example来计算一个序列的交叉熵损失和# tf.reshape将正确结果转换为一维的,tf.ones建立损失权重,所有权重都为1,不同时刻不同batch的权重是一样的loss = tf.contrib.legacy_seq2seq.sequence_loss_by_example([logits], [tf.reshape(self.targets, [-1])],[tf.ones([batch_size * num_steps], dtype=tf.float32)])# 每个batch的平均损失,reduce_sum计算loss总和self.cost = tf.reduce_sum(loss)/batch_sizeself.final_state = state# 在训练时定义反向传播if not is_training:returntrainable_variables = tf.trainable_variables()# 使用clip_by_global_norm控制梯度大小,避免梯度膨胀grads, _ = tf.clip_by_global_norm(tf.gradients(self.cost, trainable_variables), max_grad_norm)# 梯度下降优化optimizer = tf.train.GradientDescentOptimizer(learning_rate)# 训练步骤,apply_gradients将计算出的梯度应用到变量上# zip将grads和trainable_variables中每一个打包成元组# a = [1,2,3], b = [4,5,6], zip(a, b): [(1, 4), (2, 5), (3, 6)]self.train_op = optimizer.apply_gradients(zip(grads, trainable_variables))# 模型训练,给出模型的复杂度
def run_epoch(session, model, data, train_op, output_log, epoch_size):# perplexity(复杂度)是用来评价一个语言模型预测一个样本是否很好的标准。复杂度越低,代表模型的预测性能越好total_costs = 0.0iters = 0state = session.run(model.initial_state)# 训练一个epochfor step in range(epoch_size):x, y = session.run(data)# cost是交叉熵损失,即下一个单词为给定单词的概率cost, state, _ = session.run([model.cost, model.final_state, train_op],{model.input_data: x, model.targets: y, model.initial_state: state})# 将所有batch、时刻的损失相加total_costs += cost# 所有epoch总输出单词数iters += model.num_stepsif output_log and step % 100 == 0:print("After %d steps, perplexity is %.3f" % (step, np.exp(total_costs / iters)))# 返回语言模型的perplexity值return np.exp(total_costs / iters)def main():# 获取数据train_data, valid_data, test_data, _ = reader.ptb_raw_data(DATA_PATH)# 计算一个epoch需要训练的次数train_data_len = len(train_data)train_epoch_size = (train_data_len - 1)valid_data_len = len(valid_data)valid_epoch_size = (valid_data_len - 1)test_data_len = len(test_data)test_epoch_size = (test_data_len - 1)# 定义初始化函数initializer = tf.random_uniform_initializer(-0.05, 0.05)# 定义语言训练模型with tf.variable_scope("language_model", reuse=None, initializer=initializer):train_model = PTBModel(True, train_batch_size, train_num_step)# 定义语言测试模型with tf.variable_scope("language_model", reuse=True, initializer=initializer):eval_model = PTBModel(False, eval_batch_size, eval_num_step)# 训练模型with tf.Session() as session:tf.global_variables_initializer().run()train_queue = reader.ptb_producer(train_data, train_model.batch_size, train_model.num_steps)eval_queue = reader.ptb_producer(valid_data, eval_model.batch_size, eval_model.num_steps)test_queue = reader.ptb_producer(test_data, eval_model.batch_size, eval_model.num_steps)coord = tf.train.Coordinator()threads = tf.train.start_queue_runners(sess=session, coord=coord)for i in range(num_epoch):print("iteration: %d" % (i + 1))run_epoch(session, train_model, train_queue, train_model.train_op, True, train_epoch_size)# 传入了tf.no_op表示不进行优化valid_perplexity = run_epoch(session, eval_model, eval_queue, tf.no_op(), False, valid_epoch_size)print("Epoch: %d Validation Perplexity: %.3f" % (i + 1, valid_perplexity))test_perplexity = run_epoch(session, eval_model, test_queue, tf.no_op(), False, test_epoch_size)print("Test Perplexity: %.3f" % test_perplexity)coord.request_stop()coord.join(threads)if __name__ == "__main__":main()

输出结果为:

iteration: 1
After 0 steps, perplexity is 9987.416
After 100 steps, perplexity is 1314.799
After 200 steps, perplexity is 996.104
.
.
.
After 32200 steps, perplexity is 169.283
After 32300 steps, perplexity is 169.194
After 32400 steps, perplexity is 169.147
.
.
.

注:perplexity值代表从perplexity个单词中选择下一个词,若 perplexity = 169,即句子中的下一个词将会在169个词中选择,通过网络优化,可以进一步降低perplexity值。

使用TensorFlow调用PTB数据集并且搭建基于LSTM的PTB语言模型相关推荐

  1. java lstm pb_在Tensorflow Serving上部署基于LSTM的文本分类模型

    一些重要的概念 Servables Servables 是客户端请求执行计算的基础对象,大小和粒度是灵活的. Servables 不会管理自己的运行周期. 典型的Servables包括: a Tens ...

  2. TF之LSTM:基于Tensorflow框架采用PTB数据集建立LSTM网络的自然语言建模

    TF之LSTM:基于Tensorflow框架采用PTB数据集建立LSTM网络的自然语言建模 目录 关于PTB数据集 代码实现 关于PTB数据集 PTB (Penn Treebank Dataset)文 ...

  3. 使用RTX3080显卡搭建基于Pycharm+Python+Cuda+cuDNN+TensorFlow的深度学习开发环境

    本文链接:https://blog.csdn.net/tjhyx2012/article/details/112955582 作为一名新手,也是出于兴趣,我通过查找有关资料,使用RTX3080显卡搭建 ...

  4. 基于TensorFlow和mnist数据集的手写数字识别系统 ,可识别电话号码,识别准确率高,有对比实验,两组模型,可讲解代码

    基于TensorFlow和mnist数据集的手写数字识别系统 ,可识别电话号码,识别准确率高,有对比实验,两组模型,可讲解代码

  5. 全网最详细的Hadoop大数据集群搭建并进行项目分析(基于完全分布式)---终结篇

    ##所有需要的资料全部已上传到百度网盘上,请自行下载## 获取镜像,https://pan.baidu.com/s/1ho4hMrvIu1V6W4wWdH8nIA,提取码:ygyg 获取Xshell, ...

  6. 全网最详细的Hadoop大数据集群搭建并进行项目分析(基于完全分布式)---第二部分

    ##所有需要的资料全部已上传到百度网盘上,请自行下载## 获取镜像,https://pan.baidu.com/s/1ho4hMrvIu1V6W4wWdH8nIA,提取码:ygyg 获取Xshell, ...

  7. 全网最详细的Hadoop大数据集群搭建并进行项目分析(基于完全分布式)-----第一部分

    ##心路历程:这是大学时期做的项目,这个项目对我印象特别的深,当时没有记录在博客上,今后会积极分享自己做项目的历程与经验,希望能帮到需要的朋友,有什么问题或者建议欢迎在评论区留言,废话不多说,咱们就开 ...

  8. NVIDIA专家实战演示,教你快速搭建基于Python的车辆信息识别系统

    主讲人 | 何琨 英伟达 量子位编辑 | 公众号 QbitAI 随着智慧城市.自动驾驶的快速落地,车辆的检测和识别应用场景非常广泛,如车牌识别.车流统计.车辆属性识别等. 近日,在英伟达x量子位发起的 ...

  9. Python实现鸢尾花数据集分类问题——基于skearn的SVM(有详细注释的)

    Python实现鸢尾花数据集分类问题--基于skearn的SVM 代码如下: 1 # !/usr/bin/env python2 # encoding: utf-83 __author__ = 'Xi ...

  10. Python实现鸢尾花数据集分类问题——基于skearn的LogisticRegression

    Python实现鸢尾花数据集分类问题--基于skearn的LogisticRegression 一. 逻辑回归 逻辑回归(Logistic Regression)是用于处理因变量为分类变量的回归问题, ...

最新文章

  1. 史上最详细 Linux 用户与用户组知识
  2. 实战教程 | 车道线检测项目实战,霍夫变换 新方法 Spatial CNN
  3. MySql修改 表名
  4. JAVA WEB新进展
  5. 四层和七层负载均衡的区别介绍--转
  6. P2647 最大收益
  7. 《JAVA与模式》之模板方法模式
  8. git-分支管理策略-合并分支时创建新的版本
  9. linux管理之磁盘信息和进程管理
  10. 有味道的耳机!男子误食AirPods 排出后仍可正常使用
  11. android aar项目_Android-我所认知的VLayout
  12. Markdown中跳转,锚点操作浅析
  13. web程序常见错误及解决方法
  14. case 日期when 范围_亚马逊运营干货:开case最全路径和各种实用链接,赶紧收藏...
  15. 国家统计局全国统计用区划代码和城乡划分代码Python爬虫样例
  16. 蓝桥杯单片机温度传感器DS18B20(基于STC15F2K60S2)
  17. for i in range()使用方法
  18. 使用 Kitten 开发一款趣味成语接龙游戏
  19. 用python的turtle画五角星
  20. CDN的加速域名、源站地址与回源host之间的关系

热门文章

  1. 用Acrobat打印小册子
  2. javaweb实现登陆,注册,修改密码,显示信息,修改个人信息功能
  3. golang——gorountine+channal
  4. 非主流照片的PS教程!
  5. struts2+quartz定时任务
  6. 快速入门STM32单片机-机械硬件篇
  7. 计算机操作与应用60,60个技巧使您成为计算机高手!
  8. 定义一个图形抽象类,完成三角形、圆形、矩形的周长和面积计算
  9. Word 悬挂缩进文本如何对齐
  10. @SpringBootTest注解分析(一)Found multiple @SpringBootConfiguration annotated classes