データセットのAPIでtensorflow

ソース

1.データのインポート

tf.data  APIを使用すると、再利用可能な複雑な入力のパイプラインを構築するための簡単な方法を可能にします。たとえば、次のパイプライン画像モデルは、分散ファイルシステム内のファイル、各ピクチャのランダム摂動(ランダム摂動)の複数で重合してもよいし、ランダムに訓練バッチ内の1枚の画像に選択されました。パイプラインは、テキストモデルは含むことができる:ルックアップテーブル、異なる長さを有する、バッチ配列を介して埋め込み識別子に変換し、元のテキストデータからそれらの特徴を抽出します。tf.data APIを簡単に異なるデータ形式で大量のデータを処理し、変換複雑にすることができます。

データセットAPIは抽象クラスに二つの新しいTensorflowが導入されています。

  • tf.data.Dataset:各要素が1つを含むか、またはそれ以上のテンソルオブジェクトの要素(エレメント)のシリーズを表します。例えば:画像パイプラインでは、一つの要素は、画像データとそのラベルのペアとテンソルを表す単一の学習サンプルであってもよいです。あなたは、2つの異なる方法でデータセットを作成しました
    • 作成ソース  (例えば:Dataset.from_tensor_slicesを())、一つ以上のtf.Tensorオブジェクトからデータセットを構築します
    • アプリケーション形質一つ以上tf.data.Datasetオブジェクトからデータセットを構築する(例えば:Dataset.batch())、
  • tf.data.Iterator:それはデータセットから要素を抽出するための主な方法を提供します。Iterator.get_nextによる操作()は入力とパイプライン・モデルとの間のインタフェースとして、データセットの収率で次の要素を返します。最も単純なイテレータは、「ワンショットイテレータ」であり、それを反復処理するために指定されたデータセットに関連付けられています。使用するより複雑なため、Iterator.initializer動作は(パラメータ化する)異なるデータセットの再初期化(再初期化)およびパラメトリックイテレータ、例えば、訓練データと複数の反復によって検証データで同じプログラムを使用することができます。

2.基本的なメカニズム

このセクションでは、さまざまなデータセットとイテレータオブジェクトを作成するためのメカニズムを説明し、どのようにデータを抽出するためにそれらを使用します。

入力パイプラインを開始するには、ソースを定義する必要があります例えば、メモリからテンソルの一部をデータセットを構築するために、あなたはtf.data.Dataset.from_tensors()とtf.data.Dataset.from_tensor_slicesを使用することができます()。あなたの入力データがTFRecordに格納されている場合は別の方法は、あなたがディスクtf.data.TFRecordDataset上に構築することができ、フォーマットを推奨します。あなたはtf.data.Datasetオブジェクトのチェーンメソッドの呼び出しによって、DataSetオブジェクトを持っていたら、新しいデータセットに変換することができます。Dataset.map()(それは各要素に関数を適用)、ならびに、マルチ要素変換、:Dataset.batch()は、例えば、次のような要素毎の変換を、使用することができます。より詳細なAPI

データセット消費値の最も一般的に使用される方法から、それは時間の要素が(:Dataset.make_one_shot_iterator()を呼び出すことによって、例えば)データセットにアクセスすることができる提供する反復子オブジェクトを生成することです。tf.data.Iteratorは、2つの操作を提供します

  • Iterator.initializer:それはあなた(再)イテレータの初期化状態を可能に
  • Iterator.get_next():これは、特定の要素にtf.Tensorオブジェクト対応を返します。

2.1データセットの構造

要素は、それぞれが同一の構造を有するデータセット、から構成される。要素は、「コンポーネント」と呼ばれるtf.Tensorの1つまたは複数のオブジェクトが含まれてい各成分は有しtf.DTypeを:テンソル要素のタイプを表し、tf.TensorShape:それは各要素の静的形状を示しています。Dataset.output_typesとDataset.output_shapesプロパティは、データセット要素の種類や形状の各コンポーネントイントロスペクションを観察することができます。これらの属性のこの入れ子構造(入れ子構造)は、構造中に(単一テンソル、タプルのテンソル、ネストされたタプルテンソルであってもよい)要素にマッピングします。例えば:

