递归神经网络

本教程的目的是重现 Zaremba et al., 2014 的成果,他们在 PTB 数据集上得到了很棒的结果。

教程文件

本教程使用的下面文件的目录是 models/rnn/ptb:

文件 作用
ptb_word_lm.py 在 PTB 数据集上训练一个语言模型.
reader.py 读取数据集.

下载及准备数据

本教程需要的数据在 data/ 路径下,来源于 Tomas Mikolov 网站上的 PTB 数据集http://www.fit.vutbr.cz/~imikolov/rnnlm/simple-examples.tgz

该数据集已经预先处理过并且包含了全部的 10000 个不同的词语,其中包括语句结束标记符,以及标记稀有词语的特殊符号 (<unk>) 。我们在 reader.py 中转换所有的词语,让他们各自有唯一的整型标识符,便于神经网络处理。

模型

LSTM

模型的核心由一个 LSTM 单元组成,其可以在某时刻处理一个词语,以及计算语句可能的延续性的概率。网络的存储状态由一个零矢量初始化并在读取每一个词语后更新。而且,由于计算上的原因,我们将以 batch_size 为最小批量来处理数据。

基础的伪代码就像下面这样:

lstm = rnn_cell.BasicLSTMCell(lstm_size)
# 初始化 LSTM 存储状态.
state = tf.zeros([batch_size, lstm.state_size])

loss = 0.0
for current_batch_of_words in words_in_dataset:
    # 每次处理一批词语后更新状态值.
    output, state = lstm(current_batch_of_words, state)

    # LSTM 输出可用于产生下一个词语的预测
    logits = tf.matmul(output, softmax_w) + softmax_b
    probabilities = tf.nn.softmax(logits)
    loss += loss_function(probabilities, target_words)

截断反向传播

为使学习过程易于处理,通常的做法是将反向传播的梯度在(按时间)展开的步骤上照一个固定长度(num_steps)截断。 通过在一次迭代中的每个时刻上提供长度为 num_steps 的输入和每次迭代完成之后反向传导,这会很容易实现。

一个简化版的用于计算图创建的截断反向传播代码:

# 一次给定的迭代中的输入占位符.
words = tf.placeholder(tf.int32, [batch_size, num_steps])

lstm = rnn_cell.BasicLSTMCell(lstm_size)
# 初始化 LSTM 存储状态.
initial_state = state = tf.zeros([batch_size, lstm.state_size])

for i in range(len(num_steps)):
    # 每处理一批词语后更新状态值.
    output, state = lstm(words[:, i], state)

    # 其余的代码.
    # ...

final_state = state

下面展现如何实现迭代整个数据集:

# 一个 numpy 数组,保存每一批词语之后的 LSTM 状态.
numpy_state = initial_state.eval()
total_loss = 0.0
for current_batch_of_words in words_in_dataset:
    numpy_state, current_loss = session.run([final_state, loss],
        # 通过上一次迭代结果初始化 LSTM 状态.
        feed_dict={initial_state: numpy_state, words: current_batch_of_words})
    total_loss += current_loss

输入

在输入 LSTM 前,词语 ID 被嵌入到了一个密集的表示中(查看 矢量表示教程)。这种方式允许模型高效地表示词语,也便于写代码:

# embedding_matrix 张量的形状是: [vocabulary_size, embedding_size]
word_embeddings = tf.nn.embedding_lookup(embedding_matrix, word_ids)

嵌入的矩阵会被随机地初始化,模型会学会通过数据分辨不同词语的意思。

损失函数

我们想使目标词语的平均负对数概率最小

实现起来并非很难,而且函数 sequence_loss_by_example 已经有了,可以直接使用。

论文中的典型衡量标准是每个词语的平均困惑度(perplexity),计算式为

同时我们会观察训练过程中的困惑度值(perplexity)。

多个 LSTM 层堆叠

要想给模型更强的表达能力,可以添加多层 LSTM 来处理数据。第一层的输出作为第二层的输入,以此类推。

类 MultiRNNCell 可以无缝的将其实现:

lstm = rnn_cell.BasicLSTMCell(lstm_size)
stacked_lstm = rnn_cell.MultiRNNCell([lstm] * number_of_layers)

initial_state = state = stacked_lstm.zero_state(batch_size, tf.float32)
for i in range(len(num_steps)):
    # 每次处理一批词语后更新状态值.
    output, state = stacked_lstm(words[:, i], state)

    # 其余的代码.
    # ...

final_state = state

编译并运行代码

首先需要构建库,在 CPU 上编译:

bazel build -c opt tensorflow/models/rnn/ptb:ptb_word_lm

如果你有一个强大的 GPU,可以运行:

bazel build -c opt --config=cuda tensorflow/models/rnn/ptb:ptb_word_lm

运行模型:

bazel-bin/tensorflow/models/rnn/ptb/ptb_word_lm   --data_path=/tmp/simple-examples/data/ --alsologtostderr --model small

教程代码中有 3 个支持的模型配置参数:"small", "medium" 和 "large"。它们指的是 LSTM 的大小,以及用于训练的超参数集。

模型越大,得到的结果应该更好。在测试集中 small 模型应该可以达到低于 120 的困惑度(perplexity),large 模型则是低于 80,但它可能花费数小时来训练。

除此之外?

还有几个优化模型的技巧没有提到,包括:

  • 随时间降低学习率,
  • LSTM 层间 dropout.

继续学习和更改代码以进一步改善模型吧。

原文:Recurrent Neural Networks 翻译:Warln 校对:HongyangWang

时间: 2024-11-10 15:07:36

递归神经网络的相关文章

递归神经网络的不可思议的有效性 [ 译 / 转 ]

