ValueError:Tensor(“ optimizations:0”,shape =(4,),dtype = string)必须与Tensor(“ BatchDatasetV2_1:0”,shape =(),dtype = variant)来自同一张图

时间:2019-04-30 14:07:00

标签: python-3.x tensorflow tensorflow-datasets tf.keras

我是tensorflow的新手,并希望原型制作MNIST特征图的聚类。

我正在使用tensorflow 1.13.1 我需要使用tensorflow.data API,因为我的最终目标是使用相同的管道,但要使用更大的管道。

当前,我能够基于经过训练的keras模型生成特征图,但是我的问题是,当我想使用tf.data.Dataset.from_generator对特征图进行聚类时。似乎生成器功能无法访问keras模型图。

这是我的代码:

import tensorflow as tf
import tensorflow_datasets as tfds
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Dropout, Flatten, MaxPooling2D, InputLayer

datasets, ds_info = tfds.load(name='mnist', with_info=True, as_supervised=True)
mnist_train, mnist_test = datasets['train'], datasets['test']
mnist_train = mnist_train.batch(200)

# Creating a Sequential Model and adding the layers
model = Sequential()
# model.add(InputLayer(input_shape=(28, 28, 1), name='image'))
model.add(Conv2D(28, kernel_size=(3,3),input_shape=(28, 28, 1),name='image'))
model.add(Conv2D(28, kernel_size=(3,3)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten(name='feat_map')) # Fleature map required for clustering
model.add(Dense(128, activation=tf.nn.relu))
model.add(Dropout(0.2))
model.add(Dense(10,activation=tf.nn.softmax))

model.compile(optimizer='adam', 
          loss='sparse_categorical_crossentropy', 
          metrics=['accuracy'])

model.fit(mnist_train, steps_per_epoch=60000//200)

def dataset_generator():
    feature_network =  tf.keras.models.Model(model.input, model.get_layer('feat_map').output)
    for i in range(60000//200):
        feature_map_train = feature_network.predict(mnist_train, steps=1)
        for i in range(len(feature_map_train)):
            yield feature_map_train[i]

features_dataset = tf.data.Dataset.from_generator(dataset_generator, tf.float32, tf.TensorShape([None])).batch(200).prefetch(1)

num_steps=10

kmeans = tf.contrib.factorization.KMeansClustering(num_clusters=10, distance_metric='squared_euclidean') 

for _ in range(num_steps):
    kmeans.train(input_fn=lambda: 
features_dataset.make_one_shot_iterator().get_next())

这会发出警告

The graph (<tensorflow.python.framework.ops.Graph object at 0x7f84cd865518>) of the iterator is different from the graph (<tensorflow.python.framework.ops.Graph object at 0x7f84d3bce9e8>) the dataset: <DatasetV1Adapter shapes: ((28, 28, 1), ()), types: (tf.uint8, tf.int64)> was created in

最后是错误

ValueError: Tensor("optimizations:0", shape=(4,), dtype=string) must be from the same graph as Tensor("BatchDatasetV2_1:0", shape=(), dtype=variant).

有什么方法可以保存图形并将其导入到另一个图形中? Tensorflow: Tensor must be from the same graph as Tensor处给出的答案似乎是说input_fn必须包含火车所需的图形。我在以下代码中也尝试过此操作,但仍然收到与上述相同的警告,然后出现错误

RuntimeError: Graph is finalized and cannot be modified.

这里是所有内容都在input_fn create_features()内部的版本

def create_features():
    datasets, ds_info = tfds.load(name='mnist', with_info=True, as_supervised=True)
    mnist_train, mnist_test = datasets['train'], datasets['test']
    mnist_train = mnist_train.batch(200)

    # Creating a Sequential Model and adding the layers
    model = Sequential()
    # model.add(InputLayer(input_shape=(28, 28, 1), name='image'))
    model.add(Conv2D(28, kernel_size=(3,3),input_shape=(28, 28, 1),name='image'))
    model.add(Conv2D(28, kernel_size=(3,3)))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Flatten(name='feat_map')) # Flattening the 2D arrays for fully connected layers
    model.add(Dense(128, activation=tf.nn.relu))
    model.add(Dropout(0.2))
    model.add(Dense(10,activation=tf.nn.softmax))

    model.compile(optimizer='adam', 
              loss='sparse_categorical_crossentropy', 
              metrics=['accuracy'])

    model.fit(mnist_train, steps_per_epoch=60000//200)


    feature_network =  tf.keras.models.Model(model.input, model.get_layer('feat_map').output)

    def feature_iterator():
        for i in range(60000//200):
            feature_map_train = feature_network.predict(mnist_train, steps=1)
            for i in range(len(feature_map_train)):
                yield feature_map_train[i]

    return tf.data.Dataset.from_generator(feature_iterator, tf.float32, tf.TensorShape([None])).batch(200).prefetch(1).make_one_shot_iterator().get_next()

num_steps=10

kmeans = tf.contrib.factorization.KMeansClustering(num_clusters=10, distance_metric='squared_euclidean') 

for _ in range(num_steps):
    kmeans.train(create_features)

根据我的说法,第二种方法不太灵活,因为如果仅在聚类部分中需要进行一些调整,则不必重新训练CNN。

关于如何使用tensorflow数据集API将训练后的模型的输出进行聚类的任何建议都会很有帮助。

谢谢

0 个答案:

没有答案