Keras 顺序时间分布模型 2 和 3 序列之间的极值结果差异

Keras sequential timedistributed model extrem result differences between 2 and 3 sequences

我有 2 个模型,我在 2 个基本相同的自制数据集上训练它们。一个序列长度为 1,一个序列长度为 2。在第一种情况下,它像魅力一样收敛并实际计算出我的生成过程,在第二种情况下,它比机会好不了多少。我做错了什么?任何事情都可能有所帮助。

数据生成代码

def make_other_date(samples = 720,sequence = 1, features =100):
    y_train = np.zeros((samples,sequence, 2))
    x_train = np.random.randint(2, size=(samples, sequence, features))
    for  i_sample in range(samples):
        for i_sequence in range(sequence):

                if np.sum(x_train[i_sample,i_sequence,:]) > 50:

                    y_train[i_sample,:,:] = np.array([0,1])
                else:
                    y_train[i_sample,:,:] = np.array([1,0])


    return x_train-0.5,y_train #-0.5 to make mean = 0 

nsequence = 1
x_train, y_train = make_other_date(36000,sequence = nsequence)
x_val, y_val = make_other_date(360,sequence = nsequence)
print(x_train.shape,y_train.shape)#(36000, 1, 100) (36000, 1, 2)

型号

model = Sequential()
model.add(TimeDistributed(Dense(10), batch_input_shape=(None,nsequence,100)))
model.add(TimeDistributed(Dense(10))) #unnessacery 
model.add(TimeDistributed(Dense(2)))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam')
print (model.output_shape) #(None, 1, 2)

结果nsequence = 1

Epoch 10/10
28800/28800 [==============================] - 3s - loss: 3.4264e-05 - val_loss: 2.4744e-05

结果nsequence = 2

Epoch 10/10
28800/28800 [==============================] - 3s - loss: 0.6053 - val_loss: 0.6042

问题的表述有问题。我将尝试向您解释为什么您的示例无法运行,然后您可以根据需要制作另一个示例。

在数据部分,当您生成数据集时:

for i_sequence in range(sequence):
    if np.sum(x_train[i_sample,i_sequence,:]) > 50:
        y_train[i_sample,:,:] = np.array([0,1])
    else:
        y_train[i_sample,:,:] = np.array([1,0])

您仅根据此序列的最后一个元素为 整个序列 定义目标。 y_train[i_sample,0,:] 将被循环的最后一个操作覆盖,因为每次按顺序前进时都会更新 y_train[i_sample,:,:]

因此:整个序列只有一个目标,它仅取决于该序列的最后一个元素。

现在模型部分:

您的模型仅由 TimeDistributed(Dense()) 层组成。根据 definition,这是一个包装器,它在序列的每个元素上应用 相同的 密集层。这些密集层共享权重,因此将应用于序列的第一个元素的权重与应用于最后一个元素的权重完全相同。

现在,如果您考虑一下:要确定要应用于序列的第一个元素的目标,您的网络需要知道最后一个元素发生了什么,因为您以这种方式定义了数据集。

想象一下,你的一个序列 - 称之为 seq_i- 是

np.sum(x_train[seq_i,0,:]) = 52
np.sum(x_train[seq_i,1,:]) = 49

那么这个序列的目标是

y_train[seq_i,0] = [1,0]
y_train[seq_i,1] = [1,0]

假设如果输入小于 50,密集层能够预测目标 [1,0],就像您希望它用于序列的第二个元素一样。由于您将同一层应用于序列的第一个元素,它将预测该元素的 [0,1] 并在训练阶段为此受到惩罚。它会来回走动,不会学到任何东西。

清楚了吗?