TPU スピードのデータ パイプライン: tf.data.Dataset と TFRecords

1. 概要

TPU は非常に高速です。トレーニング データのストリームも、トレーニングのスピードについていく必要があります。このラボでは、tf.data.Dataset API を使用して GCS からデータを読み込み、TPU にフィードする方法を学びます。

このラボは「TPU 上の Keras」のパート 1 ですシリーズとして提供されますこれらは次の順序で実行することも、個別に実行することもできます。

ca8cc21f6838eccc.png

学習内容

  • tf.data.Dataset API を使用してトレーニング データを読み込む
  • TFRecord 形式を使用して GCS から効率的にトレーニング データを読み込む

フィードバック

この Codelab で何か問題がありましたらお知らせください。フィードバックは、GitHub の問題 [フィードバック リンク] からお送りいただけます。

2. Google Colaboratory クイック スタート

このラボでは Google Collaboratory を使用します。ユーザー側での設定は必要ありません。Colaboratory は、教育を目的としたオンライン ノートブック プラットフォームです。CPU、GPU、TPU を無料でトレーニングできます。

688858c21e3beff2.png

このサンプル ノートブックを開いていくつかのセルを実行し、Colaboratory についてよく理解してください。

c3df49e90e5a654f.png Welcome to Colab.ipynb

TPU バックエンドを選択する

8832c6208c99687d.png

Colab のメニューで [ランタイム] >ランタイム タイプを変更し、[TPU] を選択します。この Codelab では、ハードウェア アクセラレーションによるトレーニングをサポートする強力な TPU(Tensor Processing Unit)を使用します。ランタイムへの接続は初回実行時に自動的に行われますが、[接続] オプションを使用してボタンをタップします。

ノートブックの実行

76d05caa8b4db6da.png

