machine-learning - TimeDistributed(Dense) 与 Keras 中的 Dense - 相同数量的参数

标签 machine-learning neural-network keras recurrent-neural-network keras-layer

我正在构建一个模型,该模型使用循环层 (GRU) 将一个字符串转换为另一个字符串。我尝试过使用 Dense 层和 TimeDistributed(Dense) 层作为最后一层,但我不明白使用 return_sequences=True 时两者之间的区别,特别是因为它们似乎具有相同数量的参数.

我的简化模型如下:

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         
=================================================================

我想知道这是否是因为 Dense() 只会使用形状中的最后一个维度,并有效地将其他所有维度视为批处理维度。但后来我不再确定 Dense 和 TimeDistributed(Dense) 之间有什么区别。

更新查看https://github.com/fchollet/keras/blob/master/keras/layers/core.py看起来 Dense 确实仅使用最后一个维度来调整自身大小:

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() 在这种情况下实现了什么。

最佳答案

TimeDistributedDense 在 GRU/LSTM 单元展开期间对每个时间步应用相同的密集。因此误差函数将位于预测标签序列和实际标签序列之间。 (这通常是序列到序列标记问题的要求)。

但是,使用 return_sequences=False 时,Dense 层仅在最后一个单元格应用一次。当 RNN 用于分类问题时通常会出现这种情况。如果return_sequences=True,则Dense层将应用于每个时间步,就像TimeDistributedDense一样。

因此,根据您的模型,两者是相同的,但如果您将第二个模型更改为 return_sequences=False,则 Dense 将仅应用于最后一个单元格。尝试更改它,模型将抛出错误,因为 Y 的大小将为 [Batch_size, InputSize],它不再是要排序的序列,而是完整的序列标签问题。

from keras.models import Sequential
from keras.layers import Dense, Activation, TimeDistributed
from keras.layers.recurrent import GRU
import numpy as np

InputSize = 15
MaxLen = 64
HiddenSize = 16

OutputSize = 8
n_samples = 1000

model1 = Sequential()
model1.add(GRU(HiddenSize, return_sequences=True, input_shape=(MaxLen, InputSize)))
model1.add(TimeDistributed(Dense(OutputSize)))
model1.add(Activation('softmax'))
model1.compile(loss='categorical_crossentropy', optimizer='rmsprop')


model2 = Sequential()
model2.add(GRU(HiddenSize, return_sequences=True, input_shape=(MaxLen, InputSize)))
model2.add(Dense(OutputSize))
model2.add(Activation('softmax'))
model2.compile(loss='categorical_crossentropy', optimizer='rmsprop')

model3 = Sequential()
model3.add(GRU(HiddenSize, return_sequences=False, input_shape=(MaxLen, InputSize)))
model3.add(Dense(OutputSize))
model3.add(Activation('softmax'))
model3.compile(loss='categorical_crossentropy', optimizer='rmsprop')

X = np.random.random([n_samples,MaxLen,InputSize])
Y1 = np.random.random([n_samples,MaxLen,OutputSize])
Y2 = np.random.random([n_samples, OutputSize])

model1.fit(X, Y1, batch_size=128, nb_epoch=1)
model2.fit(X, Y1, batch_size=128, nb_epoch=1)
model3.fit(X, Y2, batch_size=128, nb_epoch=1)

print(model1.summary())
print(model2.summary())
print(model3.summary())

在上面的示例架构中,model1model2 是示例(序列到序列模型),model3 是完整的序列到标签模型.

关于machine-learning - TimeDistributed(Dense) 与 Keras 中的 Dense - 相同数量的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44611006/

相关文章:

python - scikit-learn 将额外数据添加到 SGDClassifier

python - 如何使用小批量代替 SGD

C# Encog 神经网络——尽管神经网络的整体误差很低,但预期输出与实际误差相去甚远

javascript - 标量输出 Tensorflow JS

python - 神经网络只预测一类,所有用于测试的输出层激活变成0.999~

python - TypeError : If class_mode ="categorical", y_col 列值必须是字符串、列表或元组类型

machine-learning - 连续/数字特征的互信息

python - 人脸识别keras维数问题

python - 为 LSTM 选择 time_step

python - Theano 在树莓派上使用 Keras