如何:忽略 NA 值(或以其他方式掩盖损失)的 TensorFlow-Probability 自定义损失
How to: TensorFlow-Probability custom loss that ignores NA values (or otherwise masks loss)
我寻求在 TensorFlow-Probability 中实现一个屏蔽损失函数,它可以忽略标签中的 NA。
对于常规张量来说,这是一项老掉牙的任务。我找不到分发示例。
我的分布大小(批次、时间步长、输出)(512、251 天,1 到 8 个时间序列)
示例中给出的传统损失函数是使用分布的对数概率。
neg_log_likelihood <- function (x, rv_x) {
-1*(rv_x %>% tfd_log_prob(x))
}
当我用零替换 NA 时,模型训练良好并收敛。当我离开 NA 时,它会按预期产生 NaN 损失。
我已经尝试了 tf$where 的许多不同排列,以用 0 替换损失,用 0 替换标签,等等。在每一种情况下,模型都会停止训练并且损失保持在某个常数附近。即使标签中只有一个 NA 也是如此。
neg_log_likelihood_missing <- function (x, rv_x) {
loss = -1*( rv_x %>% tfd_log_prob(x) )
loss_nonan = tf$where( tf$math$is_finite(x) , loss, 0 )
return(
loss_nonan
)
}
我在这里使用 R 是偶然的,python 中的任何示例或其他我都可以翻译。如果有正确的方法可以使损失正确反向传播,我将不胜感激。
如果您使用的是基于梯度的推理,您可能需要“双重位置”技巧。
虽然这会为您提供正确的 y
值:
y = computation(x)
tf.where(is_nan(y), 0, y)
...tf.where
的导数仍然可以有 nan
.
改为:
safe_x = tf.where(is_unsafe(x), some_safe_x, x)
y = computation(safe_x)
tf.where(is_unsafe(x), 0, y)
...得到一个保险箱 y
和一个保险箱 dy/dx
.
对于你正在考虑的情况,也许写:
class MyMaskedDist(tfd.Distribution):
...
def _log_prob(self, x):
safe_x = tf.where(tf.is_nan(x), self.mode(), x)
lp = compute_log_prob(safe_x)
lp = tf.where(tf.is_nan(x), tf.zeros([], lp.dtype), lp)
return lp
我寻求在 TensorFlow-Probability 中实现一个屏蔽损失函数,它可以忽略标签中的 NA。
对于常规张量来说,这是一项老掉牙的任务。我找不到分发示例。
我的分布大小(批次、时间步长、输出)(512、251 天,1 到 8 个时间序列)
示例中给出的传统损失函数是使用分布的对数概率。
neg_log_likelihood <- function (x, rv_x) {
-1*(rv_x %>% tfd_log_prob(x))
}
当我用零替换 NA 时,模型训练良好并收敛。当我离开 NA 时,它会按预期产生 NaN 损失。
我已经尝试了 tf$where 的许多不同排列,以用 0 替换损失,用 0 替换标签,等等。在每一种情况下,模型都会停止训练并且损失保持在某个常数附近。即使标签中只有一个 NA 也是如此。
neg_log_likelihood_missing <- function (x, rv_x) {
loss = -1*( rv_x %>% tfd_log_prob(x) )
loss_nonan = tf$where( tf$math$is_finite(x) , loss, 0 )
return(
loss_nonan
)
}
我在这里使用 R 是偶然的,python 中的任何示例或其他我都可以翻译。如果有正确的方法可以使损失正确反向传播,我将不胜感激。
如果您使用的是基于梯度的推理,您可能需要“双重位置”技巧。
虽然这会为您提供正确的 y
值:
y = computation(x)
tf.where(is_nan(y), 0, y)
...tf.where
的导数仍然可以有 nan
.
改为:
safe_x = tf.where(is_unsafe(x), some_safe_x, x)
y = computation(safe_x)
tf.where(is_unsafe(x), 0, y)
...得到一个保险箱 y
和一个保险箱 dy/dx
.
对于你正在考虑的情况,也许写:
class MyMaskedDist(tfd.Distribution):
...
def _log_prob(self, x):
safe_x = tf.where(tf.is_nan(x), self.mode(), x)
lp = compute_log_prob(safe_x)
lp = tf.where(tf.is_nan(x), tf.zeros([], lp.dtype), lp)
return lp