LoginSignup
6
3

More than 5 years have passed since last update.

GoogleのTPUを使って、佐藤健と亀梨和也を人よりも賢く見分けたい

Last updated at Posted at 2018-10-01

こちらで、Google ColaboratoryでTPUが使えるようになったと知り、早速試してみました。

元のコード等はこちら

設定

これは簡単。
GPUからTPUに変更するだけ。
image01.png

Googleドライブのマウント

以前書いたコードのまま実行しようとしたところ、エラーに。

E: Unable to locate package google-drive-ocamlfuse

調べてみるとこちらに情報が。
そっか、簡単になっていたのね。

from google.colab import drive
drive.mount('/content/drive')

この修正に関連して、パスが変わった(「drive/xxx」→「drive/My Drive/xxx」)ので、そこだけはコードを変更します。

とりあえずそのまま実行

Kerasのパスとか変更しなくてはいけないことはわかっているが、エラーになる体験もしてみたいので、そのまま実行。

Downloading data from https://github.com/fchollet/deep-learning-models/releases/download/v0.5/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5
87916544/87910968 [==============================] - 7s 0us/step
Train on 162 samples, validate on 18 samples
Epoch 1/1000
162/162 [==============================] - 248s 2s/step - loss: 0.6976 - acc: 0.5617 - val_loss: 0.6406 - val_acc: 0.7222
Epoch 2/1000
 64/162 [==========>...................] - ETA: 2:13 - loss: 0.5129 - acc: 0.7812

おや?変な動きだけど、エラーにはならない...というか、すごく遅い!
一旦止めて、もう一度やり直してみる、が遅い状況は変わらず。

コードを修正する

ということで、「keras」を「tensorflow.keras」に置き換えて、実行し直しています。

Train on 162 samples, validate on 18 samples
Epoch 1/1000
162/162 [==============================] - 239s 1s/step - loss: 0.7062 - acc: 0.5309 - val_loss: 0.7075 - val_acc: 0.5556
Epoch 2/1000
 64/162 [==========>...................] - ETA: 2:15 - loss: 0.5428 - acc: 0.8281

はて?変わらず遅いままだぞ??
※実行速度もほとんど変わっていない
TPUの恩恵を受けているどころか、GPUよりも遥かに(140倍!)遅い...

修正漏れ発見

じっくりと確認してみたところ、他にも修正が必要なところがあることがわかりました。

from tensorflow.contrib.tpu.python.tpu import keras_support

# 途中省略

# TPU
tpu_grpc_url = "grpc://"+os.environ["COLAB_TPU_ADDR"]
tpu_cluster_resolver = tf.contrib.cluster_resolver.TPUClusterResolver(tpu_grpc_url)
strategy = keras_support.TPUDistributionStrategy(tpu_cluster_resolver)
model = tf.contrib.tpu.keras_to_tpu_model(model, strategy=strategy)

再度実行してみたところ、今度はエラーが発生。

ValueError: 
Layer <tensorflow.python.keras.engine.input_layer.InputLayer object at 0x7febf3fdfef0> has a variable shape in a non-batch dimension.  TPU models must
have constant shapes for all operations.

You may have to specify `input_length` for RNN/TimeDistributed layers.

Layer: <tensorflow.python.keras.engine.input_layer.InputLayer object at 0x7febf3fdfef0>
Input shape: (None, None, None, 3)
Output shape: (None, None, None, 3)

InceptionV3(tensorflow.keras.applications.inception_v3.InceptionV3)を使用しているのですが、ちゃんとinput_shapeを明記してあげないといけないようです。

base_model = InceptionV3(weights='imagenet', include_top=False, input_shape=(299,299,3))

しかしまだエラーが。

AssertionError: batch_size must be divisible by strategy.num_towers (52 vs 8)

はて、指定しているバッチサイズは「64」なんだけど...
あ、学習データが90枚×2種類で180枚、64バッチで学習させるから、余りが52ってことか?
では合計128枚(64枚×2)にして、64バッチにして...へ?ダメ???
ではでは合計160枚にして、16枚評価用にして、バッチサイズを72にすると...

