gpt4 book ai didi

python - 如何在 Tensorflow 2 LSTM 训练中屏蔽多输出?

转载 作者:行者123 更新时间:2023-12-03 08:47:40 27 4
gpt4 key购买 nike

我正在 Tensorflow 2 中训练 LSTM 模型来预测两个输出:水流和水温。

  • 对于某些时间步,有一个流标签温度标签,
  • 对于某些情况,只有水流标签温度标签,
  • 对于某些人来说,两者都没有

因此,当温度和流量损失没有标签时,损失函数需要忽略它们。我已经阅读了大量 TF 文档,但我正在努力弄清楚如何最好地做到这一点。

到目前为止我已经尝试过

  • 在编译模型时指定 sample_weight_mode='temporal',然后在调用 fit 时包含 sample_weight numpy 数组

当我这样做时,我收到一个错误,要求我传递一个二维数组。但这让我感到困惑,因为有 3 个维度:n_samplessequence_lengthn_outputs

这是我基本上想做的一些代码:

import tensorflow as tf
import numpy as np

# set up the model
simple_lstm_model = tf.keras.models.Sequential([
tf.keras.layers.LSTM(8, return_sequences=True),
tf.keras.layers.Dense(2)
])

simple_lstm_model.compile(optimizer='adam', loss='mae',
sample_weight_mode='temporal')

n_sample = 2
seq_len = 10
n_feat = 5
n_out = 2

# random in/out
x = np.random.randn(n_sample, seq_len, n_feat)
y_true = np.random.randn(n_sample, seq_len, n_out)

# set the initial mask as all ones (everything counts equally)
mask = np.ones([n_sample, seq_len, n_out])
# set the mask so that in the 0th sample, in the 3-8th time step
# the 1th variable is not counted in the loss function
mask[0, 3:8, 1] = 0

simple_lstm_model.fit(x, y_true, sample_weight=mask)

错误:

ValueError: Found a sample_weight array with shape (2, 10, 2). In order to use timestep-wise sample weighting, you should
pass a 2D sample_weight array.

有什么想法吗?我一定不明白 sample_weights 做了什么,因为对我来说,只有当 sample_weight 数组与输出具有相同维度时才有意义。我可以编写一个自定义损失函数并手动处理屏蔽,但似乎应该有一个更通用或内置的解决方案。

最佳答案

1。 样本权重

是的,你理解错了。在本例中,您有 2 个样本、10 个时间步长,每个时间步长具有 5 个特征。您可以像这样传递 2D 张量,因此每个样本的每个时间步对总损失的贡献不同,所有特征的权重相同(通常是这种情况)。

这根本不是你想要的。您希望在计算后屏蔽某些损失值,这样它们就不会产生影响。

2。自定义损失

一种可能的解决方案是实现您自己的损失函数,该函数在获取meansum之前将损失张量乘以掩码。

基本上,您传递以某种方式连接在一起的masktensor并将其拆分到函数中以供使用。这就足够了:

def my_loss_function(y_true_mask, y_pred):
# Recover y and mask
y_true, mask = tf.split(y_true_mask, 2)
# You could user reduce_sum or other combinations
return tf.math.reduce_mean(tf.math.abs(y_true - y_pred) * mask)

现在你的代码(没有加权,因为不需要):

simple_lstm_model = tf.keras.models.Sequential(
[tf.keras.layers.LSTM(8, return_sequences=True), tf.keras.layers.Dense(2)]
)

simple_lstm_model.compile(optimizer="adam", loss=my_loss_function)

n_sample = 2
seq_len = 10
n_feat = 5
n_out = 2

x = np.random.randn(n_sample, seq_len, n_feat)
y_true = np.random.randn(n_sample, seq_len, n_out)

mask = np.ones([n_sample, seq_len, n_out])
mask[0, 3:8, 1] = 0

# Stack y and mask together
y_true_mask = np.stack([y_true, mask])

simple_lstm_model.fit(x, y_true_mask)

所以它有效。您还可以以其他方式堆叠这些值,但我希望您能感受到如何做到这一点。

3。屏蔽输出

请注意上面介绍的一些问题。如果你有很多零并取平均值,你可能会得到一个非常小的损失值并抑制学习。另一方面,如果您使用 sum 它可能会爆炸。

关于python - 如何在 Tensorflow 2 LSTM 训练中屏蔽多输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60728883/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com