TensorFlow 中的 RNN 和 LSTM 实现
RNN and LSTM implementation in tensorflow
我一直在尝试学习如何在 tensorflow 中编写 RNN 和 LSTM。我在这个博客上找到了一个在线示例 post
http://r2rt.com/recurrent-neural-networks-in-tensorflow-ii.html
以下是我无法理解最终用于生成 char-rnn 的 LSTM 网络的片段
x = tf.placeholder(tf.int32, [batch_size, num_steps], name='input_placeholder')
y = tf.placeholder(tf.int32, [batch_size, num_steps], name='labels_placeholder')
embeddings = tf.get_variable('embedding_matrix', [num_classes, state_size])
rnn_inputs = [tf.squeeze(i) for i in tf.split(1,
num_steps, tf.nn.embedding_lookup(embeddings, x))]
现在定义权重的代码的不同部分
with tf.variable_scope('softmax'):
W = tf.get_variable('W', [state_size, num_classes])
b = tf.get_variable('b', [num_classes], initializer=tf.constant_initializer(0.0))
logits = [tf.matmul(rnn_output, W) + b for rnn_output in rnn_outputs]
y_as_list = [tf.squeeze(i, squeeze_dims=[1]) for i in tf.split(1, num_steps, y)]
x是要馈送的数据,y是标签集。在 lstm 方程中,我们有一系列门,x(t) 乘以一系列,prev_hidden_state 乘以一组权重,添加偏差并应用非线性。
这里是我的疑惑
- 在这种情况下,只定义了一个权重矩阵是否意味着
也适用于 x(t) 和 prev_hidden_state。
- 对于嵌入矩阵,我知道它必须乘以
权重矩阵,但为什么第一维是 num_classes
- 对于 rnn_inputs 我们使用 squeeze 移除 1 的维度
但为什么我要在单热编码中这样做。
- 我还从拆分中了解到我们正在展开 x
维度 (batch_size X num_steps) 到离散 (batch_size X 1)
向量,然后通过网络传递这些值是这样的
对
我可以帮你吗
在这种情况下,只定义了一个权重矩阵是否意味着它对 x(t) 和 prev_hidden_state 都适用。
如你所说还有更多权重tf.nn.rnn_cell.LSTMCell
。它们是 RNN 单元的内部权重,当您调用单元时,tensorflow 会隐式创建它。
您显式定义的权重矩阵是从隐藏状态到词汇表的变换space。
可以查看循环部分的隐式权重,取前一个隐藏状态和当前输入输出新的隐藏状态。并且您定义的权重矩阵将隐藏状态(即state_size = 200
)转换为更高的词汇space。(即vocab_size = 2000
)
欲了解更多信息,也许您可以查看此教程:http://colah.github.io/posts/2015-08-Understanding-LSTMs/
对于嵌入矩阵,我知道它必须乘以权重矩阵,但为什么第一维是 num_classes
num_classes 占 vocab_size
,嵌入矩阵正在将词汇表转换为所需的嵌入大小(在本例中等于 state_size
)。
对于 rnn_inputs,我们使用的是压缩,它删除了 1 的维度,但为什么我要在单热编码中这样做。
您需要去掉额外的维度,因为 tf.nn.rnn
将输入作为 (batch_size, input_size)
而不是 (batch_size, 1, input_size)
。
我还从拆分中了解到,我们正在将维度 (batch_size X num_steps) 的 x 展开为离散 (batch_size X 1) 向量,然后将这些值传递给网络是这样吗?
嵌入后更精确。 (batch_size, num_steps, state_size)
变成 num_step
个元素的列表,每个元素的大小为 (batch_size, 1, state_size)
.
流程是这样的:
- 嵌入矩阵将每个单词嵌入为
state_size
维向量(矩阵的一行),使得大小(vocab_size, state_size)
.
- 检索由 x 占位符指定的索引并获取大小为
(batch_size, num_steps, state_size)
的 rnn 输入。
tf.split
将输入拆分为 (batch_size, 1, state_size)
tf.squeeze
将它们压缩为 (batch_size, state_size)
,形成 tf.nn.rnn
. 所需的输入格式
如果tensorflow的方法有什么问题,或许可以在tensorflowAPI中搜索一下,更详细的介绍。
我一直在尝试学习如何在 tensorflow 中编写 RNN 和 LSTM。我在这个博客上找到了一个在线示例 post
http://r2rt.com/recurrent-neural-networks-in-tensorflow-ii.html
以下是我无法理解最终用于生成 char-rnn 的 LSTM 网络的片段
x = tf.placeholder(tf.int32, [batch_size, num_steps], name='input_placeholder')
y = tf.placeholder(tf.int32, [batch_size, num_steps], name='labels_placeholder')
embeddings = tf.get_variable('embedding_matrix', [num_classes, state_size])
rnn_inputs = [tf.squeeze(i) for i in tf.split(1,
num_steps, tf.nn.embedding_lookup(embeddings, x))]
现在定义权重的代码的不同部分
with tf.variable_scope('softmax'):
W = tf.get_variable('W', [state_size, num_classes])
b = tf.get_variable('b', [num_classes], initializer=tf.constant_initializer(0.0))
logits = [tf.matmul(rnn_output, W) + b for rnn_output in rnn_outputs]
y_as_list = [tf.squeeze(i, squeeze_dims=[1]) for i in tf.split(1, num_steps, y)]
x是要馈送的数据,y是标签集。在 lstm 方程中,我们有一系列门,x(t) 乘以一系列,prev_hidden_state 乘以一组权重,添加偏差并应用非线性。
这里是我的疑惑
- 在这种情况下,只定义了一个权重矩阵是否意味着 也适用于 x(t) 和 prev_hidden_state。
- 对于嵌入矩阵,我知道它必须乘以 权重矩阵,但为什么第一维是 num_classes
- 对于 rnn_inputs 我们使用 squeeze 移除 1 的维度 但为什么我要在单热编码中这样做。
- 我还从拆分中了解到我们正在展开 x 维度 (batch_size X num_steps) 到离散 (batch_size X 1) 向量,然后通过网络传递这些值是这样的 对
我可以帮你吗
在这种情况下,只定义了一个权重矩阵是否意味着它对 x(t) 和 prev_hidden_state 都适用。
如你所说还有更多权重tf.nn.rnn_cell.LSTMCell
。它们是 RNN 单元的内部权重,当您调用单元时,tensorflow 会隐式创建它。
您显式定义的权重矩阵是从隐藏状态到词汇表的变换space。
可以查看循环部分的隐式权重,取前一个隐藏状态和当前输入输出新的隐藏状态。并且您定义的权重矩阵将隐藏状态(即state_size = 200
)转换为更高的词汇space。(即vocab_size = 2000
)
欲了解更多信息,也许您可以查看此教程:http://colah.github.io/posts/2015-08-Understanding-LSTMs/
对于嵌入矩阵,我知道它必须乘以权重矩阵,但为什么第一维是 num_classes
num_classes 占 vocab_size
,嵌入矩阵正在将词汇表转换为所需的嵌入大小(在本例中等于 state_size
)。
对于 rnn_inputs,我们使用的是压缩,它删除了 1 的维度,但为什么我要在单热编码中这样做。
您需要去掉额外的维度,因为 tf.nn.rnn
将输入作为 (batch_size, input_size)
而不是 (batch_size, 1, input_size)
。
我还从拆分中了解到,我们正在将维度 (batch_size X num_steps) 的 x 展开为离散 (batch_size X 1) 向量,然后将这些值传递给网络是这样吗?
嵌入后更精确。 (batch_size, num_steps, state_size)
变成 num_step
个元素的列表,每个元素的大小为 (batch_size, 1, state_size)
.
流程是这样的:
- 嵌入矩阵将每个单词嵌入为
state_size
维向量(矩阵的一行),使得大小(vocab_size, state_size)
. - 检索由 x 占位符指定的索引并获取大小为
(batch_size, num_steps, state_size)
的 rnn 输入。 tf.split
将输入拆分为(batch_size, 1, state_size)
tf.squeeze
将它们压缩为(batch_size, state_size)
,形成tf.nn.rnn
. 所需的输入格式
如果tensorflow的方法有什么问题,或许可以在tensorflowAPI中搜索一下,更详细的介绍。