Какой самый чистый и эффективный способ передать два стереоизображения в функцию потерь в Keras? - PullRequest
0 голосов
/ 13 февраля 2020

Прежде всего, почему я использую Keras? Я пытаюсь оставаться на максимально высоком уровне, но это не значит, что я боюсь низкого уровня Tensorflow; Я просто хочу увидеть, как далеко я могу go, сохраняя при этом свой код как можно более простым и читабельным.

Мне нужна моя модель Keras (специально созданная с использованием функционального API Keras), чтобы читать левое изображение с стереопара и функция минимизации потерь, которая должна получить доступ к правому и левому изображениям. Я хочу сохранить данные в tf.data.Dataset.

Что я пробовал:

  1. Чтение набора данных как (left image, right image), то есть как тензоры с формой ((W, H, 3), (W, H, 3)), затем используйте закрытие функции: определите keras_loss(left_images), который возвращает loss(y_true, y_pred), с y_true, являющимся tf.Tensor, который содержит правильное изображение. Проблема этого подхода в том, что left_images - это tf.data.Dataset, и Tensorflow жалуется (правильно), что я пытаюсь работать с набором данных вместо тензора.
  2. Чтение набора данных как (left image, (left image, right image)), что должно составить y_true a tf.Tensor с формой ((W, H, 3), (W, H, 3)), которая содержит правое и левое изображения. Проблема этого подхода в том, что он ... не работает и выдает следующую ошибку:

    ValueError: Error when checking model target: the list of Numpy arrays 
    that you are passing to your model is not the size the model expected. 
    Expected to see 1 array(s), for inputs ['tf_op_layer_resize/ResizeBilinear'] 
    but instead got the following list of 2 arrays: [<tf.Tensor 'args_1:0' 
    shape=(None, 512, 256, 3) dtype=float32>, <tf.Tensor 'args_2:0' 
    shape=(None, 512, 256, 3) dtype=float32>]...
    

Итак, есть что-то, что я не учел? Я прочитал документацию и ничего не нашел ни о том, что считается y_pred, а о y_true, ни о том, как грамотно преобразовать набор данных в тензор и не загружать все это в память.

Моя модель сконструирована так:

 def my_model(input_shape):
     width = input_shape[0]
     height = input_shape[1]
     inputs = tf.keras.Input(shape=input_shape)
     # < a few more layers >
     outputs = tf.image.resize(tf.nn.sigmoid(tf.slice(disp6, [0, 0, 0, 0], [-1, -1, -1, 2])), tf.Variable([width, height]))
     model = tf.keras.Model(inputs=inputs, outputs=outputs)
     return model

И мой набор данных построен таким образом (в случае 2, тогда как в случае 1 изменяется только функция read_stereo_pair_from_line()):

def read_img_from_file(file_name):
    img = tf.io.read_file(file_name)
    # convert the compressed string to a 3D uint8 tensor
    img = tf.image.decode_png(img, channels=3)
    # Use `convert_image_dtype` to convert to floats in the [0,1] range.
    img = tf.image.convert_image_dtype(img, tf.float32)
    # resize the image to the desired size.
    return tf.image.resize(img, [args.input_width, args.input_height])


def read_stereo_pair_from_line(line):
    split_line = tf.strings.split(line, ' ')
    return read_img_from_file(split_line[0]), (read_img_from_file(split_line[0]), read_img_from_file(split_line[1]))

# Dataset loading
list_ds = tf.data.TextLineDataset('test/files.txt')
images_ds = list_ds.map(lambda x: read_stereo_pair_from_line(x))
images_ds = images_ds.batch(1)

1 Ответ

0 голосов
/ 14 февраля 2020

решаемая. Мне просто нужно было прочитать набор данных как (left image, [left image, right image]) вместо (left image, (left image, right image)), т.е. сделать второй элемент списком, а не кортежем. Затем я могу получить доступ к изображениям как input_r = y_true[:, 1, :, :] и input_l = y_true[:, 0, :, :]

...