dataset1 = tf.data.Dataset.from_tensor_slices(tf.random_uniform([4, 10]))
print(dataset1.output_types)  # ==> "tf.float32"
print(dataset1.output_shapes)  # ==> "(10,)"

dataset2 = tf.data.Dataset.from_tensor_slices(
   (tf.random_uniform([4]),
    tf.random_uniform([4, 100], maxval=100, dtype=tf.int32)))
print(dataset2.output_types)  # ==> "(tf.float32, tf.int32)"
print(dataset2.output_shapes)  # ==> "((), (100,))"

dataset3 = tf.data.Dataset.zip((dataset1, dataset2))
print(dataset3.output_types)  # ==> (tf.float32, (tf.float32, tf.int32))
print(dataset3.output_shapes)  # ==> "(10, ((), (100,)))"

各コンポーネントの指定された名前の要素(エレメント)に容易であり、それらが異なる特徴を表す場合は、例えば、トレーニングサンプル。タプルに加えて、データセットの単一の要素を表現するために辞書テンソル上の文字列にをcollections.namedtuple、またはマップを使用することができます。

dataset = tf.data.Dataset.from_tensor_slices(
   {"a": tf.random_uniform([4]),
    "b": tf.random_uniform([4, 100], maxval=100, dtype=tf.int32)})
print(dataset.output_types)  # ==> "{'a': tf.float32, 'b': tf.int32}"
print(dataset.output_shapes)  # ==> "{'a': (), 'b': (100,)}"

データセットの変換(変換)は、任意の構造の支援データセットDataset.map()、Dataset.flat_map()、及びDataset.filter()変換を使用する場合、それらは、各要素に適用される機能を有し、素子構造は、関数のパラメータを決定します。

dataset1 = dataset1.map(lambda x: ...)

dataset2 = dataset2.flat_map(lambda x, y: ...)

# Note: Argument destructuring is not available in Python 3.
dataset3 = dataset3.filter(lambda x, (y, z): ...)

2.2イテレータを作成します

あなたが入力されたデータを表現するためにデータセットを構築したら、次のステップは、要素のデータセットにアクセスするためのイテレータを作成することです。データセットAPIは、現在の複雑さの昇順で、4つのイテレータをサポートしています。

  • ワンショット
  • 初期化可能
  • reinitializable
  • 給電可能

イテレータは、ワンショット最も簡単なイテレータでは、それだけのデータセットに対する操作の1回の繰り返し、明示的な初期化をサポートしています。ワンショット・イテレータは、入力パイプラインのサポートに基づいてキューに存在し、すでにほとんどすべてのケースを扱うことができるが、それらは、パラメータ(パラメータ)をサポートしていません。使用Dataset.range()の例は次のとおりです。

dataset = tf.data.Dataset.range(100)
iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()

for i in range(100):
  value = sess.run(next_element)
  assert i == value

初期化可能イテレータを使用する前に、あなたは、明示的なiterator.initializer操作を返却する必要があります。いくつかの不便が、それはあなたが一つ以上のtf.placeholder()テンソルを使用して、(パラメータ化)データセットの定義をパラメータ化することができることができます:あなたはイテレータを初期化するとき、彼らはそれに供給することができます。Dataset.rangeは()である例を続けます。

max_value = tf.placeholder(tf.int64, shape=[])
dataset = tf.data.Dataset.range(max_value)
iterator = dataset.make_initializable_iterator()
next_element = iterator.get_next()

# Initialize an iterator over a dataset with 10 elements.
sess.run(iterator.initializer, feed_dict={max_value: 10})
for i in range(10):
  value = sess.run(next_element)
  assert i == value

