Прежде всего, почему я использую Keras? Я пытаюсь оставаться на максимально высоком уровне, но это не значит, что я боюсь низкого уровня Tensorflow; Я просто хочу увидеть, как далеко я могу go, сохраняя при этом свой код как можно более простым и читабельным.
Мне нужна моя модель Keras (специально созданная с использованием функционального API Keras), чтобы читать левое изображение с стереопара и функция минимизации потерь, которая должна получить доступ к правому и левому изображениям. Я хочу сохранить данные в tf.data.Dataset
.
Что я пробовал:
- Чтение набора данных как
(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 жалуется (правильно), что я пытаюсь работать с набором данных вместо тензора. Чтение набора данных как (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)