Обработка пропущенных данных для основного убытка, который присутствует для вспомогательного убытка - PullRequest
0 голосов
/ 31 августа 2018

Я хочу построить модель 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 - только код в порядке. Я попытался изменить функцию потерь,

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) в качестве новой функции потерь, но все еще вводит NaNs .

Как мне обработать недостающие целевые данные для основного результата прогноза, где у меня есть вспомогательные целевые данные? Поможет ли маскировка ?

1 Ответ

0 голосов
/ 01 сентября 2018

В вашем вопросе вы представляете случай, когда отсутствующие данные входят в предсказуемые порции в вашем наборе данных. Если вы можете отделить отсутствующие данные и существующие данные таким образом, вы можете использовать

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 немедленно выбрасывает снова, но я подумал, что это будет более понятным способом представить необходимые изменения.

...