在语言建模任务上训练循环神经网络

  • A+
所属分类:人工智能
广告也精彩

介绍

有关递归神经网络和 LSTM 的介绍,请参阅了解 LSTM 网络(https://colah.github.io/posts/2015-08-Understanding-LSTMs/)。

语言建模

语言建模是一项极具挑战性的任务,在本教程中,我们将展示如何在语言建模任务上训练循环神经网络,目标是将概率分配给句子的概率模型进行拟合。 它通过预测文本中的下一个单词来给出前一个单词的历史记录。 为此,我们将使用 Penn Tree Bank(PTB)数据集,这是目前流行的基准,用来衡量这些模型的质量,且体积较小,训练的速度也相对较快。

语言建模是解决许多有趣问题的关键,诸如语音识别,机器翻译或图像字幕等。 而且也很有趣 – 来看看 这里(https://karpathy.github.io/2015/05/21/rnn-effectiveness/)。

为了说明本教程,我们将重现 Zaremba 等人发表的 2014(pdf)结果,其在 PTB 数据集上取得了非常好的质量。

教程文件

本教程引用 TensorFlow 模型库中的 models / tutorials / rnn / ptb 中的以下文件:

在语言建模任务上训练循环神经网络

下载并准备数据

本教程所需的数据位于 Tomas Mikolov 网页的 PTB 数据集 的目录中(http://www.fit.vutbr.cz/~imikolov/rnnlm/simple-examples.tgz)。

数据集已经预处理,含有全面的 10000 个不同的词,包括句子结尾的标记和用于罕见词语的特殊符号(<UNK>)。 在 reader.py 中,我们将每个单词转换为唯一的整数标识符,以便神经网络可以轻松处理数据。

模型

LSTM

该模型的核心由一个 LSTM 单元组成,该单元一次处理一个单词并计算句子中下一个单词的可能值的概率。使用零向量初始化网络的内存状态,并在读取每个单词后进行更新。出于计算的原因,我们将以小批量 batch_size 来处理数据。在本示例中,要注意 current_batch_of_words 和由单词组成的句型并不对应,这点非常重要。 批处理中的每个单词都应与时间 t 相对应。TensorFlow 将自动为您分配每批的梯度。

例如:

t=0  t=1    t=2  t=3     t=4

[The, brown, fox, is,     quick]

[The, red,   fox, jumped, high]

words_in_dataset[0] = [The, The]

words_in_dataset[1] = [brown, red]

words_in_dataset[2] = [fox, fox]

words_in_dataset[3] = [is, jumped]

words_in_dataset[4] = [quick, high]

batch_size = 2, time_steps = 5

基本伪代码如下:

words_in_dataset = tf.placeholder(tf.float32, [time_steps, batch_size, num_features])

lstm = tf.contrib.rnn.BasicLSTMCell(lstm_size)

# Initial state of the LSTM memory.

state = lstm.zero_state(batch_size, dtype=tf.float32)

probabilities = []

loss = 0.0

for current_batch_of_words in words_in_dataset:

# The value of state is updated after processing each batch of words.

output, state = lstm(current_batch_of_words, state)

# The LSTM output can be used to make next word predictions

logits = tf.matmul(output, softmax_w) + softmax_b

probabilities.append(tf.nn.softmax(logits))

loss += loss_function(probabilities, target_words)

截断反向传播

通过设计,递归神经网络(RNN)的输出取决于任意远距离的输入。 遗憾的是,这增加了反向传播计算的困难性。 为了使学习过程易于处理,通常的做法是创建网络的 “展开” 版本,其中包含固定数量(num_steps)的 LSTM 输入和输出。 然后在 RNN 的这种有限近似上训练该模型。 可以通过一次输入长度为 num_steps 的输入并在每个这样的输入块之后执行反向传递来实现。

这是一个简化的代码块,用于创建执行截断反向传播的图形:

# Placeholder for the inputs in a given iteration.

words = tf.placeholder(tf.int32, [batch_size, num_steps])

lstm = tf.contrib.rnn.BasicLSTMCell(lstm_size)

# Initial state of the LSTM memory.

initial_state = state = lstm.zero_state(batch_size, dtype=tf.float32)

for i in range(num_steps):

# The value of state is updated after processing each batch of words.

output, state = lstm(words[:, i], state)

# The rest of the code.

# ...

final_state = state

这是如何在整个数据集上实现迭代:

# A numpy array holding the state of LSTM after each batch of words.

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],

# Initialize the LSTM state from the previous iteration.

feed_dict={initial_state: numpy_state, words: current_batch_of_words})

total_loss += current_loss

输入

在输入 LSTM 之前,单词 ID 将嵌入到密集表示中(请参阅 矢量表示教程 https://www.tensorflow.org/tutorials/representation/word2vec)。 这允许模型对有关特定单词的知识进行有效地表示,且写起来也很容易:

# embedding_matrix is a tensor of shape [vocabulary_size, embedding size]

word_embeddings = tf.nn.embedding_lookup(embedding_matrix, word_ids)

嵌入矩阵将随机初始化,模型将学习通过查看数据来区分单词的含义。

损失函数

我们要将目标词的平均负对数概率最小化:

在语言建模任务上训练循环神经网络

虽然执行起来并不是很困难,不过函数 sequence_loss_by_example 已经是可用状态,所以我们可以在此使用。

论文中报告的典型指标是每个单词的平均困惑值(通常只称为困惑值),等于

在语言建模任务上训练循环神经网络

我们将在整个训练过程中监控其价值。

堆叠多个 LSTM

为使模型具有更强的表现力,我们可以添加多层 LSTM 来处理数据。 第一层的输出将成为第二层的输入,依此类推。

我们有一个名为 MultiRNNCell 的类,可实现无缝:

def lstm_cell():

return tf.contrib.rnn.BasicLSTMCell(lstm_size)

stacked_lstm = tf.contrib.rnn.MultiRNNCell(

[lstm_cell() for _ in range(number_of_layers)])

initial_state = state = stacked_lstm.zero_state(batch_size, tf.float32)

for i in range(num_steps):

# The value of state is updated after processing each batch of words.

output, state = stacked_lstm(words[:, i], state)

# The rest of the code.

# ...

final_state = state

运行代码

在运行代码之前,请下载 PTB 数据集,如本教程开头所述。然后,提取主目录下的 PTB 数据集,如下所示:

tar xvfz simple-examples.tgz -C $HOME

注意:在 Windows 上,您可能需要使用 其他工具(https://wiki.haskell.org/How_to_unpack_a_tar_file_in_Windows)。

现在,克隆来自 GitHub 的 TensorFlow 模型 repo(https://github.com/tensorflow/models)。运行以下命令:

cd models/tutorials/rnn/ptb

python ptb_word_lm.py --data_path=$HOME/simple-examples/data/ --model=small

教程代码中有 3 种支持的模型配置:“小”,“中” 和 “大”。 它们的区别在于 LSTM 的大小和用于训练的超参数集。

模型越大,应该取得的结果越好。 小型模型在测试装置上达到的困惑值应低于 120,大型模型可达到困惑值 80 以下,尽管这可能需要好几个小时来训练。

未来

还有一些我们没有提及的技巧可以使模型更佳,包括:

• 降低学习率计划

• LSTM 层之间的丢失

将继续研究代码并对其进行修改,进一步改进模型。

  • 微信
  • 扫一扫
  • weinxin
  • 微信公众号
  • 扫一扫
  • weinxin
广告也精彩
Wireless无线蓝牙运动耳机
半身裙时尚
iPhone 配件
唐人街探案 大朋vr一体机M2 Pro 头戴式VR眼镜  虚拟现实电影视频 1万+部影视 百款游戏
广告也精彩

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: