TFRecordsからすべての例を一度に読むにはどうしますか?
full_connected_readerの例 のメソッドtf.parse_single_example
で指定されたコードに似たコードを使用して、read_and_decode
を使用して個々の例を読み出してきました。ただし、検証データセット全体に対して一度にネットワークを実行したいので、代わりに全体をロードしたいと思います。
よくわかりませんが、 ドキュメント は、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
のエラーが発生します]
これは、すべてのレコードを一度に読み取る適切な方法ですか?もしそうなら、実際にレコードを読むために何を変更する必要がありますか?どうもありがとう!
わかりやすくするために、単一の.tfrecordsファイルに数千の画像があり、それらは720 x 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
( (fastertf.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
まだ活発なトピックであるかどうかはわかりません。私がこれまで知っているベストプラクティスを共有したいのですが、それは1年前の質問です。
テンソルフローには、このような問題に対して非常に便利な方法があります。入力データの束全体を読み取りまたは反復し、データセットをランダムにテストするためのトレーニングを生成します。 '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