# Initialize the same iterator over a dataset with 100 elements.
sess.run(iterator.initializer, feed_dict={max_value: 100})
for i in range(100):
  value = sess.run(next_element)
  assert i == value

反復子がreinitializable異なる複数でDataSetオブジェクトから初期化することができます。検証入力パイプライン(データを変更されていないことが予測に評価されます)。たとえば、あなたがトレーニング入力パイプラインを(その入力画像は汎化能力を向上させるために、ランダムな摂動を行う)必要がある場合があります。これらは、典型的には、異なるパイプラインDataSetオブジェクトを使用し、それらは同じ構造を有している(例えば:同じ種類と各コンポーネントの形状)

# Define training and validation datasets with the same structure.
training_dataset = tf.data.Dataset.range(100).map(
    lambda x: x + tf.random_uniform([], -10, 10, tf.int64))
validation_dataset = tf.data.Dataset.range(50)

# A reinitializable iterator is defined by its structure. We could use the
# `output_types` and `output_shapes` properties of either `training_dataset`
# or `validation_dataset` here, because they are compatible.
iterator = tf.data.Iterator.from_structure(training_dataset.output_types,
                                   training_dataset.output_shapes)
next_element = iterator.get_next()

training_init_op = iterator.make_initializer(training_dataset)
validation_init_op = iterator.make_initializer(validation_dataset)

# Run 20 epochs in which the training dataset is traversed, followed by the
# validation dataset.
for _ in range(20):
  # Initialize an iterator over the training dataset.
  sess.run(training_init_op)
  for _ in range(100):
    sess.run(next_element)

  # Initialize an iterator over the validation dataset.
  sess.run(validation_init_op)
  for _ in range(50):
    sess.run(next_element)

給紙可能イテレータは、イテレータをtf.Session.runが使用される各コールを選択するように馴染みfeed_dict機構を介して、tf.placeholderと共に使用することができます。それはreinitializableイテレータと同じ機能を提供していますが、イテレータの間で相互に切り替えたとき、それはイテレータを初期化する必要はありません。たとえば:同じトレーニングと検証サンプルを使用して、あなたはtf.data.Iterator.from_string_handle搬送可能なイテレータを定義するために使用でき、2つのデータセットを切り替えることができます:

# Define training and validation datasets with the same structure.
training_dataset = tf.data.Dataset.range(100).map(
    lambda x: x + tf.random_uniform([], -10, 10, tf.int64)).repeat()
validation_dataset = tf.data.Dataset.range(50)

# A feedable iterator is defined by a handle placeholder and its structure. We
# could use the `output_types` and `output_shapes` properties of either
# `training_dataset` or `validation_dataset` here, because they have
# identical structure.
handle = tf.placeholder(tf.string, shape=[])
iterator = tf.data.Iterator.from_string_handle(
    handle, training_dataset.output_types, training_dataset.output_shapes)
next_element = iterator.get_next()

# You can use feedable iterators with a variety of different kinds of iterator
# (such as one-shot and initializable iterators).
training_iterator = training_dataset.make_one_shot_iterator()
validation_iterator = validation_dataset.make_initializable_iterator()

# The `Iterator.string_handle()` method returns a tensor that can be evaluated
# and used to feed the `handle` placeholder.
training_handle = sess.run(training_iterator.string_handle())
validation_handle = sess.run(validation_iterator.string_handle())

# Loop forever, alternating between training and validation.
while True:
  # Run 200 steps using the training dataset. Note that the training dataset is
  # infinite, and we resume from where we left off in the previous `while` loop
  # iteration.
  for _ in range(200):
    sess.run(next_element, feed_dict={handle: training_handle})

  # Run one pass over the validation dataset.
  sess.run(validation_iterator.initializer)
  for _ in range(50):
    sess.run(next_element, feed_dict={handle: validation_handle})