セルを 1 つずつ実行するには、セルをクリックして Shift+Enter キーを押します。[ランタイム >すべて実行

目次

429f106990037ec4.png

すべてのノートブックには目次があります。左側にある黒い矢印をクリックすると開きます。

非表示のセル

edc3dba45d26f12a.png

一部のセルにはタイトルのみが表示されます。これは Colab 固有のノートブック機能です。それらをダブルクリックすると内部のコードを確認できますが、通常はあまり興味を引かないものです。通常はサポート関数または可視化関数です。内部の関数を定義するには、これらのセルを実行する必要があります。

認証

cdd4b41413100543.png

承認済みアカウントで認証すれば、Colab が限定公開の Google Cloud Storage バケットにアクセスできます。上記のコード スニペットによって認証プロセスがトリガーされます。

3. [情報] Tensor Processing Unit(TPU)とは

概要

f88cf6facfc70166.png

Keras の TPU でモデルをトレーニングする(TPU が使用できない場合は GPU または CPU にフォールバックする)コード:

try: # detect TPUs
    tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
    strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
    strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines

# use TPUStrategy scope to define model
with strategy.scope():
  model = tf.keras.Sequential( ... )
  model.compile( ... )

# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)

本日は TPU を使用して、インタラクティブな速度(トレーニング実行あたり数分)で花の分類器を構築し、最適化します。

688858c21e3beff2.png

TPU を選ぶ理由

最新の GPU は、プログラム可能な「コア」を中心に構成されています。コアは、3D レンダリング、ディープ ラーニング、物理シミュレーションなどのさまざまなタスクを処理できる非常に柔軟なアーキテクチャです。一方、TPU は従来のベクトル プロセッサと専用の行列乗算ユニットをペアにして、ニューラル ネットワークなど、大規模な行列乗算が主体となるあらゆるタスクに優れています。

8eb3e718b8e2ed08.png

イラスト: 行列乗算としての高密度ニューラル ネットワーク レイヤ。ニューラル ネットワークによって一度に処理された 8 つの画像のバッチを示しています。1 行 x 列の乗算を実行して、画像のすべてのピクセル値の加重合計が実際に行われていることを確認してください。畳み込みレイヤも行列の乗算として表すことができますが、やや複雑です( 説明はセクション 1)。

ハードウェア

MXU と VPU

TPU v2 コアは、行列の乗算を実行する行列乗算ユニット(MXU)と、活性化やソフトマックスなどの他のタスクのためのベクトル処理ユニット(VPU)で構成されます。VPU は、float32 と int32 の計算を処理します。一方、MXU は、混合精度の 16 ~ 32 ビット浮動小数点形式で動作します。

7d68944718f76b18.png

混合精度の浮動小数点数と bfloat16

MXU は、bfloat16 入力と float32 出力を使用して行列乗算を計算します。中間の累積は float32 精度で行われます。

19c5fc432840c714.png

通常、ニューラル ネットワーク トレーニングでは浮動小数点精度の低下によるノイズに耐えられます。ノイズがオプティマイザーの収束に役立つ場合もあります。従来、計算を高速化するために 16 ビットの浮動小数点精度が使用されてきましたが、float16 形式と float32 形式では範囲が大きく異なります。精度を float32 から float16 に下げると、通常、オーバーフローとアンダーフローが発生します。ソリューションは存在しますが、通常、float16 を機能させるには追加の作業が必要です。

そのため、Google は TPU に bfloat16 形式を導入しました。bfloat16 は、float32 とまったく同じ指数ビットと範囲を持つ切り捨て型 float32 です。これは、TPU が bfloat16 入力と float32 出力の混合精度で行列乗算を計算するという事実に加え、通常はコードを変更しなくても精度が下がるというパフォーマンス向上のメリットを享受できることを意味します。

シストリック配列

MXU は、いわゆる「シストリックアレイ」を使用して、ハードウェアで行列乗算を実装します。このアーキテクチャでは、データ要素が一連のハードウェア計算ユニットを通過します。(医学用語では、「最高血圧」は心臓の収縮と血流を意味し、ここではデータの流れを指します)。

行列の乗算の基本要素は、一方の行列と他方の行の直線との間のドット積です(このセクションの冒頭にある図を参照)。行列の乗算 Y=X*W の場合、結果の 1 つの要素は次のようになります。

Y[2,0] = X[2,0]*W[0,0] + X[2,1]*W[1,0] + X[2,2]*W[2,0] + ... + X[2,n]*W[n,0]

GPU では、このドット積を GPU「コア」にプログラムします。必要な数の「コア」で実行できるからです。結果の行列のすべての値を一度に計算しようと試みます。結果として得られるマトリクスのサイズが 128x128 の場合、128x128=16K「コア」が必要になります。通常は実現できません最大の GPU は約 4,000 コアです。一方、TPU は、MXU のコンピューティング単位に最小限のハードウェア(bfloat16 x bfloat16 => float32 乗アキュムレータ、それ以外は何も使用しません)を使用します。これらは非常に小さいため、TPU は 128x128 MXU で 16K を実装し、この行列の乗算を一度に処理できます。

f1b283fc45966717.gif

イラスト: MXU シストリック アレイ。コンピューティング要素は乗算アキュムレータです。1 つの行列の値が配列に読み込まれます(赤いドット)。もう一方の行列の値は、配列(グレーのドット)を通過します。縦線により値が上に移動します。水平線は部分合計を表します。配列の中をデータが流れるときに、行列乗算の結果が右側から出力されることを確認するのは、ユーザーの演習として行います。

それに加えて、ドット積が MXU で計算されている間、中間合計は単に隣接する計算ユニット間で流れます。メモリやレジスタ ファイルへの格納や取得も不要です。最終的に、TPU シストリック アレイ アーキテクチャは、行列の乗算の計算において、密度と電力の大幅な利点があるだけでなく、GPU よりも無視できないほどの速度の点で優れています。

Cloud TPU

Cloud TPU v2 インチGoogle Cloud Platform では、PCI 接続 TPU ボードを備えた仮想マシン(VM)を利用できます。TPU ボードには、デュアルコア TPU チップが 4 つあります。各 TPU コアは、VPU(ベクトル プロセッシング ユニット)と 128x128 MXU(MatriX 乗算ユニット)を備えています。この「Cloud TPU」は通常はネットワーク経由で要求元の VM に接続されます。全体像は次のようになります。

dfce5522ed644ece.png

図: ネットワークに接続された「Cloud TPU」を持つ VM提供しています「Cloud TPU」それ自体は、4 つのデュアルコア TPU チップを搭載した PCI 接続 TPU ボードを備えた VM で構成されています。

TPU Pod

Google のデータセンターでは、TPU がハイ パフォーマンス コンピューティング(HPC)相互接続に接続されているため、1 つの非常に大規模なアクセラレータのように見えます。Google ではこれを Pod と呼び、最大 512 個の TPU v2 コアまたは 2,048 個の TPU v3 コアを含めることができます。

2ec1e0d341e7fc34.jpeg

イラスト: TPU v3 Pod。HPC Interconnect で接続された TPU ボードとラック。

トレーニング中に、TPU コア間で勾配が all-reduce アルゴリズムを使用して交換されます(all-reduce についてはこちらの説明をご覧ください)。トレーニング対象のモデルは、大規模なバッチサイズでトレーニングすることでハードウェアを利用できます。

d97b9cc5d40fdb1d.gif

イラスト: Google TPU の 2D トロイダル メッシュ HPC ネットワークで all-reduce アルゴリズムを使用したトレーニング中の勾配の同期。

ソフトウェア

大規模なバッチサイズのトレーニング

TPU の理想的なバッチサイズは TPU コアあたり 128 個のデータアイテムですが、ハードウェアではすでに TPU コアあたり 8 個のデータアイテムから良好な利用率を示しています。1 つの Cloud TPU には 8 つのコアがあることを思い出してください。

この Codelab では、Keras API を使用します。Keras で指定するバッチは、TPU 全体のグローバル バッチサイズです。バッチは自動的に 8 に分割され、TPU の 8 コアで実行されます。

da534407825f01e3.png

パフォーマンスに関するその他のヒントについては、TPU パフォーマンス ガイドをご覧ください。非常に大きなバッチサイズの場合、一部のモデルでは特別な注意が必要です。詳細については、LARSOptimizer をご覧ください。

仕組み: XLA

TensorFlow プログラムは計算グラフを定義します。TPU は Python コードを直接実行するのではなく、TensorFlow プログラムで定義された計算グラフを実行します。内部では、XLA(アクセラレータ線形代数コンパイラ)と呼ばれるコンパイラが、計算ノードの Tensorflow グラフを TPU マシンコードに変換します。このコンパイラは、コードとメモリ レイアウトに対して多くの高度な最適化も行います。処理が TPU に送信されると、コンパイルが自動的に行われます。ビルドチェーンに XLA を明示的に含める必要はありません。

edce61112cd57972.png

図: TPU で実行するには、TensorFlow プログラムで定義された計算グラフがまず XLA(高速線形代数コンパイラ)表現に変換され、その後 XLA によって TPU マシンコードにコンパイルされます。

Keras での TPU の使用

TPU は、Tensorflow 2.1 以降の Keras API を通じてサポートされています。Keras のサポートは TPU と TPU Pod で動作します。TPU、GPU、CPU で動作する例を次に示します。

try: # detect TPUs
    tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
    strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
    strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines

# use TPUStrategy scope to define model
with strategy.scope():
  model = tf.keras.Sequential( ... )
  model.compile( ... )

# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)

このコード スニペットは次のようになります。

  • TPUClusterResolver().connect() は、ネットワーク上の TPU を検索します。ほとんどの Google Cloud システム(AI Platform ジョブ、Colaboratory、Kubeflow、「ctpu up」ユーティリティで作成されたディープ ラーニング VM)で、パラメータなしで機能します。これらのシステムは、TPU_NAME 環境変数のおかげで TPU の場所を把握しています。TPU を手動で作成する場合は、TPU_NAME 環境を設定します。変数使用している VM に対して実行するか、明示的なパラメータで TPUClusterResolver を呼び出します(TPUClusterResolver(tp_uname, zone, project))。
  • TPUStrategy は、分布と「all-reduce」を実装する部分です。勾配同期アルゴリズムを使用します
  • 戦略はスコープを通じて適用されます。モデルは、戦略 scope() 内で定義する必要があります。
  • tpu_model.fit 関数は、TPU トレーニングの入力として tf.data.Dataset オブジェクトを想定しています。

TPU 移行の一般的なタスク

  • TensorFlow モデルにデータを読み込む方法は数多くありますが、TPU では tf.data.Dataset API を使用する必要があります。
  • TPU は非常に高速であり、実行時にデータの取り込みがボトルネックになることがよくあります。TPU パフォーマンス ガイドには、データのボトルネックを検出するためのツールや、パフォーマンスに関するその他のヒントが記載されています。
  • int8 または int16 の数値は int32 として扱われます。TPU には、32 ビット未満で動作する整数ハードウェアはありません。
  • 一部の TensorFlow オペレーションはサポートされていません。こちらのリストをご覧ください。幸いなことに、この制限はトレーニング コード、つまりモデルのフォワード パスとバックワード パスにのみ適用されます。Tensorflow のオペレーションはすべて CPU で実行されるため、データ入力パイプラインでも使用できます。
  • tf.py_func は TPU でサポートされていません。

4. データを読み込んでいます

c0ecb860e4cad0a9.jpeg cc4781a7739c49ae.jpeg 81236b00f8bbf39e.jpeg 961e2228974076bb.jpeg 7517dc163bdffcd5.jpeg 96392df4767f566d.png

今回は花の画像のデータセットを使用します。目標は、花を 5 種類に分類する方法を学ぶことです。データの読み込みは tf.data.Dataset API を使用して実行されます。まず、API について説明します。

ハンズオン

次のノートブックを開いてセルを実行(Shift+Enter キー)し、「必要な作業」が表示されている箇所をすべて手順に沿って操作してくださいラベルです。

c3df49e90e5a654f.png Fun with tf.data.Dataset (playground).ipynb

その他の情報

「花」についてデータセット

データセットは 5 つのフォルダで構成されています。各フォルダには 1 種類の花が入っています。フォルダの名前は、ヒマワリ、デイジー、タンポポ、チューリップ、バラです。データは Google Cloud Storage の公開バケットでホストされています。抜粋:

gs://flowers-public/sunflowers/5139971615_434ff8ed8b_n.jpg
gs://flowers-public/daisy/8094774544_35465c1c64.jpg
gs://flowers-public/sunflowers/9309473873_9d62b9082e.jpg
gs://flowers-public/dandelion/19551343954_83bb52f310_m.jpg
gs://flowers-public/dandelion/14199664556_188b37e51e.jpg
gs://flowers-public/tulips/4290566894_c7f061583d_m.jpg
gs://flowers-public/roses/3065719996_c16ecd5551.jpg
gs://flowers-public/dandelion/8168031302_6e36f39d87.jpg
gs://flowers-public/sunflowers/9564240106_0577e919da_n.jpg
gs://flowers-public/daisy/14167543177_cd36b54ac6_n.jpg

tf.data.Dataset を選ぶ理由

Keras と Tensorflow は、すべてのトレーニング関数と評価関数でデータセットを受け入れます。データセットにデータを読み込むと、ニューラル ネットワークのトレーニング データに役立つ共通機能が API によってすべて提供されます。

dataset = ... # load something (see below)
dataset = dataset.shuffle(1000) # shuffle the dataset with a buffer of 1000
dataset = dataset.cache() # cache the dataset in RAM or on disk
dataset = dataset.repeat() # repeat the dataset indefinitely
dataset = dataset.batch(128) # batch data elements together in batches of 128
AUTOTUNE = tf.data.AUTOTUNE
dataset = dataset.prefetch(AUTOTUNE) # prefetch next batch(es) while training

パフォーマンスのヒントとデータセットのベスト プラクティスについては、こちらの記事をご覧ください。リファレンス ドキュメントはこちらです。

tf.data.Dataset の基本

データは通常、複数のファイル(ここでは画像)に含まれます。以下を呼び出して、ファイル名のデータセットを作成できます。

filenames_dataset = tf.data.Dataset.list_files('gs://flowers-public/*/*.jpg')
# The parameter is a "glob" pattern that supports the * and ? wildcards.

次に「map」を使用して各ファイル名に関数を追加します。この関数は通常、ファイルをメモリ内の実際のデータに読み込んでデコードします。

def decode_jpeg(filename):
  bits = tf.io.read_file(filename)
  image = tf.io.decode_jpeg(bits)
  return image

image_dataset = filenames_dataset.map(decode_jpeg)
# this is now a dataset of decoded images (uint8 RGB format)

データセットを反復処理するには:

for data in my_dataset:
  print(data)

タプルのデータセット

教師あり学習では通常、トレーニング データセットはトレーニング データと正解のペアで構成されます。これを可能にするために、デコード関数はタプルを返すことができます。タプルのデータセットが得られます。これに対して反復処理を行うと、タプルが返されます。返される値は、モデルで使用できる Tensorflow のテンソルです。これらに対して .numpy() を呼び出すと、未加工の値を表示できます。

def decode_jpeg_and_label(filename):
  bits = tf.read_file(filename)
  image = tf.io.decode_jpeg(bits)
  label = ... # extract flower name from folder name
  return image, label

image_dataset = filenames_dataset.map(decode_jpeg_and_label)
# this is now a dataset of (image, label) pairs 

for image, label in dataset:
  print(image.numpy().shape, label.numpy())

まとめ:画像を 1 つずつ読み込むのは時間がかかります。

このデータセットを反復処理すると、1 秒あたり 1 ~ 2 個の画像を読み込むことができることがわかります。動作が遅すぎます。トレーニングに使用するハードウェア アクセラレータは、この速度を何倍も持続できます。次のセクションに進み、この目標を達成する方法をご確認ください。

ソリューション

こちらがソリューション ノートブックです。行き詰まった場合に使用できます。

c3df49e90e5a654f.png Fun with tf.data.Dataset (solution).ipynb

学習した内容

  • 🤔? tf.data.Dataset.list_files
  • 🤔? tf.data.Dataset.map
  • 🤔? タプルのデータセット
  • 😃? データセットの反復処理

このチェックリストをぜひチェックしてみてください。

5. データの高速読み込み

このラボで使用する Tensor Processing Unit(TPU)ハードウェア アクセラレータは非常に高速です。多くの場合、仕事をこなすのに十分な速さでデータを供給することが課題です。Google Cloud Storage(GCS)は非常に高いスループットを維持できますが、他のクラウド ストレージ システムと同様に、接続の開始にはネットワーク間のコストがかかります。そのため、データを数千の個別ファイルとして保存することは理想的ではありません。少数のファイルにまとめて処理し、tf.data.Dataset を活用して複数のファイルを並行して読み取ります。

リードスルー

画像ファイルを読み込んで一般的なサイズに変更し、16 個の TFRecord ファイルに保存するコードは、次のノートブックにあります。ざっと目を通してください。この Codelab の残りの部分では、適切な TFRecord 形式のデータが提供されるため、これを実行する必要はありません。

c3df49e90e5a654f.png Flower pictures to TFRecords.ipynb

最適な GCS スループットを実現する理想的なデータ レイアウト

TFRecord ファイル形式

Tensorflow でデータの保存に推奨されるファイル形式は、protobuf ベースの TFRecord 形式です。他のシリアル化形式も機能しますが、次のように記述して、TFRecord ファイルからデータセットを直接読み込むことができます。

filenames = tf.io.gfile.glob(FILENAME_PATTERN)
dataset = tf.data.TFRecordDataset(filenames)
dataset = dataset.map(...) # do the TFRecord decoding here - see below

最適なパフォーマンスを得るには、以下の複雑なコードを使用して複数の TFRecord ファイルから一度に読み取ることをおすすめします。このコードは、N 個のファイルを並行して読み取り、読み取り速度を優先してデータの順序を無視します。

AUTOTUNE = tf.data.AUTOTUNE
ignore_order = tf.data.Options()
ignore_order.experimental_deterministic = False

filenames = tf.io.gfile.glob(FILENAME_PATTERN)
dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads=AUTOTUNE)
dataset = dataset.with_options(ignore_order)
dataset = dataset.map(...) # do the TFRecord decoding here - see below

