我正在使用LSTM层研究一个二进制分类问题,其中我将每个时间步划分为属于(0,1)类。我有可变大小的序列。因此,我在序列末尾使用-1值填充并掩盖了这些额外的步骤。我的输入遵循形状(300,2000,8)
,所以我所有的300个样本有2000个时间步长和8个特征。如果一个样本最初有1500个时间步,那么我将在最后为8个特征中的每一个添加500个额外的步骤,值为= -1。
我为和添加了padding输入= train_x,标签= train_y,所以train_y的形状实际上是(300,2000,1)
。因此,输入向量和标签向量都用-1填充,表示要忽略的步骤。
现在,我有一些疑问,让我头疼了好几天。从我从这里理解的,每当keras"看到"所有特征值为-1的时间步长时,它将在处理中忽略它。然而,当我访问自定义损失函数y_predictions和y_labels中的张量时,y_labels中值为-1的时间步长也具有模型给出的预测(例如,值在0到1之间),该预测通常与所有-1时间步长相同。我在想我是不是做错了什么?
-
在传递给模型时,我应该只填充和掩码特征向量并保持标签向量的原始大小吗?
-
我想我最终'忽略' -1时间步长做这在损失函数的开始,然后在进行计算并返回损失值时,只使用y_true为!= -1的时间步长的索引。这有意义吗?
pos_class = tf.where(y_true > 0) neg_class = tf.where(y_true == 0) ... rest of calculations ...
模型构建部分的代码如下:
# train_x -> (300,2000,8)
# train_y -> (300,2000,1)
# both already padded and masked with -1 for the extra steps
input_layer = Input(shape=(2000, 8))
mask_1 = Masking(mask_value=-1)(input_layer)
lstm_1 = LSTM(64, return_sequences=True)(mask_1)
dense_1 = Dense(1, activation="sigmoid")(lstm_1)
model = Model(inputs=input_layer, outputs=dense_1)
model.summary()
optimizer = Adam(lr=0.001)
model.compile(optimizer=optimizer, loss=CustomLossFun, metrics=[CustomMcc(), CustomPrecision()])
train_model = model.fit(x = train_x, y = train_y, ...)
明白了这个问题的答案。
我仍然会在损失函数中得到一个与整个序列大小相同的张量。然而,被屏蔽的值只是作为填充符而没有被计算(这可能就是为什么它们是重复的相同值)。对于损失函数,我仍然需要忽略它们。