初めに
- 転職して約1ヶ月経過1
- 仕事でバリバリ TensorFlow 活用中
- ↑にともなって月の前半は TF(再)勉強
- その成果の紹介
- 主にデータ収集・読込回りの情報共有
- あとQiitaスライドモードのテストも兼
tf.train.batchXXX()
- 指定したバッチサイズのミニバッチをどんどん生成してくれる「データプロバイダ」を生成する関数
- 内部でキューを利用して、先読み・送出する仕組み
- 複数のデータを同時(同期)的に送出可能(画像とラベルとか)
- 参照:Batching at the end of an input pipeline
サンプル
# データ・ラベルの定義
data = tf.random_uniform([2], -1, 1)
label = tf.cast(tf.reduce_prod(data)>=0, tf.float32)
# バッチデータプロデューサ(バッチサイズ:1000)
X_batch, Y_batch = tf.train.batch(
[data, label], batch_size=1000)
# セッション開始
with tf.Session() as sess:
# 入力 enqueue スレッド開始
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(
sess=sess, coord=coord)
try:
# ミニバッチ処理ループ
while not coord.should_stop():
XData, YData = sess.run([X_batch, Y_batch])
# 学習等の処理
finally:
coord.request_stop()
coord.join(threads)
tf.XxxReader
- ファイルからデータを読み込むキューを生成するクラス
-
reader.read()
メソッドにファイル名(のキュー)を渡すことで、ファイルの内容(の一部(を表す tensor))が得られる - ファイル(やレコード)の種類によって各種のクラスが用意されている
- 参照:Readers
サンプル
sample.csv からデータを読み込んで処理する例
# CSV ファイル名(※1ファイルでもキュー生成必要)
filename_queue = tf.train.string_input_producer(
["sample.csv"])
# TextLineReader 生成(1行ずつ読み込む Reader)
reader = tf.TextLineReader()
key, value = reader.read(filename_queue)
# CSVデコード(列は3列、いずれも実数値、という指定↓)
x1, x2, y = tf.decode_csv(value, [[1.0], [1.0], [1.0]])
x = tf.pack([x1, x2])
# バッチデータプロデューサ(バッチサイズ:1000)
X_batch, Y_batch = tf.train.batch(
[x, y], batch_size=1000)
※あとは先ほどと同様
キューの仕組み
-
tf.train.QueueRunner
- ↑のキューへの enqueue 操作を繰り返し実行するスレッド(を作成するクラス)
- セッション開始後、
tf.train.start_queue_runners()
で開始する2
-
tf.train.Coordinator
- 複数スレッドを束ね、停止などの同期をとるクラス。
サンプル
(先ほどのコードの再掲)
# セッション開始
with tf.Session() as sess:
# 入力 enqueue スレッド開始
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(
sess=sess, coord=coord)
try:
# ミニバッチ処理ループ
while not coord.should_stop():
XData, YData = sess.run([X_batch, Y_batch])
# 学習等の処理
finally:
coord.request_stop()
coord.join(threads)
オリジナルレコードファイルの利用
TensorFlow 独自のレコード形式を利用する方法の紹介。
tf.TFRecordReader
- TensorFlow 独自のレコード形式で保存したファイルから、1レコードずつ読み込む
Reader
クラス。 - レコードの値(string)にシリアライズしたオブジェクトを格納(し、それをデコード)することで、バイナリデータ等様々なデータを利用可能3。
tf.python_io.TFRecordWriter
- 先述のレコード形式ファイルを書き出す Writer クラス(Python IO)
- (事前処理として)実行してレコードファイルを作成するのに使用(=セッションとは無関係)
tf.train.Example
- 複雑なデータをシリアライズ/デシリアライズするためのクラス
-
writer.write()
時は、tf.train.Example
のインスタンスを生成し、シリアライズして書き込み -
reader.read()
時は、tf.parse_example()
やtf.parse_single_example()
を利用してデシリアライズ&データを(Dict
として)取得して利用
-
サンプル
ファイル書込(シリアライズ)
# filename: 書込先ファイル名(例:"sample.tfr")
with tf.python_io.TFRecordWriter(filename) as writer:
while True:
# img_file: 画像ファイル名(例:"data01.jpg")
image = open(img_filename).read()
label = ... # 何らかの方法で取得or算出
# tf.train.Example 生成
example = tf.train.Example(features=tf.train.Features(feature={
'label': tf.train.Feature(int64_list=tf.train.Int64List(value=[label])),
'image_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[image]))}))
# レコード書込
writer.write(example.SerializeToString())
ファイル読込(デシリアライズ)
# tf.TFRecordReader 生成、レコード読込
reader = tf.TFRecordReader()
result.key, value = reader.read(filename_queue)
# デシリアライズ、Dict 取得
features = tf.parse_single_example(value, features={
'label': tf.FixedLenFeature([], tf.int64),
'image': tf.FixedLenFeature([], tf.string),
})
# 結果取得
label = tf.cast(features['label'], tf.int32)
image = tf.image.decode_jpeg(features['image_raw'], channels=result.depth)
参考
- Inputs and Readers (API リファレンス)
- Threading and Queues
-
Reading data
- 参考日本語訳:TensorFlow : How To : データを読む