イテレータ消費値から2.3

Iterator.get_next()メソッドは、イテレータの次の要素に対応する、tf.Tensor以上のオブジェクトを返します。これらのレビューはテンソルあるたびに、彼らは、基礎となるデータセット内の次の要素の値を取得します。(注:他の類似Tensorflow状態オブジェクトがありますが、コールIterator.get_next()のすぐ前方イテレータを聞かせていない代わりに、あなたはtf.Tensorを使用する必要があり、式の結果を渡し、Tensorflow式が返されるオブジェクト。 )次の要素を取得し、イテレータをできるように、)(tf.Session.runへ

イテレータは、データセットの終わりに達した場合は、行うIterator.get_next()操作はtf.errors.OutOfRangeErrorをスローします。その後、イテレータを使用すると、さらに使用する場合は、それを再初期化しなければならず、存在の状態に使用することはできません。

dataset = tf.data.Dataset.range(5)
iterator = dataset.make_initializable_iterator()
next_element = iterator.get_next()

# Typically `result` will be the output of a model, or an optimizer's
# training operation.
result = tf.add(next_element, next_element)

sess.run(iterator.initializer)
print(sess.run(result))  # ==> "0"
print(sess.run(result))  # ==> "2"
print(sess.run(result))  # ==> "4"
print(sess.run(result))  # ==> "6"
print(sess.run(result))  # ==> "8"
try:
  sess.run(result)
except tf.errors.OutOfRangeError:
  print("End of dataset")  # ==> "End of dataset"

一般的なパターンは、try-除くブロックにカプセル化「トレーニングループ」です。

sess.run(iterator.initializer)
while True:
  try:
    sess.run(result)
  except tf.errors.OutOfRangeError:
    break

データセットの各要素は、ネストされた構造を有する場合、Iterator.get_next()は、値が同じtf.Tensor入れ子構造の1つ以上のオブジェクトの存在である戻ります

dataset1 = tf.data.Dataset.from_tensor_slices(tf.random_uniform([4, 10]))
dataset2 = tf.data.Dataset.from_tensor_slices((tf.random_uniform([4]), tf.random_uniform([4, 100])))
dataset3 = tf.data.Dataset.zip((dataset1, dataset2))

iterator = dataset3.make_initializable_iterator()

sess.run(iterator.initializer)
next1, (next2, next3) = iterator.get_next()

用next1、ネクスト2、またはNEXT3のいずれかが、すべてのコンポーネントのために評価されますが、イテレータれたことに注意してください。一般的な消費者は、イテレータは単一の式ですべてのコンポーネントが含まれています。

3.読み取り、入力データ

3.1消費者numpyのアレイ

すべての入力データがメモリにロードされている場合は、最も簡単な方法は、データセットからのデータ入力を作成することで、tf.Tensorオブジェクトと使用Dataset.from_tensor_slicesに変換して()。

# Load the training data into two NumPy arrays, for example using `np.load()`.
with np.load("/var/data/training_data.npy") as data:
  features = data["features"]
  labels = data["labels"]

# Assume that each row of `features` corresponds to the same row as `labels`.
assert features.shape[0] == labels.shape[0]

dataset = tf.data.Dataset.from_tensor_slices((features, labels))

上記のコードは、(tf.constantとして配列とラベルアレイを備えてなることに注意してください)あなたのTensorFlowグラフの操作にネスト。これは、小さなデータセットでも実行できますが、メモリを無駄にすることができます - メモリの配列がtf.GraphDefバッファプロトコルの場合----何回もコピーされますので、そしてあなただけがメモリ2GBの制限を実行することができます。

# Load the training data into two NumPy arrays, for example using `np.load()`.
with np.load("/var/data/training_data.npy") as data:
  features = data["features"]
  labels = data["labels"]

# Assume that each row of `features` corresponds to the same row as `labels`.
assert features.shape[0] == labels.shape[0]

features_placeholder = tf.placeholder(features.dtype, features.shape)
labels_placeholder = tf.placeholder(labels.dtype, labels.shape)

dataset = tf.data.Dataset.from_tensor_slices((features_placeholder, labels_placeholder))
# [Other transformations on `dataset`...]
dataset = ...
iterator = dataset.make_initializable_iterator()

sess.run(iterator.initializer, feed_dict={features_placeholder: features,
                                          labels_placeholder: labels})

3.2消費者TFRecordデータ

あなたはより多くの大規模なデータセットのメモリサイズよりも扱うことができるので、データセットAPIは、複数のファイル形式をサポートしています。例えば、TFRecordファイル形式は、簡単なレコード指向のバイナリ形式で、多くのTensorFlowアプリケーションは、トレーニングデータのためにそれを使用します。tf.data.TFRecordDatasetクラスを使用すると、1つの中で流動化以上のコンテンツがTFRecordをファイル、パイプラインの一部として入力してできます。

# Creates a dataset that reads all of the examples from two files.
filenames = ["/var/data/file1.tfrecord", "/var/data/file2.tfrecord"]
dataset = tf.data.TFRecordDataset(filenames)

初期化子TFRecordDataset ファイル名のパラメータは文字列であってもよいし、文字列、またはtf.Tensor上の文字列のものであってもよいです。あなたがトレーニングデータと検証データに対応した、二つの文書のセットを持っているのであれば、あなたはtf.placeholder(tf.string)を使用するファイル名を表し、そしてイテレータから適切なファイル名を初期化することができます。

filenames = tf.placeholder(tf.string, shape=[None])
dataset = tf.data.TFRecordDataset(filenames)
dataset = dataset.map(...)  # Parse the record into tensors.
dataset = dataset.repeat()  # Repeat the input indefinitely.
dataset = dataset.batch(32)
iterator = dataset.make_initializable_iterator()

# You can feed the initializer with the appropriate filenames for the current
# phase of execution, e.g. training vs. validation.

# Initialize `iterator` with training data.
training_filenames = ["/var/data/file1.tfrecord", "/var/data/file2.tfrecord"]
sess.run(iterator.initializer, feed_dict={filenames: training_filenames})

# Initialize `iterator` with validation data.
validation_filenames = ["/var/data/validation1.tfrecord", ...]
sess.run(iterator.initializer, feed_dict={filenames: validation_filenames})

3.3消費者のテキストデータ

多くのデータセットは、1つ以上のテキストファイルに配布します。tf.data.TextLineDatasetは、テキストファイルからの行(ライン)を抽出するための簡単な方法を提供します。一の以上のファイル名が与えられ、TextLineDatasetは、これらのファイルの各行の文字列型の要素を生成します。あなたはtf.placeholder(tf.string)はパラメータを渡すことができるようにとTFRecordDatasetは同様に、TextLineDatasetは、Aパラメータファイル名tf.Tensorとして受け入れます。

filenames = ["/var/data/file1.txt", "/var/data/file2.txt"]
dataset = tf.data.TextLineDataset(filenames)

開始、またはするためにヘッダ行を使用してファイルにはコメントが含まれている場合、デフォルトでは、収率は、例えば、私たちが望むものではありませんTextLineDataset各ファイルのすべての行になります。行がDataset.skip()とDataset.filter()変換によって除去されます。各ファイルに独立して、これらのアプリケーションを変換するために、我々は、各ファイルのネストされたデータセットを作成するためにDataset.flat_map()を使用します。

filenames = ["/var/data/file1.txt", "/var/data/file2.txt"]

dataset = tf.data.Dataset.from_tensor_slices(filenames)

# Use `Dataset.flat_map()` to transform each file as a separate nested dataset,
# and then concatenate their contents sequentially into a single "flat" dataset.
# * Skip the first line (header row).
# * Filter out lines beginning with "#" (comments).
dataset = dataset.flat_map(
    lambda filename: (
        tf.data.TextLineDataset(filename)
        .skip(1)
        .filter(lambda line: tf.not_equal(tf.substr(line, 0, 1), "#"))))

4. Dataset.map()データの前処理

関数f与えられた入力データのセットを適用することにより、各要素は、Dataset.map(F)の変換は、新しいデータセットを生成します。関数f(新しいデータセットの単一の要素を表す)パラメータと戻りtf.Tensorオブジェクトとして(INPUTで単一の要素を表す)tf.Tensorオブジェクトを受け付けます。それは別の要素を変換する標準TensorFlowの動作可能を使用して実装されます。

このセクションでは、どのようにDataset.map()Aの例が含まれています。

4.1解析tf.Exampleプロトコルバッファメッセージ

多くの入力パイプラインは、(例えば:tf.python_io.TFRecordWriterを使用して)TFRecordファイル形式からtf.train.Exampleプロトコルバッファメッセージを引っ張ってきます。各tf.train.Exampleレコードが1つ以上の「機能」が含まれ、入力パイプラインは、通常、これらの機能のテンソルに変換されます。

# Transforms a scalar string `example_proto` into a pair of a scalar string and
# a scalar integer, representing an image and its label, respectively.
def _parse_function(example_proto):
  features = {"image": tf.FixedLenFeature((), tf.string, default_value=""),
              "label": tf.FixedLenFeature((), tf.int32, default_value=0)}
  parsed_features = tf.parse_single_example(example_proto, features)
  return parsed_features["image"], parsed_features["label"]

# Creates a dataset that reads all of the examples from two files, and extracts
# the image and label features.
filenames = ["/var/data/file1.tfrecord", "/var/data/file2.tfrecord"]
dataset = tf.data.TFRecordDataset(filenames)
dataset = dataset.map(_parse_function)

4.2画像データは復号化、およびサイズ変更します

現実世界の画像データは、ニューラルネットワークを訓練するとき、多くの場合、あなたは同じ大きさの異なる大きさに画像を変換する必要があり、そのため、固定バッチサイズに変換する必要があります。

# Reads an image from a file, decodes it into a dense tensor, and resizes it
# to a fixed shape.
def _parse_function(filename, label):
  image_string = tf.read_file(filename)
  image_decoded = tf.image.decode_image(image_string)
  image_resized = tf.image.resize_images(image_decoded, [28, 28])
  return image_resized, label

# A vector of filenames.
filenames = tf.constant(["/var/data/image1.jpg", "/var/data/image2.jpg", ...])

# `labels[i]` is the label for the image in `filenames[i].
labels = tf.constant([0, 37, ...])

dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))
dataset = dataset.map(_parse_function)