递归神经网络(Recurrent Neural Networks,RNNs)就像一种神奇的魔法.我至今仍对于我第一次训练递归网络记忆犹新.那个网络是被用于生成图像说明(Image Captioning)的.仅仅进行了几十分钟的训练,我的第一个模型(这个模型中相当一部分超参数都是我随意选取的)就开始能给图片生成看起来非常不错的描述,而这些描述基本上能称得上是有意义的.有时结果的质量和模型复杂度之间的关联性完全超出你的预期,而我的第一次实验就是一个例子.为什么当时这些训练结果看起来如此惊人?是因为大

深入探究递归神经网络:大牛级的训练和优化如何修成?

深入探究递归神经网络:大牛级的训练和优化如何修成? 摘要:不同于传统FNN,RNN无需在层面之间构建,同时引入定向循环,能够更好地处理高维度信息的整体逻辑顺序.本文中,MIT的Nikhil Buduma将带您深入探析RNN的原理.训练和优化等各方面的内容,以及RNN已经获取的一些成就. 在深度学习领域,传统的前馈神经网络(feed-forward neural net,简称FNN)具有出色的表现,取得了许多成功,它曾在许多不同的任务上——包括手写数字识别和目标分类上创造了记录.甚至到了今天,FN

能模仿韩寒小四写作的神奇递归神经网络

作者:寒小阳 && 龙心尘 时间:2016年4月 出处: http://blog.csdn.net/han_xiaoyang/article/details/51253274 http://blog.csdn.net/longxinchen_ml/article/details/51253526 声明:版权所有,转载请联系作者并注明出处 特别鸣谢:北京大学焦剑博士对Recurrent Neural Networks Tutorial part1一文的翻译和部分内容提供 1.引言 在离人工智

递归神经网络不可思议的有效性

递归神经网络(RNNs)有一些不可思议的地方.我仍然记得我训练的第一个用于 图片字幕的递归网络.从花几十分钟训练我的第一个婴儿模型(相当随意挑选的超参数)开始,到训练出能够针对图像给出有意义描述的模型.有些时候,模型对于输出结果质量的简单程度的比例,会与你的期望相差甚远,而这还仅仅是其中一点.有如此令人震惊结果,许多人认为是因为RNNs非常难训练(事实上,通过多次试验,我得出了相反的结论).一年前:我一直在训练RNNs,我多次见证了它们的强大的功能和鲁棒性,而且它们的输出结果同样让我感到有趣.这

TensorFlow(十一):递归神经网络(RNN与LSTM)

RNN RNN(Recurrent Neural Networks,循环神经网络)不仅会学习当前时刻的信息,也会依赖之前的序列信息.由于其特殊的网络模型结构解决了信息保存的问题.所以RNN对处理时间序列和语言文本序列问题有独特的优势.递归神经网络都具有一连串重复神经网络模块的形式.在标准的RNNs中,这种重复模块有一种非常简单的结构. 那么S(t+1) = tanh( U*X(t+1) + W*S(t)).tanh激活函数图像如下: 激活函数tanh把状态S值映射到-1和1之间. RNN通过BP

递归神经网络RNN

递归神经网络 实际属于输入之间可能是存在联系的,所以在多次输入x0.x1........中,每次的中间信息A(也称为机器单元)都保存下来传给下次输入的中间信息A,每次输入的计算结果h0.h1......不一定是目标结果可以不使用,只有最终的ht是想要的预测结果. 递归神经网络适合自然语言处理. 每一步都会对它之前所有的操作进行参数更新,这个与其他的神经网络是不同的. 以E3为例,它的反向传播指向s3,而s3的反向传播指向s2和x3,会对它前面的所有的步都进行更新. 递归神经网络会出现梯度消失(某

抽象理解切片递归神经网络(SRNN)的结构

过年这几天只能待家里了,最近几个月,上海交通大学的研究人员提出了切片递归神经网络(SRNN)的结构,该结构在不改变循环单元的情况下比RNN结构快135倍. 这种操作,就像踩在一个热轮子上,是怎么发生的? 在论文<Sliced Recurrent Neural Networks>中,研究者给出了具体的介绍.让我们来看看这篇论文的重点“只关注不谈论”——. “曲线救国”的PaperBERT 传统RNN结构中最流行的循环单元是LSTM和GRU,两者都可以通过隐藏层中的门控机制(Gating Mech

循环和递归神经网络 (RNN) 与 长短时记忆 (LSTM)

即使不是 NLPer,现实中依然会面对很多序列问题. 全文内容来自 Ian Goodfellow, Yoshua Bengio 和 Aaron Courville 3位大老爷的作品"Deep Learning"的其中1章"Sequence Modeling: Recurrent and Recursive Nets" 1. 1986年 Rumelhart 等人提出循环神经网络.循环网络与多层网络相比,会共享每层的权重,从而能够扩展和应用网络于不同长度的序列案例,以及

递归神经网络(Recurrent Neural Networks,RNN)

在深度学习领域,传统的多层感知机(MLP)具有出色的表现,取得了许多成功,它曾在许多不同的任务上——包括手写数字识别和目标分类上创造了记录.甚至到了今天,MLP在解决分类任务上始终都比其他方法要略胜一筹. 尽管如此,大多数专家还是会达成共识:MLP可以实现的功能仍然相当有限.究其原因,人类的大脑有着惊人的计算功能,而“分类”任务仅仅是其中很小的一个组成部分.我们不仅能够识别个体案例,更能分析输入信息之间的整体逻辑序列.这些信息序列富含有大量的内容,信息彼此间有着复杂的时间关联性,并且信息长度各种