为什么不使用 Flatten 后跟 Dense 层而不是 TimeDistributed?

Why not use Flatten followed by a Dense layer instead of TimeDistributed?

我正在努力更好地理解 Keras 层。我正在研究一个序列到序列模型,我在其中嵌入一个句子并将其传递给 returns 序列的 LSTM。此后,我想对句子中的每个时间步长(单词)应用一个 Dense 层,并且 TimeDistributed 似乎像这种情况一样为三维张量完成了工作。

据我了解,密集层仅适用于二维张量,而 TimeDistributed 仅在三维空间的每个时间步上应用相同的密集层。难道不能简单地压平时间步长,应用致密层并执行重塑以获得相同的结果,或者这些在某种程度上不等同,我错过了吗?

假设您有一批 4 个时间步长,每个时间步长包含一个 3 元素向量。让我们用这个来表示:

现在你想使用密集层来转换这个批处理,所以你每个时间步得到 5 个特征。该层的输出可以表示为如下所示:

您考虑两个选项,一个 TimeDistributed 密集层,或重塑为平面输入,应用密集层并重塑回时间步长。

在第一个选项中,您将对每个时间步应用一个具有 3 个输入和 5 个输出的密集层。这可能看起来像这样:

这里的每个蓝色圆圈是密集层中的一个单元。通过对每个输入时间步执行此操作,您可以获得总输出。重要的是,这五个单元对于所有时间步长都是相同的,因此您只有一个具有 3 个输入和 5 个输出的密集层的参数。

第二个选项涉及将输入展平为 12 元素向量,应用具有 12 个输入和 20 个输出的密集层,然后将其重新整形。这是它的样子:

这里为了清楚起见只画了一个单元的输入连接,但是每个单元都会连接到每个输入。显然,在这里,您有更多的参数(具有 12 个输入和 20 个输出的密集层的参数),并且还要注意每个输出值都受到每个输入值的影响,因此一个时间步长中的值会影响其他时间步长的输出.这是好事还是坏事取决于您的问题和模型,但这是与之前的重要区别,在之前每个时间步长的输入和输出都是独立的。除此之外,此配置要求您在每个批次上使用固定数量的时间步长,而之前的工作独立于时间步长数。

您还可以考虑选择具有四个密集层的选项,每个密集层独立应用于每个时间步长(我没有画出来,但希望您能理解)。这与前一个类似,只是每个单元只会从其各自的时间步长输入接收输入连接。我认为在 Keras 中没有直接的方法可以做到这一点,您必须将输入分成四个,对每个部分应用密集层并合并输出。同样,在这种情况下,时间步数将是固定的。

Dense 层可以作用于任何张量,不一定是 2 阶。我认为 TimeDistributed 包装器不会改变 Dense 层的作用方式。仅将 Dense 层应用于 3 阶张量将与应用 Dense 层的 TimeDistributed 包装器完全相同。这是插图:

from tensorflow.keras.layers import *
from tensorflow.keras.models import *

model = Sequential()

model.add(Dense(5,input_shape=(50,10)))

model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_5 (Dense)              (None, 50, 5)             55        
=================================================================
Total params: 55
Trainable params: 55
Non-trainable params: 0
_________________________________________________________________
model1 = Sequential()

model1.add(TimeDistributed(Dense(5),input_shape=(50,10)))

model1.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
time_distributed_3 (TimeDist (None, 50, 5)             55        
=================================================================
Total params: 55
Trainable params: 55
Non-trainable params: 0
_________________________________________________________________

除了上述答案之外, 这里有几张图片比较了两层的输出形状。因此,当在 LSTM(例如)之后使用这些层之一时,会有不同的行为。