4.3 tf.py_func()

パフォーマンス上の理由から、我々はデータを前処理するためにTensorFlow操作を使用することをお勧めします。しかし、時には、あなたが入力したデータを解析し、追加のPythonライブラリのための呼び出しは有用であろう。あなたはDataset.map()変換動作にtf.py_func()を呼び出すことによって、これを達成することができます。

import cv2

# Use a custom OpenCV function to read the image, instead of the standard
# TensorFlow `tf.read_file()` operation.
def _read_py_function(filename, label):
  image_decoded = cv2.imread(image_string, cv2.IMREAD_GRAYSCALE)
  return image_decoded, label

# Use standard TensorFlow operations to resize the image to a fixed shape.
def _resize_function(image_decoded, label):
  image_decoded.set_shape([None, None, None])
  image_resized = tf.image.resize_images(image_decoded, [28, 28])
  return image_resized, label

filenames = ["/var/data/image1.jpg", "/var/data/image2.jpg", ...]
labels = [0, 37, 29, 1, ...]

dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))
dataset = dataset.map(
    lambda filename, label: tf.py_func(
        _read_py_function, [filename, label], [tf.uint8, label.dtype]))
dataset = dataset.map(_resize_function)

前記パッキング要素(バッチデータセット要素)

5.1単純なバッチ処理