TFRecord クイック リファレンス

TFRecord には、バイト文字列(バイトのリスト)、64 ビット整数、32 ビット浮動小数点の 3 種類のデータを格納できます。それらは常にリストとして格納され、1 つのデータ要素はサイズ 1 のリストになります。次のヘルパー関数を使用して、データを TFRecord に保存できます。

バイト文字列の書き込み

# warning, the input is a list of byte strings, which are themselves lists of bytes
def _bytestring_feature(list_of_bytestrings):
  return tf.train.Feature(bytes_list=tf.train.BytesList(value=list_of_bytestrings))

整数の書き込み

def _int_feature(list_of_ints): # int64
  return tf.train.Feature(int64_list=tf.train.Int64List(value=list_of_ints))

浮動小数点数の書き込み

def _float_feature(list_of_floats): # float32
  return tf.train.Feature(float_list=tf.train.FloatList(value=list_of_floats))

TFRecord の書き込み(上記のヘルパーを使用)

# input data in my_img_bytes, my_class, my_height, my_width, my_floats
with tf.python_io.TFRecordWriter(filename) as out_file:
  feature = {
    "image": _bytestring_feature([my_img_bytes]), # one image in the list
    "class": _int_feature([my_class]),            # one class in the list
    "size": _int_feature([my_height, my_width]),  # fixed length (2) list of ints
    "float_data": _float_feature(my_floats)       # variable length  list of floats
  }
  tf_record = tf.train.Example(features=tf.train.Features(feature=feature))
  out_file.write(tf_record.SerializeToString())

