TensorFlow: почему значение моего монитора обратных вызовов Keras недоступно? - PullRequest
0 голосов
/ 27 мая 2019

Я использую TensorFlow 1.12. Я пытаюсь подобрать модель, используя обратные вызовы Keras:

checkpoint_full = tf.keras.callbacks.ModelCheckpoint(filepath='model/dir/model.{epoch:02d}.hdf5', monitor='val_dice_loss', save_best_only=True, mode="min")
tensorboard = tf.keras.callbacks.TensorBoard(log_dir='/media/nfs/7_raid/ebos/models/fcn/logs/', write_graph=False)
history = model.fit(train,
                    steps_per_epoch=int(np.ceil(num_samples / float(BATCH_SIZE))),
                    epochs=NUM_EPOCHS,
                    validation_data=val,
                    verbose=0,
                    callbacks=[checkpoint_full, tensorboard])

Однако выдается следующая ошибка:

WARNING:tensorflow:Can save best model only with val_dice_loss available, skipping.

Во-первых, я не понимаю, как разрешается строка, заданная для monitor. Я следую двум руководствам по Keras ( 1 , 2 ), и оба предоставляют имена строк, на которые нет ссылок нигде в их коде. Я предполагаю, что они указывают строки, которые пользователь может впоследствии использовать для получения информации о динамике производительности после обучения, а не указывают, какой показатель fit должен отслеживать? Если да, то почему это говорит о том, что значение недоступно?

Во-вторых, ответы на подобные вопросы указывают на то, что проблема заключается в отсутствии данных проверки. Тем не менее, я почти уверен, что предоставляю данные fit, о чем свидетельствует циклический просмотр val и подсчет количества записей. Что я делаю не так?

Для справки, мои наборы данных генерируются так:

def train_sample_fetcher():
    return sample_fetcher()

def val_sample_fetcher():
    return sample_fetcher(is_validations=True)

def sample_fetcher(is_validations=False):
    sample_names = [filename[:-4] for filename in os.listdir(DIR_DATASET + "ndarrays/")]
    if not is_validations: sample_names = sample_names[:int(len(sample_names) * TRAIN_VAL_SPLIT)]
    else: sample_names = sample_names[int(len(sample_names) * TRAIN_VAL_SPLIT):]
    for sample_name in sample_names:
        rgb = tf.image.decode_jpeg(tf.read_file(DIR_DATASET + sample_name + ".jpg"))
        rgb = tf.image.resize_images(rgb, (HEIGHT, WIDTH))
        #d = tf.image.decode_jpeg(tf.read_file(DIR_DATASET + "depth/" + sample_name + ".jpg"))
        #d = tf.image.resize_images(d, (HEIGHT, WIDTH))
        #rgbd = tf.concat([rgb,d], axis=2)
        onehots = tf.convert_to_tensor(np.load(DIR_DATASET + "ndarrays/" + sample_name + ".npy"), dtype=tf.float32)
        yield rgb, onehots

train = tf.data.Dataset.from_generator(generator=train_sample_fetcher, output_types=(tf.uint8, tf.uint8))
#train = train.repeat()
train = train.batch(BATCH_SIZE)
#train = train.shuffle(10)
val = tf.data.Dataset.from_generator(generator=val_sample_fetcher, output_types=(tf.uint8, tf.uint8))

Моя функция потерь выглядит следующим образом:

def dice_loss(y_true, y_pred):
    smooth = 1.
    y_true_f = tf.reshape(y_true, [-1]) # Flatten
    y_pred_f = tf.reshape(y_pred, [-1]) # Flatten
    intersection = tf.reduce_sum(y_true_f * y_pred_f)
    dice_coefficient = (2. * intersection + smooth) / (tf.reduce_sum(y_true_f) + tf.reduce_sum(y_pred_f) + smooth)
    loss = 1 - dice_coefficient
    return loss

Я выполняю семантическую сегментацию, и потеря костей рассчитывается на пиксель.

1 Ответ

1 голос
/ 28 мая 2019

Монитор 'val_loss', поскольку ваша функция потери уже установлена ​​на вашу пользовательскую функцию потери кости.

Параметр monitor ожидает метрику.'loss' всегда доступен, и если у вас есть данные проверки, то также 'val_loss'.Некоторые люди любят использовать 'accuracy' и подтверждение для этого.Если бы у вас была пользовательская функция метрики, например, чувствительность, называемая (например) sensitivity_deluxe(), вы могли бы включить sensitivity_deluxe в массив метрик в compile(), и она была бы доступна для любых обратных вызовов, ссылающихся на нее в их поле monitor.,Каждый раз, когда у вас есть данные проверки, вы можете добавить префикс строки метрики к значению 'val _'.

Пример:

model.compile(loss=my_loss_function(), optimizer='Adam', metrics=[sensitivity_deluxe])
reduce_lr = ReduceLROnPlateau(monitor='val_loss', patience=3, mode='min')
earlystop = EarlyStopping(monitor='val_sensitivity_deluxe', patience=5, mode='max')
model.fit(X, y, validation_split=0.5, callbacks=[earlystop, reduce_lr])

Я не могу ответить на ваш второй вопрос относительно проверки, не увидев ваш fit(), но похоже, что вы, вероятно, в порядке, поскольку вы настроили отдельные генераторы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...