Tensorflow 1.10+: переход эпохи к оценщику input_fn?

Подпись tf.estimator input_fn может выглядеть примерно так:

def input_fn(files:list, params:dict):
    dataset = tf.data.TFRecordDataset(files)
                .map(lambda record: parse_record_fn(record))

    if params['mode'] == 'train':
        # train specific things
    # ...

Такое определение позволяет построить все свои input_fn следующим образом:

train_fn = lambda: input_fn(files['training_set'], {**params, **{"mode": "train"}})
valid_fn = lambda: input_fn(files['validation_set'], {**params, **{"mode": "eval"}})
test_fn  = lambda: input_fn(files['test_set'],  {**params, **{"mode": "test"}})


train_spec = tf.estimator.TrainSpec(input_fn=train_fn, ...)
eval_spec  = tf.estimator.EvalSpec(input_fn=valid_fn,  ...)  

Мой вопрос заключается в том, как можно изменить подпись input_fn, чтобы учесть вариации на основе эпох. Я понимаю, что это может создать узкое место, но было бы неплохо, если бы я мог сделать что-то вроде:


def input_fn(...):
    # see above

    epoch = params["epoch"]
    if epoch % 100 == 0:
        # modify or make a new dataset

    # ...
    return dataset.make_one_shot_iterator().get_next()

Ключ в том, чтобы убедиться, что input_fn по-прежнему совместим с:

tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)

person SumNeuron    schedule 14.06.2019    source источник


Ответы (1)


Я не знаю ни одной опции, которая предоставляет число epoch в качестве параметра как такового.

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

Например, если у меня есть 2 набора данных: ds1 и ds2 говорят и хотят использовать ds1 всякий раз, когда число «эпохи» не делится на 100, я могу просто создать новый набор данных, выполнив что-то вроде:

dataset = ds1.repeat(99).concatenate(ds2)

поскольку наборы данных по умолчанию загружаются лениво, мне не нужно беспокоиться о последствиях для памяти (я не загружаю в память в 100 раз больше данных).

Очевидно, что это влияет на размер набора данных, поэтому вам нужно подумать о стратегии шагов между eval ops/обратными вызовами и т. д., но это должно быть достаточно легко настроить.

person Stewart_R    schedule 14.06.2019
comment
Спасибо за ваш ответ. К сожалению, это не совсем работает в моем случае. Моя функция ввода имеет некоторую требуемую обработку для каждой обработки, которая происходит во время выполнения. Таким образом, данные загружаются, каждые n эпох к данным применяется некоторая случайность, затем данные изменяются на основе этого, а затем возвращаются (features, labels) кортежи / dataset. Это необходимо, потому что расчет всего этого заранее требует слишком больших затрат. - person SumNeuron; 14.06.2019