一步一步带你用TensorFlow玩转LSTM

更多深度文章,请关注:https://yq.aliyun.com/cloud



LSTM,全称为长短期记忆网络(Long Short Term Memory networks),是一种特殊的RNN,能够学习到长期依赖关系。LSTM由Hochreiter & Schmidhuber (1997)提出,许多研究者进行了一系列的工作对其改进并使之发扬光大。

了解LSTM请前往——LSTM的“前生今世”

LSTM在解决许多问题上效果非常好,现在被广泛使用。它们主要用于处理序列数据。这个博客的主要目的是让读者了解在TensorFlow中,如何实现基本的LSTM网络并掌握实现的细节。为了实现这一目标,我们把MNIST作为我们的数据集。

MNIST数据集:

MNIST数据集由手写数字及其相应标签的图像组成。我们可以借助TensorFlow的内置功能下载和读取数据:

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)

数据分为三部分:

训练数据(mnist.train)-55000个图像的训练数据。

测试数据(mnist.test)-10000个图像的测试数据。

验证数据(mnist.validation)-5000个图像的验证数据。

数据形状:

接下来我们介绍一下MNIST数据集的训练数据的形状。

训练集包括55000个28×28像素的图像。这些784(28X28)像素值以单个维度向量的形式被平坦化。所有这样的55000个像素向量(每个图像一个)的集合被存储为numpy阵列的形式(55000,784),并被称为mnist.train.images

这些55000个训练图像中的每一个与表示该图像属于的类的标签相关联。一共有10个这样的类(0,1,2 ... 9)。标签以一种热编码形式的表示。因此标签被存储为numpy形状阵列的形式(55000,10)被称为mnist.train.labels

为什么是MNIST?

LSTM通常用于解决复杂序列的相关问题,如NLP领域的实验:语言建模、字嵌入,编码器等。MNIST给了我们解决这类问题的机会。这里的输入数据只是一组像素值。我们可以轻松地格式化这些值,并集中应用到问题细节上。

实现

在我们没有展示代码之前,让我们先来看一下这个实验的实现方式。这会使编码部分更加容易理解。

A vanilla RNN

经常性的神经网络,通过时间展开,一般可以被图像化视为:

1.Xt是指时间步长t的输入。

2.St是指时间步长t处的隐藏状态。它可以被可视化为网络的“内存”。

3.Ot指的是输出在时间步长t。

4.U,V和W是所有时间步长共享的参数。该参数共享的意义在于,我们的模型在不同输入的时间步长可以执行相同的任务。

我们通过展开RNN想要介绍的是,在每个时间步骤中,网络可以被视为前馈网络,同时要考虑到前一个时间步长的输出(由时间步长之间的连接表示)。

两个警告:

我们的实现将取决于两个主要概念。

1.TensorFlow中LSTM细胞的解释。

2.将输入格式化,然后将其输入到TensorFlow RNNs中。

TensorFlow中LSTM细胞的解释:

基本的LSTM细胞单元在TensorFlow中声明为:

tf.contrib.rnn.BasicLSTMCell(num_units)

这里的num_units指的是LSTM单元中的单位数。

num_units可以解释为前馈神经网络隐藏层的类比。前馈神经网络隐层中的节点num_units数目等于LSTM网络每个时间步长的LSTM单元的数量。以下图片应该可以帮助你理解:

每个num_unitsLSTM网络都可以将它看作是一个标准的LSTM单元。

上图是从文章开头的博客中得到,它精准的描述了LSTM的概念。

将输入格式化,然后将其输入到TensorFlow RNNs中

张量流(tensorflow)中最简单的RNN形式是在static_rnn中定义:

tf.static_rnn(cell,inputs)

当然还有其他形式的定义方法,这里我们只需要用到最简单的定义方法。

inputs参数是为了接受形状张量列表[batch_size,input_size]。该列表的长度是网络展开的时间步长数,即该列表的每个元素对应于我们展开网络的相应时间步长的输入。

对于我们的MNIST图像的情况,我们有大小为28X28的图像。它们可以被推断为具有28行28像素的图像。我们将通过28个时间步骤展开我们的网络,使得在每个时间步长,我们可以输入一行28像素(input_size),从而通过28个时间步长输入完整的图像。如果我们提供batch_size图像的数量,每个时间步长将提供相应的batch_size图像行。下图应该可以解释上述描述:

生成的输出static_rnn是形状的张量列表[batch_size,n_hidden]。列表的长度是网络展开的时间步长数,即每个时间步长的一个输出张量。在这个实现中,我们将只关注最后时间的输出,当图像的所有行被提供给RNN时,即在最后时间步长将产生预测。

我们已经准备好编写代码了。如果一旦上述概念很清楚,编写部分很简单。

Code

首先,可以导入必需的依赖项、数据集并声明一些常量。我们将使用batch_size=128num_units=128