最も簡単な方法はバッチ処理は、単一のスタック要素にn個の連続する要素のデータセットです。Dataset.batch()を正確にこれを行う変換することができ、それはtf.stack()制約を同様の操作を使用して、アプリケーションの各構成要素:例えば、各要素iについて、すべての要素が同じを持っている必要がありますテンソルの形状:

inc_dataset = tf.data.Dataset.range(100)
dec_dataset = tf.data.Dataset.range(0, -100, -1)
dataset = tf.data.Dataset.zip((inc_dataset, dec_dataset))
batched_dataset = dataset.batch(4)

iterator = batched_dataset.make_one_shot_iterator()
next_element = iterator.get_next()

print(sess.run(next_element))  # ==> ([0, 1, 2,   3],   [ 0, -1,  -2,  -3])
print(sess.run(next_element))  # ==> ([4, 5, 6,   7],   [-4, -5,  -6,  -7])
print(sess.run(next_element))  # ==> ([8, 9, 10, 11],   [-8, -9, -10, -11])

5.2使用パディングパックテンソル

上記の方法は、同じサイズを必要とします。しかし、多くのモデル:入力データの種々の(例えば、モデル配列など)のサイズ(例えば:配列異なる長さを有する)は、このような状況を処理するために、Dataset.padded_batch()もしによって、バッチのテンソルの異なる形状を変換することができそのパッドの上に運ば1つ以上のディメンションを指定します。

