TensorFlow - читать все примеры из TFRecords сразу?
Как вы читаете все примеры из TFRecords одновременно?
Я использую tf.parse_single_example
читать отдельные примеры, используя код, аналогичный приведенному в методе read_and_decode
в примере полностью_connected_reader. Тем не менее, я хочу запустить сеть по всему набору данных для проверки сразу, и поэтому хотел бы загрузить их целиком.
Я не совсем уверен, но документация предлагает мне использовать tf.parse_example
вместо tf.parse_single_example
загрузить весь файл TFRecords сразу. Я не могу заставить это работать, хотя. Я предполагаю, что это связано с тем, как я определяю функции, но я не уверен, как в спецификации функции утверждать, что есть несколько примеров.
Другими словами, моя попытка использовать что-то похожее на:
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)
features = tf.parse_example(serialized_example, features={
'image_raw': tf.FixedLenFeature([], tf.string),
'label': tf.FixedLenFeature([], tf.int64),
})
не работает, и я предполагаю, что это потому, что функции не ожидают нескольких примеров одновременно (но опять же, я не уверен). [Это приводит к ошибке ValueError: Shape () must have rank 1
]
Это правильный способ прочитать все записи одновременно? И если да, что мне нужно изменить, чтобы на самом деле читать записи? Спасибо много!
7 ответов
Просто для ясности, у меня есть несколько тысяч изображений в одном файле.tfrecords, это файлы размером 720 на 720 rgb png. Метки являются одним из 0,1,2,3.
Я также попытался использовать parse_example и не смог заставить его работать, но это решение работает с parse_single_example.
Недостатком является то, что прямо сейчас я должен знать, сколько элементов в каждой записи.tf, что является своего рода обломом. Если я найду лучший способ, я обновлю ответ. Кроме того, будьте осторожны, выходя за пределы количества записей в файле.tfrecords, он начнется заново с первой записи, если вы пропустите последнюю запись
Хитрость заключалась в том, чтобы бегун очереди использовал координатора.
Я оставил здесь некоторый код, чтобы сохранить изображения во время их чтения, чтобы вы могли убедиться, что изображение правильное.
from PIL import Image
import numpy as np
import tensorflow as tf
def read_and_decode(filename_queue):
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)
features = tf.parse_single_example(
serialized_example,
# Defaults are not specified since both keys are required.
features={
'image_raw': tf.FixedLenFeature([], tf.string),
'label': tf.FixedLenFeature([], tf.int64),
'height': tf.FixedLenFeature([], tf.int64),
'width': tf.FixedLenFeature([], tf.int64),
'depth': tf.FixedLenFeature([], tf.int64)
})
image = tf.decode_raw(features['image_raw'], tf.uint8)
label = tf.cast(features['label'], tf.int32)
height = tf.cast(features['height'], tf.int32)
width = tf.cast(features['width'], tf.int32)
depth = tf.cast(features['depth'], tf.int32)
return image, label, height, width, depth
def get_all_records(FILE):
with tf.Session() as sess:
filename_queue = tf.train.string_input_producer([ FILE ])
image, label, height, width, depth = read_and_decode(filename_queue)
image = tf.reshape(image, tf.pack([height, width, 3]))
image.set_shape([720,720,3])
init_op = tf.initialize_all_variables()
sess.run(init_op)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
for i in range(2053):
example, l = sess.run([image, label])
img = Image.fromarray(example, 'RGB')
img.save( "output/" + str(i) + '-train.png')
print (example,l)
coord.request_stop()
coord.join(threads)
get_all_records('/path/to/train-0.tfrecords')
Чтобы прочитать все данные только один раз, вам нужно пройти num_epochs
к string_input_producer
, Когда все записи прочитаны, .read
Метод читателя выдаст ошибку, которую вы можете поймать. Упрощенный пример:
import tensorflow as tf
def read_and_decode(filename_queue):
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)
features = tf.parse_single_example(
serialized_example,
features={
'image_raw': tf.FixedLenFeature([], tf.string)
})
image = tf.decode_raw(features['image_raw'], tf.uint8)
return image
def get_all_records(FILE):
with tf.Session() as sess:
filename_queue = tf.train.string_input_producer([FILE], num_epochs=1)
image = read_and_decode(filename_queue)
init_op = tf.initialize_all_variables()
sess.run(init_op)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
try:
while True:
example = sess.run([image])
except tf.errors.OutOfRangeError, e:
coord.request_stop(e)
finally:
coord.request_stop()
coord.join(threads)
get_all_records('/path/to/train-0.tfrecords')
И использовать tf.parse_example
(который быстрее чем tf.parse_single_example
) вам нужно сначала пакетировать примеры следующим образом:
batch = tf.train.batch([serialized_example], num_examples, capacity=num_examples)
parsed_examples = tf.parse_example(batch, feature_spec)
К сожалению, таким образом, вам нужно знать количество примеров заранее.
Если вам нужно прочитать все данные из TFRecord одновременно, вы можете написать более простое решение всего за несколько строк кода, используя tf_record_iterator:
Итератор, который читает записи из файла TFRecords.
Для этого вам достаточно:
- создать пример
- перебирать записи из итератора
- разбирать каждую запись и читать каждую функцию в зависимости от ее типа
Вот пример с объяснением, как читать каждый тип.
example = tf.train.Example()
for record in tf.python_io.tf_record_iterator(<tfrecord_file>):
example.ParseFromString(record)
f = example.features.feature
v1 = f['int64 feature'].int64_list.value[0]
v2 = f['float feature'].float_list.value[0]
v3 = f['bytes feature'].bytes_list.value[0]
# for bytes you might want to represent them in a different way (based on what they were before saving)
# something like `np.fromstring(f['img'].bytes_list.value[0], dtype=np.uint8
# Now do something with your v1/v2/v3
Вы также можете использовать tf.python_io.tf_record_iterator
вручную повторить все примеры в TFRecord
,
Я проверяю это с помощью кода ниже:
import tensorflow as tf
X = [[1, 2],
[3, 4],
[5, 6]]
def _int_feature(value):
return tf.train.Feature(int64_list=tf.train.Int64List(value=value))
def dump_tfrecord(data, out_file):
writer = tf.python_io.TFRecordWriter(out_file)
for x in data:
example = tf.train.Example(
features=tf.train.Features(feature={
'x': _int_feature(x)
})
)
writer.write(example.SerializeToString())
writer.close()
def load_tfrecord(file_name):
features = {'x': tf.FixedLenFeature([2], tf.int64)}
data = []
for s_example in tf.python_io.tf_record_iterator(file_name):
example = tf.parse_single_example(s_example, features=features)
data.append(tf.expand_dims(example['x'], 0))
return tf.concat(0, data)
if __name__ == "__main__":
dump_tfrecord(X, 'test_tfrecord')
print('dump ok')
data = load_tfrecord('test_tfrecord')
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
Y = sess.run([data])
print(Y)
Конечно, вы должны использовать свой собственный feature
Спецификация.
Недостатком является то, что я не знаю, как использовать многопоточность таким образом. Однако чаще всего мы читаем все примеры, когда оцениваем набор данных проверки, который обычно не очень большой. Поэтому я думаю, что эффективность может быть не узким местом.
И у меня есть еще одна проблема, когда я тестирую эту проблему, это то, что я должен указать длину функции. Вместо tf.FixedLenFeature([], tf.int64)
Я должен написать tf.FixedLenFeature([2], tf.int64)
в противном случае InvalidArgumentError
произошло. Я понятия не имею, как этого избежать.
Python: 3.4
Тензор потока: 0.12.0
Я не знаю, является ли это все еще активной темой. Я хотел бы поделиться лучшей практикой, которую я знаю до сих пор, хотя это вопрос год назад.
В тензорном потоке у нас есть очень полезный метод для решения этой проблемы - читать или перебирать весь набор входных данных и генерировать обучение для тестирования набора данных случайным образом. tf.train.shuffle_batch может генерировать базу данных на входном потоке (например, reader.read()) на вашем поведении. Как, например, вы можете сгенерировать набор данных 1000, предоставив список аргументов следующим образом:
reader = tf.TFRecordReader()
_, serialized = reader.read(filename_queue)
features = tf.parse_single_example(
serialized,
features={
'label': tf.FixedLenFeature([], tf.string),
'image': tf.FixedLenFeature([], tf.string)
}
)
record_image = tf.decode_raw(features['image'], tf.uint8)
image = tf.reshape(record_image, [500, 500, 1])
label = tf.cast(features['label'], tf.string)
min_after_dequeue = 10
batch_size = 1000
capacity = min_after_dequeue + 3 * batch_size
image_batch, label_batch = tf.train.shuffle_batch(
[image, label], batch_size=batch_size, capacity=capacity, min_after_dequeue=min_after_dequeue
)
Кроме того, если вы не думаете, что tf.train.shuffle_batch - это то, что вам нужно. Вы также можете попробовать комбинацию tf.TFRecordReader(). Read_up_to() и tf.parse_example(). Вот пример для вашей справки:
def read_tfrecords(folder_name, bs):
filename_queue = tf.train.string_input_producer(tf.train.match_filenames_once(glob.glob(folder_name + "/*.tfrecords")))
reader = tf.TFRecordReader()
_, serialized = reader.read_up_to(filename_queue, bs)
features = tf.parse_example(
serialized,
features={
'label': tf.FixedLenFeature([], tf.string),
'image': tf.FixedLenFeature([], tf.string)
}
)
record_image = tf.decode_raw(features['image'], tf.uint8)
image = tf.reshape(record_image, [-1, 250, 151, 1])
label = tf.cast(features['label'], tf.string)
return image, label
1), но если у нас есть несколько файлов tfrecord, как мы зацикливаем их все и получаем все установленные нами метки (изображение, метка), а затем наносим все метки сразу?2) если у нас есть набор данных о дисбалансе из 100 классов и каждой партии 64, как мы гарантируем, что каждый раз, когда мы берем все классы, скажем, мы берем партию из 128, чтобы выбрать хотя бы один из каждого класса во время обучения?