将多个输入从 tf.dataset API 传递给 keras 模型?

W. *_*am 8 keras

我的 Keras 模型有两个输入和三个输出。我的 tfrecords 文件有一对图像和一对标签。如果我使用fit_generator,它会正常工作。在其中我创建了自己的生成器,为两个模型输入提供两个图像,三个标签提供三个模型输出。但我想用model.fit. 在其中我可以直接传递数据集实例。所以任何人都知道如何将 (x1, x2(, (y1, y2, y3) 的元组传递给 Keras 模型 vi tf.dataset API。

我之前用过的:

def _parse_function_all(example_proto):

  features = {'image_raw1': tf.FixedLenFeature([], tf.string),
      'image_raw2': tf.FixedLenFeature([], tf.string),
      'label1': tf.FixedLenFeature([], tf.int64),
      'label2': tf.FixedLenFeature([], tf.int64),
      'label3': tf.FixedLenFeature([], tf.int64),

      }


      features = tf.parse_single_example(example_proto, features)
      image1 = tf.decode_raw(features['image_raw1'], tf.uint8)
      image2 = tf.decode_raw(features['image_raw2'], tf.uint8)

      image1.set_shape([  224 * 224 * 3])
      image2.set_shape([  224 * 224 * 3])

      image1= tf.reshape(image1, (  224 , 224 , 3))
      image2 = tf.reshape(image2, (224 , 224 , 3))

      label1 = tf.cast(features['label1'], tf.int32)
      label2 = tf.cast(features['label2'], tf.int32)
      label3 = tf.cast(features['label3'], tf.int32)

      image_pair = tf.stack([image1, image2], 0)

      label_pair = tf.stack([label1, label2, label3], 0)

  return image_pair, label_pair


 def data_gen(  sess=None):

    dataset = tf.data.TFRecordDataset(val_files, num_parallel_reads=8)  

    dataset = dataset(tf.contrib.data.shuffle_and_repeat(buffer_size=4 * batch_size))


    dataset = dataset(_parse_function_all, num_parallel_calls=4) 
    dataset = dataset.batch(batch_size)

    dataset_val = dataset_val.prefetch(tf.contrib.data.AUTOTUNE)

    iterator = dataset.make_initializable_iterator()
    next_element = iterator.get_next()

    sess.run(iterator.initializer)
    while True:
        try:
            next_val = sess.run(next_element)
            images = np.array(next_val[0])
            labels = np.array(next_val[1])

            y_true1 = one_hot(labels[:, 0], num_classes=num_classes)
            y_true2 = one_hot(labels[:, 1], num_classes=num_classes)
            y_true_3 = labels[:, 2]


            yield ({'input_1': images[:,0], 'input_2': images[:,1]}, {'out_1': y_true1,'out_2': y_true2, 'concatenate':y_true_3 })
        except tf.errors.OutOfRangeError:

          break

model.fit_generator(generator = data_gen(sess)) 
Run Code Online (Sandbox Code Playgroud)

我想用什么

def _parse_function_all(example_proto):

  features = {'image_raw1': tf.FixedLenFeature([], tf.string),
      'image_raw2': tf.FixedLenFeature([], tf.string),
      'label1': tf.FixedLenFeature([], tf.int64),
      'label2': tf.FixedLenFeature([], tf.int64),
      'label3': tf.FixedLenFeature([], tf.int64),
      }

      features = tf.parse_single_example(example_proto, features)
      image1 = tf.decode_raw(features['image_raw1'], tf.uint8)
      image2 = tf.decode_raw(features['image_raw2'], tf.uint8)

      image1.set_shape([  224 * 224 * 3])
      image2.set_shape([  224 * 224 * 3])

      image1= tf.reshape(image1, (  224 , 224 , 3))
      image2 = tf.reshape(image2, (224 , 224 , 3))

      label1 = tf.cast(features['label1'], tf.int32)
      label2 = tf.cast(features['label2'], tf.int32)
      label3 = tf.cast(features['label3'], tf.int32)

      image_pair = tf.stack([image1, image2], 0)

      label_pair = tf.stack([label1, label2, label3], 0)

  return ((image1, image2), (label1, label2, label3))  # it gave error in this line. because it is wrong way. 

    dataset = tf.data.TFRecordDataset(val_files, num_parallel_reads=8)  
    dataset = dataset(tf.contrib.data.shuffle_and_repeat(buffer_size=4 * batch_size))
    dataset = dataset(_parse_function_all, num_parallel_calls=4) 
    dataset = dataset.batch(batch_size)
    dataset_val = dataset_val.prefetch(tf.contrib.data.AUTOTUNE)

    model.fit(dataset_val)
Run Code Online (Sandbox Code Playgroud)

那么是否有任何解决方案可以将(图像,标签)的元组传递给具有多个输入的 Keras 模型?

W. *_*am 1

在新版本的 TensorFlow(1.14 及更高版本)中,tf.keras 允许我将多个实例传递给 model.fit。