我正在建立一个模型,使用周期图层(GRUs)将字符串转换为另一个字符串。我已经尝试了密集型和时间分布(密集)层作为最后一层,但我不明白使用return_sequences = True时两者之间的差异,特别是因为它们看起来具有相同数量的参数。时间分布(密集)与密集在Keras - 相同数量的参数
我的简化模型如下:
InputSize = 15
MaxLen = 64
HiddenSize = 16
inputs = keras.layers.Input(shape=(MaxLen, InputSize))
x = keras.layers.recurrent.GRU(HiddenSize, return_sequences=True)(inputs)
x = keras.layers.TimeDistributed(keras.layers.Dense(InputSize))(x)
predictions = keras.layers.Activation('softmax')(x)
网络的总结是:
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 64, 15) 0
_________________________________________________________________
gru_1 (GRU) (None, 64, 16) 1536
_________________________________________________________________
time_distributed_1 (TimeDist (None, 64, 15) 255
_________________________________________________________________
activation_1 (Activation) (None, 64, 15) 0
=================================================================
这是有道理的,以我为我的TimeDistributed的理解是,它适用于同一层的所有时间点,所以密集层有16 * 15 + 15 = 255个参数(权重+偏差)。
但是,如果我切换到一个简单的致密层:
inputs = keras.layers.Input(shape=(MaxLen, InputSize))
x = keras.layers.recurrent.GRU(HiddenSize, return_sequences=True)(inputs)
x = keras.layers.Dense(InputSize)(x)
predictions = keras.layers.Activation('softmax')(x)
我仍然只有255个参数:
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 64, 15) 0
_________________________________________________________________
gru_1 (GRU) (None, 64, 16) 1536
_________________________________________________________________
dense_1 (Dense) (None, 64, 15) 255
_________________________________________________________________
activation_1 (Activation) (None, 64, 15) 0
=================================================================
我不知道这是因为密集()将只使用最后维度的形状,并将其他所有内容有效地视为批量维度。但是,我不确定密集和TimeDistributed(密集)之间有什么不同。
更新看着https://github.com/fchollet/keras/blob/master/keras/layers/core.py它似乎是密集使用最后一个维度只大小本身:
def build(self, input_shape):
assert len(input_shape) >= 2
input_dim = input_shape[-1]
self.kernel = self.add_weight(shape=(input_dim, self.units),
它还使用keras.dot申请权:
def call(self, inputs):
output = K.dot(inputs, self.kernel)
的keras.dot意味着它可以很好地处理n维张量。我想知道它的确切行为是否意味着Dense()将在每个时间步骤被调用。如果是这样,这个问题仍然是TimeDistributed()在这种情况下实现的。
让我补充一点,这两个模型在训练过程中的表现几乎完全相同。 – thon
我也一直在想。所以你确认了Dense()和TimeDistributed(Dense())在你的情况下具有相同的性能?我认为更好的API设计将允许用户设置参数,无论是在时间步上使用相同的密集层,还是在每个时间步使用单独的密集层。 – ymeng