Я новичок в 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, был бы очень полезен.
спасибо