TFRecord からデータを読み取るには、まず、保存したレコードのレイアウトを宣言する必要があります。宣言では、固定長のリストまたは可変長のリストとして名前付きフィールドにアクセスできます。

TFRecords からの読み取り

def read_tfrecord(data):
  features = {
    # tf.string = byte string (not text string)
    "image": tf.io.FixedLenFeature([], tf.string), # shape [] means scalar, here, a single byte string
    "class": tf.io.FixedLenFeature([], tf.int64),  # shape [] means scalar, i.e. a single item
    "size": tf.io.FixedLenFeature([2], tf.int64),  # two integers
    "float_data": tf.io.VarLenFeature(tf.float32)  # a variable number of floats
  }

  # decode the TFRecord
  tf_record = tf.io.parse_single_example(data, features)

  # FixedLenFeature fields are now ready to use
  sz = tf_record['size']

  # Typical code for decoding compressed images
  image = tf.io.decode_jpeg(tf_record['image'], channels=3)

  # VarLenFeature fields require additional sparse.to_dense decoding
  float_data = tf.sparse.to_dense(tf_record['float_data'])

  return image, sz, float_data

# decoding a tf.data.TFRecordDataset
dataset = dataset.map(read_tfrecord)
# now a dataset of triplets (image, sz, float_data)

