【问题标题】:Handling missing data for the main loss, which is present for auxiliary loss处理主要损失的缺失数据,辅助损失存在
【发布时间】:2019-02-05 22:47:24
【问题描述】:

我想为具有主要目标和辅助目标的数据集构建 Keras 模型。我的数据集中所有条目都有辅助目标的数据,但对于主要目标,我只有所有数据点的子集的数据。考虑以下示例,它应该可以预测

max(min(x1, x2), x3)

但对于某些值,它只给出了我的辅助目标,min(x1, x2)

from keras.models import Model
from keras.optimizers import Adadelta
from keras.losses import mean_squared_error
from keras.layers import Input, Dense

import tensorflow as tf
import numpy

input = Input(shape=(3,))

hidden = Dense(2)(input)
min_pred = Dense(1)(hidden)
max_min_pred = Dense(1)(hidden)

model = Model(inputs=[input],
              outputs=[min_pred, max_min_pred])

model.compile(
    optimizer=Adadelta(),
    loss=mean_squared_error,
    loss_weights=[0.2, 1.0])

def random_values(n, missing=False):
    for i in range(n):
        x = numpy.random.random(size=(4, 3))
        _min = numpy.minimum(x[..., 0], x[..., 1])
        if missing:
            _max_min = numpy.full((len(x), 1), numpy.nan)
        else:
            _max_min = numpy.maximum(_min, x[..., 2]).reshape((-1, 1))
        yield x, [numpy.array(_min).reshape((-1, 1)), numpy.array(_max_min)]

model.fit_generator(random_values(50, False),
                    steps_per_epoch=50)
model.fit_generator(random_values(5, True),
                    steps_per_epoch=5)
model.fit_generator(random_values(50, False),
                    steps_per_epoch=50)

显然,上面的代码不起作用——目标为 NaN 意味着损失 NaN,这意味着 NaN 的权重适应,因此权重变为 NaN,模型变得无用。 (另外,实例化整个 NaN 数组很浪费,但原则上我丢失的数据可以是任何有数据的批次的一部分,所以为了拥有同质数组,这似乎是合理的。)

我的代码不必与所有keras 后端一起使用,tensorflow-only 代码就可以了。我试过改变损失函数,

def loss_0_where_nan(loss_function):
    def filtered_loss_function(y_true, y_pred):
        with_nans = loss_function(y_true, y_pred)
        nans = tf.is_nan(with_nans)
        return tf.where(nans, tf.zeros_like(with_nans), with_nans)
    return filtered_loss_function

并使用loss_0_where_nan(mean_squared_error) 作为新的损失函数,但it still introduces NaNs

对于有辅助目标数据的主要预测输出,我应该如何处理缺失的目标数据? masking 有帮助吗?

【问题讨论】:

    标签: python keras missing-data


    【解决方案1】:

    在您的问题中,您提出了缺失数据出现在数据集中可预测块中的情况。如果您可以像这样分离出丢失的数据和现有数据,则可以使用

    truncated_model = Model(inputs=[input],
                            outputs=[min_pred])
    
    truncated_model.compile(
        optimizer=Adadelta(),
        loss=[mean_squared_error])
    

    定义一个与你的完整模型共享一些层的模型,然后替换

    model.fit_generator(random_values(5, True),
                        steps_per_epoch=5)
    

    def partial_data(entry):
       x, (y0, y1) = entry
       return x, y0
    
    truncated_model.fit_generator(map(partial_data, random_values(5, True)),
                                  steps_per_epoch=5)
    

    在非缺失数据上训练截断模型。

    鉴于对输入数据提供者的这种控制级别,您显然可以调整您的 random_values 方法,使其甚至不会生成 partial_data 立即再次丢弃的数据,但我认为这将是更清晰的方法提出必要的更改。

    【讨论】:

      猜你喜欢
      • 2019-09-23
      • 2017-02-12
      • 1970-01-01
      • 1970-01-01
      • 2021-07-18
      • 2019-04-11
      • 2018-08-30
      • 1970-01-01
      • 2017-03-14
      相关资源
      最近更新 更多