【问题标题】:keras model.fit() fed with initializable iterator of tf.Dataset objectkeras model.fit() 提供了 tf.Dataset 对象的可初始化迭代器
【发布时间】:2018-10-07 18:26:38
【问题描述】:

我正在使用 tf.keras API 构建我的 CNN 模型,并使用 tf.Dataset API 为我的模型创建输入管道。来自tf.keras.datasets的mnist数据集用于测试并通过执行代码在内存中准备:

(train_images,train_labels),(test_images,test_labels) = tf.keras.datasets.mnist.load_data()

还有一些与我的 keras 模型兼容的预处理:

Train_images = np.expand_dims(train_images,3).astype('float')/255.0
Test_images = np.expand_dims(test_images,3).astype('float')/255.0

Train_labels = tf.keras.utils.to_categorical(train_labels)
Test_labels = tf.keras.utils.to_categorical(test_labels)

这些数据以数组的形式存储在内存中,创建 Dataset 对象有两个选项。第一个是简单地使用tf.data.Dataset.from_tensor_slices

image = tf.data.Dataset.from_tensor_slices((Train_images,Train_labels))

并将这个结果对象输入到 model.fit():

model.fit(x=image,steps_per_epoch=1000)

或通过以下方式输入此数据集的迭代器:

iterator = image.make_one_shot_iterator()

model.fit(x=iterator,steps_per_epoch=1000)

这两个选项都可以正常工作,因为这里名为 image 的数据集是使用内存中的数据创建的。但是,根据这里的Importing Data,我们可能希望避免这样做,因为它会多次复制数据并占用内存。所以另一种选择是基于tf.placeholder 以及可初始化的迭代器创建这样一个数据集对象:

X = tf.placeholder(tf.float32,shape = [60000,28,28,1])
Y = tf.placeholder(tf.float32,shape = [60000,10])
image2 = tf.data.Dataset.from_tensor_slices((X,Y))
iterator2 = image.make_initializable_iterator()

with tf.Session() as sess:
  sess.run(iterator2.initializer,feed_dict={X:Train_images,Y:Train_labels}
  sess.run(iterator2.get_next())

这种迭代器在使用tf.Session() 时可以正常工作,同时在内存中提供数据并避免数据的多个副本。但我找不到让它与keras.model.fit() 一起工作的方法,因为你不能真正调用iterator.initializer 或在那里提供任何数据。有没有办法使用这种迭代器?

【问题讨论】:

    标签: python tensorflow keras


    【解决方案1】:

    我不认为 keras 正式支持传递可初始化迭代器的情况,正如您所指出的,没有地方提供占位符和值映射。

    但是可以使用keras callbacks 解决方法:

    import tensorflow as tf
    import numpy as np
    import pandas as pd
    
    # Make sure only tensorflow.keras is imported, don't mix with keras
    from tensorflow.keras import layers
    import tensorflow.keras.backend as K
    
    # example data
    x_values = np.random.randn(200, 100).astype(np.float32)
    y_labels = np.random.randint(low=0, high=9, size=200)
    
    graph = tf.Graph()
    with graph.as_default():
        # make datasets from placeholders as in https://www.tensorflow.org/guide/datasets#reading_input_data
        # X:
        features_placeholder = tf.placeholder(tf.float32, x_values.shape, name='features')
        dataset_x = tf.data.Dataset.from_tensor_slices({'x': features_placeholder})
        # Y:
        labels_placeholder = tf.placeholder(tf.float32, [None], name='labels')
        dataset_y = tf.data.Dataset.from_tensor_slices({'y': labels_placeholder})
    
        # compose datasets to make X-Y pairs for training
        dataset0 = tf.data.Dataset.zip((dataset_x, dataset_y))
        dataset0 = dataset0.batch(16).repeat()
    
        # build model with keras
        inputs = tf.keras.Input(name='x', shape=(x_values.shape[1],))
        mlp1 = layers.Dense(16, name='mlp-1', activation='relu')
        mlp1_out = mlp1(inputs)
        output = layers.Dense(1, name='y', activation='linear')
        output_out = output(mlp1_out)
        model = tf.keras.Model(inputs=inputs, outputs=output_out)
        # The compile step specifies the training configuration.
        model.compile(optimizer=tf.train.RMSPropOptimizer(0.001), loss='mse', metrics=['mse'])
    
        iterator = dataset0.make_initializable_iterator()
        feed_dict = { labels_placeholder: y_labels, features_placeholder: x_values }
    
        class InitIteratorCallback(tf.keras.callbacks.Callback):
            """
            Ensures that placeholders in dataset are initialized before each epoch begins
            """
    
            def on_epoch_begin(self, epoch, logs=None):
                sess = K.get_session()
                sess.run(iterator.initializer, feed_dict=feed_dict)
    
    
        model.fit(iterator, callbacks=[InitIteratorCallback()],
                  epochs=10, steps_per_epoch=300)
    

    【讨论】:

      猜你喜欢
      • 2019-01-08
      • 1970-01-01
      • 1970-01-01
      • 2021-12-31
      • 1970-01-01
      • 1970-01-01
      • 2013-06-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多