我正在阅读第14章的手工机器学习与Scikit-学习和TensorFlow。上面写着:
虽然使用
OutputProjectionWrapper
是将RNN输出序列的维数降到每个时间步长(每个实例)只有一个值的最简单的解决方案,但它并不是最有效的。有一个更复杂但更有效的解决方案:您可以重塑RNN输出,然后应用一个具有适当输出大小的完全连接层。..。这可以提供一个显著的速度提升,因为只有一个完全连接的层,而不是一个时间步骤。
这对我来说毫无意义。对于OutputProjectionWrapper
,我们需要每个时间步骤执行两个操作:
当然,当我们在顶部使用普通的BasicRNNCell
+密集层时,我们只需要在每个时间步骤上做一个操作(第一个),但是接下来我们需要将每个输出张量通过我们的密集层。因此,在这两种情况下,我们都需要执行同样数量的操作。
另外,我无法理解以下部分:
这可以提供一个显著的速度提升,因为只有一个完全连接的层,而不是一个时间步骤。
在这两种情况下,我们不是只有一个完全连接的层吗?据我所知,OutputProjectionWrapper
在每个时间步骤上都使用相同的共享层。我甚至不知道它如何为每个时间步骤创建不同的层,因为OutputProjectionWrapper
没有我们将要使用的时间步骤的数量信息。
如果有人能解释这些方法的不同之处,我将非常感激。
UPD这里是这个问题的伪码。我是不是遗漏了什么?
# 2 time steps, x1 and x2 - inputs, h1 and h2 - hidden states, y1 and y2 - outputs.
# OutputProjectionWrapper
h1 = calc_hidden(x1, 0)
y1 = dense(h1)
h2 = calc_hidden(x2, h1)
y2 = dense(h2)
# BasicRNNCell + dense layer on top of all time steps
h1 = calc_hidden(x1, 0)
y1 = h1
h2 = calc_hidden(x2, h1)
y2 = h2
y1 = dense(y1)
y2 = dense(y2)
UPD 2我创建了两个小代码片段(一个带有OutputProjectionWrapper
,另一个在顶部有BasicRNNCell
和tf.layers.dense
)--它们都创建了14个形状相同的变量。因此,这些方法之间绝对没有记忆上的差异。
发布于 2020-05-22 13:20:58
我猜想,对形状张量(x,n)施加1层比对形状(x) n倍的张量施加同一层要快。
发布于 2019-08-04 15:46:48
这个网页对你的问题有一个详细的解释。
https://www.oreilly.com/library/view/neural-networks-and/9781492037354/ch04.html
这是上面一页的节选。希望这能有所帮助。
虽然使用OutputProjectionWrapper是将RNN输出序列的维数降到每个时间步长(每个实例)只有一个值的最简单的解决方案,但它并不是最有效的。有一个更复杂但更有效的解决方案:您可以重新构造batch_size、n_steps、n_neurons到batch_size *n_steps、n_neurons的RNN输出,然后应用一个具有适当输出大小的完全连接层(在我们的例子中只有1),这将产生一个形状为batch_size * n_steps,n_outputs的输出张量,然后将该张量整形到batch_size、n_steps、n_outputs。这些操作如图4-10所示.
https://stackoverflow.com/questions/55301120
复制相似问题