Как я могу передать входные / выходные изображения в Tensorboard, используя метод Keras model.fit () для обучения модели? - PullRequest
2 голосов
/ 20 февраля 2020

Я недавно переключился с Tensorflow 1.14 и Estimaror API на Tensorflow 2.0 и keras API. Я работаю над проблемой сегментации изображений, поэтому все входные / выходные данные / метки являются изображениями. Когда я использовал Estimator, все было довольно просто. В model_fn, где аргументы были (функции, метки, режим, параметры), я мог просто выбрать функции и метки, выполнить необходимую обработку и затем передать ее в tf.summary.image (), и все работало как чудо. Теперь, используя API-интерфейс keras, хотя он обеспечивает большую простоту использования, он усложняет простую обработку данных во время обучения, что становится еще сложнее при использовании его с набором данных API. Пример: Tensorflow 1.14 / Estimator:

def model_fn(features, labels, mode, params): 
    loss, train_op, = None, None
    eval_metric_ops, training_hooks, evaluation_hooks = None, None, None
    output = model(input=features)
    predictions = tf.argmax(output, axis=-1)
    predictions_dict = {'predicted': predictions}
    dice_score = tf.contrib.metrics.f1_score(labels=label, predictions=predictions[:, :, :, 1])
    if mode in (estimator.ModeKeys.TRAIN, estimator.ModeKeys.EVAL):
        global_step = tf.train.get_or_create_global_step()
        learning_rate = tf.train.exponential_decay(params['lr'], global_step=global_step,
                                                   decay_steps=params['decay_steps'],
                                                   decay_rate=params['decay_rate'], staircase=False)
        loss = loss_fn(outputs=predictions, labels=labels)
        summary.image('Input_Image', features)
        summary.image('Label', tf.expand_dims(tf.cast(label, dtype=tf.float32), axis=-1))
        summary.image('Prediction', tf.expand_dims(tf.cast(predictions, dtype=tf.float32), axis=-1))
    if mode == estimator.ModeKeys.TRAIN:
        with tf.name_scope('Metrics'):
            summary.scalar('Dice_Coefficient', dice_score[1])
            summary.scalar('Learning_Rate', learning_rate)
        summary.merge_all()
        train_logs_hook = tf.estimator.LoggingTensorHook({'Dice_Coefficient': dice_score[1]},every_n_iter=params['train_log_every_n_steps'])                                                  every_n_iter=params['train_log_every_n_steps'])
        training_hooks = [train_logs_hook]
        train_op = Adam(learning_rate=learning_rate, epsilon=params['epsilon']).minimize(loss=loss, global_step=global_step)
    if mode == estimator.ModeKeys.EVAL:
        eval_metric_ops = {'Metrics/Dice_Coefficient': dice_score}
        eval_summary_hook = tf.estimator.SummarySaverHook(output_dir=params['eval_metrics_path'],
                                                          summary_op=summary.merge_all(),
                                                          save_steps=params['eval_steps_per_summary_save'])
        evaluation_hooks = [eval_summary_hook]
    return estimator.EstimatorSpec(mode,
                                   predictions=predictions_dict,
                                   loss=loss,
                                   train_op=train_op,
                                   eval_metric_ops=eval_metric_ops,
                                   training_hooks=training_hooks,
                                   evaluation_hooks=evaluation_hooks)

Используя Keras с Tensorflow 2.0 AFAIK, у меня не может быть такого доступа к тензорам ввода / вывода во время обучения или оценки (обратите внимание, что хотя во время оценки оценщик не получает сводки изображений, вы все равно можете получить доступ для предварительного просмотра результатов с помощью tf.estimator.SummarySaverHook). Ниже моя ложная попытка:

   def train_data(params):  # Similar is the eval_data
       def standardization_sumamries(image, label, step, writer):
           # Some processing to images
           with writer.as_default():
               tf.summary.image('Input_dataset', image, step=step, max_outputs=1)
               tf.summary.image('label_dataset', label, step=step, max_outputs=1)
           return image, label
       data_set = tf.data.Dataset.from_generator(generator=lambda: data_generator(params),
                                              output_types=(tf.float32, tf.int64),
                                              output_shapes=(tf.TensorShape([None, None]), tf.TensorShape([None, None])))
       data_set = data_set.map(lambda x, y: standardization_sumamries(image=x, label=y, step=params['global_step'], writer=params['writer']))
       data_set = data_set.batch(params['batch_size'])
       data_set = data_set.prefetch(buffer_size=-1)
       return data_set

    model = tf.keras.models.load_model(saved_model)
    summary_writer = tf.summary.create_file_writer(save_model_path)
    step = tf.Variable(0, trainable=False, dtype=tf.int64)
    tensorboard = tf.keras.callbacks.TensorBoard(log_dir=save_model_path, histogram_freq=1, write_graph=True,
                                                 write_images=False)
    early_stop = tf.keras.callbacks.EarlyStopping(patience=args.early_stop)
    callbacks = [tensorboard, early_stop]
    params = {'batch_size': args.batch_size,
                       'global_step': step,
                       'writer': summary_writer}

    model.fit(x=train_data(params), epochs=args.epochs, initial_epoch=args.initial_epoch,
              validation_data=val_data(params), steps_per_epoch=2, callbacks=callbacks)

Получение входных изображений из API набора данных получено из здесь , но это просто получает тонны изображений всякий раз, когда набор данных получает данные из генератора. Кроме того, переменная step постоянна и не меняется (я не могу понять, как заставить ее работать), все находится под шагом 0, и я не могу придумать какой-либо жизнеспособный способ соединить эти выходы с прогнозируемым выходом. , учитывая, что я найду способ напечатать их. Итак, вопрос заключается в следующем: есть ли что-то, чего мне до сих пор не хватает в синергии Keras API и Tensorboard по кратким изображениям. Есть ли способ сохранения кратких изображений, скажем, для каждой половины периода обучения и один раз в конце оценки, или я должен просто позволить модели обучаться и получать результаты обучения через model.predict () в конце обучения и затем проверить, если что-то идет не так (что не эффективно)?

...