dataset = tf.data.Dataset.range(100)
dataset = dataset.map(lambda x: tf.fill([tf.cast(x, tf.int32)], x))
dataset = dataset.padded_batch(4, padded_shapes=[None])

iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()

print(sess.run(next_element))  # ==> [[0, 0, 0], [1, 0, 0], [2, 2, 0], [3, 3, 3]]
print(sess.run(next_element))  # ==> [[4, 4, 4, 4, 0, 0, 0],
                               #      [5, 5, 5, 5, 5, 0, 0],
                               #      [6, 6, 6, 6, 6, 6, 0],
                               #      [7, 7, 7, 7, 7, 7, 7]]

Dataset.padded_batch()は可変長であってもよいパディングの各次元の各成分のための異なる設定、または一定の長さ(サンプル中のどれを指定することはできません)に変換することを可能にします。あなたは(デフォルトは0.0である)パディングの値をオーバーライドすることができます。

6.トレーニングワークフロー(トレーニングワークフロー)

6.1ハンドル複数のエポック

データセットAPIは、同じデータにエポックを複数扱うための2つの主要な方法を提供します。

最も簡単な方法は、データセット()複数の反復を変換にDataset.repeatを使用することです。例:データセットを作成し、その入力10エポックを繰り返します。

filenames = ["/var/data/file1.tfrecord", "/var/data/file2.tfrecord"]
dataset = tf.data.TFRecordDataset(filenames)
dataset = dataset.map(...)
dataset = dataset.repeat(10)
dataset = dataset.batch(32)

Dataset.repeat()が入力を繰り返していきます引数を使用しません。Dataset.repeat()パラメータ変換器は、最初の信号のいずれかとすることなく、次のラウンドの終了時に、それに接続されています。

あなたは、各ラウンドの終了は、信号を受信したい場合は、データセットの終わりにtf.errors.OutOfRangeErrorをキャプチャし、トレーニングループを書くことができます。その瞬間、あなたは、ホイールの一部の統計情報を収集することができます(例:検証エラー)

filenames = ["/var/data/file1.tfrecord", "/var/data/file2.tfrecord"]
dataset = tf.data.TFRecordDataset(filenames)
dataset = dataset.map(...)
dataset = dataset.batch(32)
iterator = dataset.make_initializable_iterator()
next_element = iterator.get_next()