INFO:tensorflow:Querying Tensorflow master (b'grpc://10.104.87.194:8470') for TPU system metadata.
INFO:tensorflow:Found TPU system:
INFO:tensorflow:*** Num TPU Cores: 8
INFO:tensorflow:*** Num TPU Workers: 1
INFO:tensorflow:*** Num TPU Cores Per Worker: 8
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:CPU:0, CPU, -1, 13775578281952910176)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:XLA_CPU:0, XLA_CPU, 17179869184, 11472039453562412302)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:XLA_GPU:0, XLA_GPU, 17179869184, 16699149825347599599)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:0, TPU, 17179869184, 12947970202392715099)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:1, TPU, 17179869184, 5831191770111493889)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:2, TPU, 17179869184, 12266886104312379857)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:3, TPU, 17179869184, 12195656273203857672)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:4, TPU, 17179869184, 5342099664455282737)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:5, TPU, 17179869184, 4909200579248859706)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:6, TPU, 17179869184, 6257043378114727165)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:7, TPU, 17179869184, 11756941070616601390)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU_SYSTEM:0, TPU_SYSTEM, 17179869184, 2180101584340784034)
WARNING:tensorflow:tpu_model (from tensorflow.contrib.tpu.python.tpu.keras_support) is experimental and may change or be removed at any time, and without warning.
Train on 160 samples, validate on 16 samples
Epoch 1/1000
INFO:tensorflow:New input shapes; (re-)compiling: mode=train, [TensorSpec(shape=(9, 299, 299, 3), dtype=tf.float32, name='input_20'), TensorSpec(shape=(9, 1), dtype=tf.float32, name='dense_3_target_10')]
INFO:tensorflow:Overriding default placeholder.
INFO:tensorflow:Remapping placeholder for input_2
INFO:tensorflow:Cloning SGD {'lr': 0.009999999776482582, 'momentum': 0.8999999761581421, 'decay': 0.0, 'nesterov': False}
INFO:tensorflow:Get updates: Tensor("loss_1/add:0", shape=(), dtype=float32)
INFO:tensorflow:Started compiling
INFO:tensorflow:Finished compiling. Time elapsed: 93.16143774986267 secs
INFO:tensorflow:Setting weights on TPU model.
 72/160 [============>.................] - ETA: 2:56 - loss: 0.6279 - acc: 0.5556INFO:tensorflow:New input shapes; (re-)compiling: mode=train, [TensorSpec(shape=(2, 299, 299, 3), dtype=tf.float32, name='input_20'), TensorSpec(shape=(2, 1), dtype=tf.float32, name='dense_3_target_10')]
INFO:tensorflow:Overriding default placeholder.
INFO:tensorflow:Remapping placeholder for input_2
INFO:tensorflow:Cloning SGD {'lr': 0.009999999776482582, 'momentum': 0.8999999761581421, 'decay': 0.0, 'nesterov': False}
INFO:tensorflow:Get updates: Tensor("loss_2/add:0", shape=(), dtype=float32)
INFO:tensorflow:Started compiling
INFO:tensorflow:Finished compiling. Time elapsed: 52.98347616195679 secs
144/160 [==========================>...] - ETA: 30s - loss: 0.6840 - acc: 0.5000 INFO:tensorflow:New input shapes; (re-)compiling: mode=eval, [TensorSpec(shape=(2, 299, 299, 3), dtype=tf.float32, name='input_20'), TensorSpec(shape=(2, 1), dtype=tf.float32, name='dense_3_target_10')]
INFO:tensorflow:Overriding default placeholder.
INFO:tensorflow:Remapping placeholder for input_2
INFO:tensorflow:Cloning SGD {'lr': 0.009999999776482582, 'momentum': 0.8999999761581421, 'decay': 0.0, 'nesterov': False}
INFO:tensorflow:Started compiling
INFO:tensorflow:Finished compiling. Time elapsed: 43.58580756187439 secs
160/160 [==============================] - 327s 2s/step - loss: 0.6705 - acc: 0.5500 - val_loss: 0.8207 - val_acc: 0.5000
(以下、省略)

(何故か)動いた!
が、始まるまでが遅い!!(苦笑)
TPU用のバイナリに変換するのが遅い模様。

識別してみたが...

一枚づつ識別しようとしたら、また

AssertionError: batch_size must be divisible by strategy.num_towers (1 vs 8)

のエラーが...
あぁ、めんどくさい(爆)

感想

簡単に動かせるかと思ったら、結構ハマるポイントがありました。
モデルによってはもっとありそうな感じです。

もう少しいじってみたいと思います。

6
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3