Help us understand the problem. What is going on with this article?

TensorFlow データ読込実用編

More than 3 years have passed since last update.

TensorFlow データ読込実用編

by antimon2
1 / 21

初めに

  • 転職して約1ヶ月経過1
  • 仕事でバリバリ TensorFlow 活用中
  • ↑にともなって月の前半は TF(再)勉強
  • その成果の紹介

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)


参考


  1. ていうか転職しました。機械学習ライフを満喫しています。 

  2. 逆にtf.train.start_queue_runners()せずにキュー(を利用した操作)を利用しようとすると、enqueue待ちで無限ループ発生するので注意! 

  3. シリアライズの利点は、複数の画像ファイル等を1つのレコードファイルにまとめることでディスクIOが減り、結果的にパフォーマンス改善につながる(ことが期待される)こと。 

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away