有用なコード スニペット:

単一のデータ要素の読み取り

tf.io.FixedLenFeature([], tf.string)   # for one byte string
tf.io.FixedLenFeature([], tf.int64)    # for one int
tf.io.FixedLenFeature([], tf.float32)  # for one float

要素の固定サイズリストの読み取り

tf.io.FixedLenFeature([N], tf.string)   # list of N byte strings
tf.io.FixedLenFeature([N], tf.int64)    # list of N ints
tf.io.FixedLenFeature([N], tf.float32)  # list of N floats

可変長のデータアイテムの読み取り

tf.io.VarLenFeature(tf.string)   # list of byte strings
tf.io.VarLenFeature(tf.int64)    # list of ints
tf.io.VarLenFeature(tf.float32)  # list of floats

VarLenFeature はスパース ベクトルを返します。TFRecord のデコード後に追加のステップが必要です。

dense_data = tf.sparse.to_dense(tf_record['my_var_len_feature'])

TFRecords にオプション フィールドを含めることもできます。フィールドの読み取り時にデフォルト値を指定した場合、そのフィールドが欠落していても、エラーの代わりにデフォルト値が返されます。

tf.io.FixedLenFeature([], tf.int64, default_value=0) # this field is optional

学習した内容

  • 🤔? データファイルをシャーディングして GCS からすばやくアクセス
  • 😝? TFRecord の書き方について確認しました。(構文を忘れた場合は、このページをクイック リファレンスとしてブックマークしておいてください)
  • 🤔? TFRecordDataset を使用して TFRecord からデータセットを読み込む

このチェックリストをぜひチェックしてみてください。

6. 完了

これで、TPU にデータをフィードできるようになりました。次のラボに進んでください。

TPU の実践

TPU と GPU は Cloud AI Platform で利用できます。

ぜひフィードバックをお寄せください。このラボで問題が見つかった場合や、改善が必要だと思われる点がありましたら、お知らせください。フィードバックは、GitHub の問題 [フィードバック リンク] からお送りいただけます。

HR.png

マーティン・ゲルナー(Martin Görner)氏、small.jpg
著者: Martin Görner
Twitter: @martin_gorner