import tensorflow as tf
from tensorflow.contrib import rnn
#import mnist dataset
from tensorflow.examples.tutorials.mnist import input_data
mnist=input_data.read_data_sets("/tmp/data/",one_hot=True)
#define constants
#unrolled through 28 time steps
time_steps=28
#hidden LSTM units
num_units=128
#rows of 28 pixels
n_input=28
#learning rate for adam
learning_rate=0.001
#mnist is meant to be classified in 10 classes(0-9).
n_classes=10
#size of batch
batch_size=128

现在让我们来声明将其用于形状的输出转换占位符和权重及偏置变量[batch_size,num_units][batch_size,n_classes]

#weights and biases of appropriate shape to accomplish above task
out_weights=tf.Variable(tf.random_normal([num_units,n_classes]))
out_bias=tf.Variable(tf.random_normal([n_classes]))
#defining placeholders
#input image placeholder
x=tf.placeholder("float",[None,time_steps,n_input])
#input label placeholder
y=tf.placeholder("float",[None,n_classes])

我们正在接收形状的输入[batch_size,time_steps,n_input],我们需要将其转换成长度形状[batch_size,n_inputs]的张量列表,time_steps以便它可以被馈送到static_rnn

#processing the input tensor from [batch_size,n_steps,n_input] to "time_steps" number of [batch_size,n_input] tensors
input=tf.unstack(x ,time_steps,1)

现在我们准备定义我们的网络。我们将使用一层BasicLSTMCell,使我们的static_rnn网络脱颖而出。

#defining the network
lstm_layer=rnn.BasicLSTMCell(n_hidden,forget_bias=1)
outputs,_=rnn.static_rnn(lstm_layer,input,dtype="float32")

由于我们要的是预测的结果,所以我们只考虑最后一步的输入。

#converting last output of dimension [batch_size,num_units] to [batch_size,n_classes] by out_weight multiplication
prediction=tf.matmul(outputs[-1],out_weights)+out_bias

定义损失、优化器和准确性。

#loss_function
loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction,labels=y))
#optimization
opt=tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)
#model evaluation
correct_prediction=tf.equal(tf.argmax(prediction,1),tf.argmax(y,1))
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

现在我们已经定义了图,我们可以运行它。

#initialize variables
init=tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)
    iter=1
    while iter<800:
      batch_x,batch_y=mnist.train.next_batch(batch_size=batch_size)
        batch_x=batch_x.reshape((batch_size,time_steps,n_input))
        sess.run(opt, feed_dict={x: batch_x, y: batch_y})
       if iter %10==0:
            acc=sess.run(accuracy,feed_dict={x:batch_x,y:batch_y})
            los=sess.run(loss,feed_dict={x:batch_x,y:batch_y})
            print("For iter ",iter)
            print("Accuracy ",acc)
            print("Loss ",los)
            print("__________________")
        iter=iter+1

这里要注意的一个关键点,我们的图像基本上是被平坦化为一个单一的维度矢量784。函数next_batch(batch_size)必然返回batch_size为784维度向量的批次,因此它们被重塑为[batch_size,time_steps,n_input]可以被占位符接受。

我们还可以计算我们的模型的测试精度:

#calculating test accuracy
test_data = mnist.test.images[:128].reshape((-1, time_steps, n_input))
test_label = mnist.test.labels[:128]
print("Testing Accuracy:", sess.run(accuracy, feed_dict={x: test_data, y: test_label}))

运行时,模型运行测试精度为99.21%。

这个博客目的是让读者对张量流中RNN的实现细节有所了解。以便我们建立了一些更复杂的模型,以有效地在张量流中使用RNN。

本文由北邮@爱可可-爱生活老师推荐,@阿里云组织翻译。

文章原标题《Understanding LSTM in Tensorflow(MNIST dataset)》

作者:jasdeep06 博客:https://jasdeep06.github.io/

译者:袁虎 审阅:主题曲哥哥

文章为简译,更为详细的内容,请查看原文

时间: 2025-01-30 03:53:16

一步一步带你用TensorFlow玩转LSTM的相关文章

一文详解如何用 TensorFlow 实现基于 LSTM 的文本分类(附源码)

 引言 学习一段时间的tensor flow之后,想找个项目试试手,然后想起了之前在看Theano教程中的一个文本分类的实例,这个星期就用tensorflow实现了一下,感觉和之前使用的theano还是有很大的区别,有必要总结mark一下.   模型说明 这个分类的模型其实也是很简单,主要就是一个单层的LSTM模型,当然也可以实现多层的模型,多层的模型使用Tensorflow尤其简单,下面是这个模型的图  简单解释一下这个图,每个word经过embedding之后,进入LSTM层,这里LSTM是

深度学习必备手册(上)

