ValueError: Tensor («оптимизации: 0», shape = (4,), dtype = string) должны быть из того же графика, что и Tensor («BatchDatasetV2_1: 0», shape = (), dtype = вариант) - PullRequest
0 голосов
/ 30 апреля 2019

Я новичок в tenorflow и хотел бы создать прототип кластеризации карты объектов MNIST.

Я использую tenorflow 1.13.1 Мне нужно использовать API tenorflow.data, потому что моя конечная цель - использовать тот же конвейер, но для гораздо большего набора.

В настоящее время я могу сгенерировать карту объектов на основе обученной модели керас, но моя проблема заключается в том, что я хочу кластеризовать карту объектов с помощью 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 должен быть из того же графика, что и 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, если некоторые изменения необходимы только в части кластеризации.

Любой совет о том, как кластеризовать выходные данные обученной модели с использованием API набора данных tenorflow, был бы очень полезен.

спасибо

...