#python #tensorflow #tfrecord
#python #тензорный поток #tfrecord
Вопрос:
Я надеюсь получить разъяснения о том, как shuffle
tf.data.Dataset.list_files()
работает аргумент in . В документации указано, что при shuffle=True
этом имена файлов будут перемешиваться случайным образом. Я сделал прогнозы модели, используя набор данных tfrecords, который был загружен с использованием tf.data.Dataset.list_files()
, и я бы ожидал, что показатель точности будет одинаковым независимо от порядка файлов (т. Е. Является ли shuffle True или False), но я вижу иначе.
Это ожидаемое поведение или что-то не так с моим кодом или интерпретацией? У меня есть воспроизводимый пример кода ниже.
Как ни странно, до тех пор, пока tf.random.set_random_seed()
задано изначально (и, похоже, даже не имеет значения, какое начальное значение установлено), результаты предсказаний будут одинаковыми, независимо от того, имеет ли значение shuffle значение True или False list_files()
.
tensorflow== 1.13.1, keras==2.2.4
Спасибо за любые разъяснения!
Редактировать: переосмысливая это и задаваясь вопросом, является ли Y = [y[0] for _ in range(steps) for y in sess.run(Y)]
это отдельным и независимым вызовом?
# Fit and Save a Dummy Model
import numpy as np
import tensorflow as tf
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import np_utils
from sklearn import datasets, metrics
seed = 7
np.random.seed(seed)
tf.random.set_random_seed(seed)
dataset = datasets.load_iris()
X = dataset.data
Y = dataset.target
dummy_Y = np_utils.to_categorical(Y)
# 150 rows
print(len(X))
model = Sequential()
model.add(Dense(8, input_dim=4, activation='relu'))
model.add(Dense(3, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X, dummy_Y, epochs=10, batch_size=10, verbose=2)
model.save('./iris/iris_model')
predictions = model.predict(X)
predictions = np.argmax(predictions, axis=1)
# returns accuracy = 0.3466666666666667
print(metrics.accuracy_score(y_true=Y, y_pred=predictions))
Разделите набор данных на несколько файлов tfrecords, чтобы мы могли перезагрузить его с помощью list_files() позже:
numrows = 15
for i, j in enumerate(range(0, len(X), numrows)):
with tf.python_io.TFRecordWriter('./iris/iris{}.tfrecord'.format(i)) as writer:
for x, y in zip(X[j:j numrows, ], Y[j:j numrows, ]):
features = tf.train.Features(feature=
{'X': tf.train.Feature(float_list=tf.train.FloatList(value=x)),
'Y': tf.train.Feature(int64_list=tf.train.Int64List(value=[y]))
})
example = tf.train.Example(features=features)
writer.write(example.SerializeToString())
На этом этапе я выхожу (ipython) и перезапускаю снова:
import numpy as np
import tensorflow as tf
from keras.models import load_model
from sklearn import metrics
model = load_model('./iris/iris_model')
batch_size = 10
steps = int(150/batch_size)
file_pattern = './iris/iris*.tfrecord'
feature_description = {
'X': tf.FixedLenFeature([4], tf.float32),
'Y': tf.FixedLenFeature([1], tf.int64)
}
def _parse_function(example_proto):
return tf.parse_single_example(example_proto, feature_description)
def load_data(filenames, batch_size):
raw_dataset = tf.data.TFRecordDataset(filenames)
dataset = raw_dataset.map(_parse_function)
dataset = dataset.batch(batch_size, drop_remainder=True)
dataset = dataset.prefetch(2)
iterator = dataset.make_one_shot_iterator()
record = iterator.get_next()
return record['X'], record['Y']
def get_predictions_accuracy(filenames):
X, Y = load_data(filenames=filenames, batch_size=batch_size)
predictions = model.predict([X], steps=steps)
predictions = np.argmax(predictions, axis=1)
print(len(predictions))
with tf.Session() as sess:
Y = [y[0] for _ in range(steps) for y in sess.run(Y)]
print(metrics.accuracy_score(y_true=Y, y_pred=predictions))
# No shuffle results:
# Returns expected accuracy = 0.3466666666666667
filenames_noshuffle = tf.data.Dataset.list_files(file_pattern=file_pattern, shuffle=False)
get_predictions_accuracy(filenames_noshuffle)
# Shuffle results, no seed value set:
# Returns UNEXPECTED accuracy (non-deterministic value)
filenames_shuffle_noseed = tf.data.Dataset.list_files(file_pattern=file_pattern, shuffle=True)
get_predictions_accuracy(filenames_shuffle_noseed)
# Shuffle results, seed value set:
# Returns expected accuracy = 0.3466666666666667
# It seems like it doesn't even matter what seed value you set, as long as you you set it
seed = 1000
tf.random.set_random_seed(seed)
filenames_shuffle_seed = tf.data.Dataset.list_files(file_pattern=file_pattern, shuffle=True)
get_predictions_accuracy(filenames_shuffle_seed)
Комментарии:
1. Смог ответить на мой собственный вопрос — на самом деле это было связано с
Y = [y[0] for _ in range(steps) for y in sess.run(Y)]
тем, что это был отдельный и независимый вызов