# Compute for 100 epochs.
for _ in range(100):
  sess.run(iterator.initializer)
  while True:
    try:
      sess.run(next_element)
    except tf.errors.OutOfRangeError:
      break

  # [Perform end-of-epoch calculations here.]

入力データのランダムシャッフルの6.2ペア

Dataset.shuffle()は同じアルゴリズムおよび入力データセットのtf.RandomShuffleQueueランダムシャッフルを使用して変換される:それは、固定サイズのバッファを維持し、ランダムで均一にバッファから次の要素を選択します。

filenames = ["/var/data/file1.tfrecord", "/var/data/file2.tfrecord"]
dataset = tf.data.TFRecordDataset(filenames)
dataset = dataset.map(...)
dataset = dataset.shuffle(buffer_size=10000)
dataset = dataset.batch(32)
dataset = dataset.repeat()

6.3を使用する高度なAPI

tf.train.MonitoredTrainingSessionのAPIは、下の分散セットTensorflow実行の多くの側面を簡素化することができます。訓練は、送信信号に、MonitoredTrainingSession使用tf.errors.OutOfRangeErrorを完了すると、そのデータセットのAPIとそれを使用するために、我々は)(Dataset.make_one_shot_iteratorを使用することをお勧めします。例えば:

filenames = ["/var/data/file1.tfrecord", "/var/data/file2.tfrecord"]
dataset = tf.data.TFRecordDataset(filenames)
dataset = dataset.map(...)
dataset = dataset.shuffle(buffer_size=10000)
dataset = dataset.batch(32)
dataset = dataset.repeat(num_epochs)
iterator = dataset.make_one_shot_iterator()

next_example, next_label = iterator.get_next()
loss = model_function(next_example, next_label)

training_op = tf.train.AdagradOptimizer(...).minimize(loss)

with tf.train.MonitoredTrainingSession(...) as sess:
  while not sess.should_stop():
    sess.run(training_op)

tf.estimator.Estimator input_fnでデータセットを使用するために、我々はDataset.make_one_shot_iterator()を使用することをお勧めします。例えば:

def dataset_input_fn():
  filenames = ["/var/data/file1.tfrecord", "/var/data/file2.tfrecord"]
  dataset = tf.data.TFRecordDataset(filenames)

  # Use `tf.parse_single_example()` to extract data from a `tf.Example`
  # protocol buffer, and perform any additional per-record preprocessing.
  def parser(record):
    keys_to_features = {
        "image_data": tf.FixedLenFeature((), tf.string, default_value=""),
        "date_time": tf.FixedLenFeature((), tf.int64, default_value=""),
        "label": tf.FixedLenFeature((), tf.int64,
                                    default_value=tf.zeros([], dtype=tf.int64)),
    }
    parsed = tf.parse_single_example(record, keys_to_features)

    # Perform additional preprocessing on the parsed data.
    image = tf.decode_jpeg(parsed["image_data"])
    image = tf.reshape(image, [299, 299, 1])
    label = tf.cast(parsed["label"], tf.int32)

    return {"image_data": image, "date_time": parsed["date_time"]}, label

  # Use `Dataset.map()` to build a pair of a feature dictionary and a label
  # tensor for each example.
  dataset = dataset.map(parser)
  dataset = dataset.shuffle(buffer_size=10000)
  dataset = dataset.batch(32)
  dataset = dataset.repeat(num_epochs)
  iterator = dataset.make_one_shot_iterator()

  # `features` is a dictionary in which each value is a batch of values for
  # that feature; `labels` is a batch of labels.
  features, labels = iterator.get_next()
  return features, labels

参照

公式tensorflowデータセット

 

 

公開された557元の記事 ウォンの賞賛500 ビュー153万+

おすすめ

転載: blog.csdn.net/qq_16234613/article/details/103758216