更多深度文章,请关注云计算频道:https://yq.aliyun.com/cloud 请收下这份关于人工智能的根目录--博客整理系列(一) 关于数据科学的那些事--博客整理系列(二) 机器学习必备手册--博客整理系列(三) 扩展眼界的都在这--博客整理系列(四) 深度学习必备手册--博客整理系列(六) 深度学习的概念源于人工神经网络的研究,如果追溯深度学习的概念还是要回到2006年Hinton那篇论文,基于深信度网(DNB)提出非监督贪心逐层训练算法,未解决深层结构相关的优化难题出现的论文.

实践操作:六步教你如何用开源框架Tensorflow对象检测API构建一个玩具检测器

TensorFlow对象检测API是一个建立在TensorFlow之上的开源框架,可以轻松构建,训练和部署对象检测模型. 到目前为止,API的性能给我留下了深刻的印象.在这篇文章中,我将API的对象设定为一个可以运动的玩具.本文将用六个步骤突出API的性能并教你如何构建一个玩具探测器,你也可以根据这六个步骤扩展与实践你想要构建的任何单个或多个对象检测器. 玩具检测器 代码在我的GitHub repo上. 地址:https://github.com/priya-dwivedi/Deep-Learn

《安娜卡列尼娜》文本生成——利用 TensorFlow 构建 LSTM 模型

前言 最近看完了 LSTM 的一些外文资料,主要参考了 Colah 的 blog以及 Andrej Karpathy blog的一些关于 RNN 和 LSTM 的材料,准备动手去实现一个 LSTM 模型.代码的基础框架来自于 Udacity 上深度学习纳米学位的课程(付费课程)的一个 demo,我刚开始看代码的时候真的是一头雾水,很多东西没有理解,后来反复查阅资料,并我重新对代码进行了学习和修改,对步骤进行了进一步的剖析,下面将一步步用 TensorFlow 来构建 LSTM 模型进行文本学习并

下一个杀手级应用:Podcasting你玩了么?

播客,对于现在很多朋友而言,是个很陌生的词汇,一如当初我向小编提到过Sklip时让他感到一头雾水一样,到底什么是播客呢? 应该说,播客这个名词作为"Podcast"的中文译名使用较多的一个而已,它是数字广播技术的一种,出现的初期借助一个叫"http://www.aliyun.com/zixun/aggregation/11683.html">iPodder"的软件与一些便携播放器相结合而实现. Podcasting录制的是网络广播或类似的网络声讯节目

TensorFlow入门(五)多层 LSTM 通俗易懂版

前言: 根据我本人学习 TensorFlow 实现 LSTM 的经历,发现网上虽然也有不少教程,其中很多都是根据官方给出的例子,用多层 LSTM 来实现 PTBModel 语言模型,比如: tensorflow笔记:多层LSTM代码分析  但是感觉这些例子还是太复杂了,所以这里写了个比较简单的版本,虽然不优雅,但是还是比较容易理解. 如果你想了解 LSTM 的原理的话(前提是你已经理解了普通 RNN 的原理),可以参考我前面翻译的博客: (译)理解 LSTM 网络 (Understanding

安装Linux Mint 17后要做的20件事

安装Linux Mint 17后要做的20件事 Linux Mint 17 Qiana Cinnamon Linux Mint 17已经发布,定名为Qiana.Mint是Linux最佳发行版之一,它定位于桌面用户,关注可用性和简洁.它携带了风格迥异的桌面环境,如Mate以及Cinnamon,并基于不同的发行版,如Ubuntu或Debian. 在本文中,我们使用的是Linux Mint 17的cinnamon版本.要获取更多关于Cinnamon版本的信息(包括下载链接),可以访问 - http:/

《程序员的呐喊》一一1.10 变换

1.10 变换 程序员的呐喊 我经常听到有人说Ruby没有自动化的重构工具,所以根本没法用.虽然Ruby将来会具备一些重构功能,但是总会有一些是Java已经自动化,而Ruby没有的.他们说,这是必不可少的功能啊. 对此我表示怀疑. 到底什么是重构?字典里根本就没有这个词. 福勒告诉我们所谓重构,就是通过迭代,将恶心的代码变成优质代码的艺术和科学,是能妆点代码却不会在操作过程中产生破坏的算法,而且正确性都是能证明的. 他的剖析非常出色.他专为Java程序员呈现了一些很不错的技术,有些是早已为大家熟

AI超大事件丨从研究到应用,这是一份2017年AI领域的最全面总结

2017年已经结束了,还有什么比回顾这一整年中AI的发展历程更激动人心的吗? AI大事件的作者Denny Britz梳理了2017整年的AI大事,人工智能从研究到应用领域的回顾,都在这篇AI超大事件里了. 强化学习在很多游戏上达到了超人表现 今年AI领域最成功的故事可能就是AlphaGo了(Nature论文),AlphaGo是一个强化学习代理,击败了世界上最好的国际象棋棋手. AlphaGo的第一个版本使用来自人类专家的训练数据进行引导,并通过自我对弈和蒙特卡洛树搜索进一步提升.不久之后,Alp