
åçcloud.google.com
ãã³ãœã«ããã»ããµ
Habréã«ã€ããŠã¯ãTPUã®é 眮æ¹æ³ïŒ ãã¡ã ã ãã¡ã ã ãã¡ã ïŒãããã³TPUããã¥ãŒã©ã«ãããã¯ãŒã¯ã®ãã¬ãŒãã³ã°ã«é©ããŠããçç±ããã§ã«æžããŠããŸã ã ãããã£ãŠãTPUã¢ãŒããã¯ãã£ã®è©³çŽ°ãæãäžããããšã¯ããããã¥ãŒã©ã«ãããã¯ãŒã¯ããã¬ãŒãã³ã°ãããšãã«èæ ®ããå¿ èŠãããæ©èœã®ã¿ãæ€èšããŸãã
çŸåšã3äžä»£ã®ãã³ãœã«ããã»ããµããããæåŸããã³ç¬¬3äžä»£ã®TPUããã©ãŒãã³ã¹ã¯420 TFlopsïŒ1ç§éã«æ°å åã®æµ®åå°æ°ç¹æŒç®ïŒã§ã128 GBã®é«åž¯åå¹ ã¡ã¢ãªãå«ãŸããŠããŸãã ãã ããColaboratoryã§ã¯ã180 TFlopsã®ããã©ãŒãã³ã¹ãš64 GBã®ã¡ã¢ãªãåãã第2äžä»£ã®TPUã®ã¿ãå©çšå¯èœã§ãã å°æ¥ããããã®TPUãæ€èšããŸãã
ãã³ãœã«ããã»ããµã¯4ã€ã®ãããã§æ§æãããåãããã«ã¯2ã€ã®ã³ã¢ãå«ãŸããåèš8ã€ã®ã³ã¢ãTPUã«å«ãŸããŠããŸãã TPUãã¬ãŒãã³ã°ã¯ãã¬ããªã±ãŒã·ã§ã³ã䜿çšããŠãã¹ãŠã®ã³ã¢ã§äžŠè¡ããŠå®è¡ãããŸããããŒã¿ããªã¥ãŒã ã®8åã®1ãæã€TensorFlowã°ã©ãã®ã³ããŒãåã³ã¢ã§å®è¡ãããŸãã
ãã³ãœã«ããã»ããµã®åºç€ã¯ããããªãã¯ã¹ãŠãããïŒMXUïŒã§ãã è¡åã䜿çšããæäœã®å¹ççãªå®è£ ã®ããã«ã128x128ã®ã·ã¹ããªãã¯é åãæã€unningãªããŒã¿æ§é ã䜿çšããŸãã ãããã£ãŠãTPUæ©åšãªãœãŒã¹ã®äœ¿çšãæ倧åããã«ã¯ããããµã³ãã«ãŸãã¯ãã£ãŒãã£ã®å¯žæ³ã128ã®åæ°ïŒ source ïŒã§ãªããã°ãªããŸããã ãŸããTPUã¡ã¢ãªã·ã¹ãã ã®æ§è³ªã«ããããããµã³ãã«ãšãã£ãŒãã£ã®å¯žæ³ã¯8ã®åæ°ã§ããããšãæãŸããã§ãã
å ±åãã©ãããã©ãŒã
Colaboratoryã¯ãæ©æ¢°åŠç¿ãã¯ãããžãŒãé²åãããããã®Googleã®ã¯ã©ãŠããã©ãããã©ãŒã ã§ãã ãã®äžã§ã人æ°ã®ããã©ã€ãã©ãªTensorFlowãKerasãsklearnãpandasãªã©ãåããç¡æã®ä»®æ³ãã·ã³ãå ¥æã§ããŸãã æã䟿å©ãªããšã¯ãå ±åç 究宀ã§Jupyterã«äŒŒãã©ããããããå®è¡ã§ããããšã§ãã ããŒãããœã³ã³ã¯Googleãã©ã€ãã«ä¿åãããŠãããããŒãããœã³ã³ãé åžããããã³ã©ãã¬ãŒã·ã§ã³ãæŽçãããã§ããŸãã ããã¯ã©ããããããColaboratoryã§ã©ã®ããã«èŠãããã§ãïŒ åçã¯ã¯ãªãã¯å¯èœã§ã ïŒïŒ

ã³ãŒããã©ãããããã®ãã©ãŠã¶ã§èšè¿°ããGoogle Cloudã®ä»®æ³ãã·ã³ã§å®è¡ããŸãã è»ã¯12æéçºè¡ããããã®åŸåæ¢ããŸãã ãã ããå¥ã®ä»®æ³ãã·ã³ãèµ·åããããã«12æéåäœããããšã劚ãããã®ã¯ãããŸããã ä»®æ³ãã·ã³ãåæ¢ãããšãä»®æ³ãã·ã³ã®ãã¹ãŠã®ããŒã¿ãåé€ãããããšã«æ³šæããŠãã ããã ãããã£ãŠãå¿ èŠãªããŒã¿ãã³ã³ãã¥ãŒã¿ãŒãŸãã¯Googleãã©ã€ãã«ä¿åããããšãå¿ããªãã§ãã ãããä»®æ³ãã·ã³ãåèµ·åããåŸãå床ããŠã³ããŒãããŠãã ããã
å ±åãã©ãããã©ãŒã ã§ã®äœæ¥ã®è©³çŽ°ãªæé ã¯ã ãã¡ã ã ãã¡ã ã ãã¡ãã§ãã
ãã³ãœã«ããã»ããµãColaboratoryã«æ¥ç¶ããŸã
ããã©ã«ãã§ã¯ãColaboratoryã¯GPUãŸãã¯TPUèšç®ã¢ã¯ã»ã©ã¬ãŒã¿ãŒã䜿çšããŸããã ã©ã³ã¿ã€ã ->ã©ã³ã¿ã€ã ã¿ã€ãã®å€æŽ->ããŒããŠã§ã¢ã¢ã¯ã»ã©ã¬ãŒã¿ã®ã¡ãã¥ãŒã§æ¥ç¶ã§ããŸãã 衚瀺ããããªã¹ãã§ããTPUããéžæããŸãã

ã¢ã¯ã»ã©ã¬ãŒã¿ã®ã¿ã€ããéžæãããšãColaboratoryã©ããããããæ¥ç¶ãããŠããä»®æ³ãã·ã³ãåèµ·åããTPUãå©çšå¯èœã«ãªããŸãã
ä»®æ³ãã·ã³ã«ããŒã¿ãããŠã³ããŒãããå Žåãåèµ·åããã»ã¹äžã«åé€ãããŸãã ããŒã¿ãå床ããŠã³ããŒãããå¿ èŠããããŸãã
CIFAR-10èªèçšã®Kerasãã¥ãŒã©ã«ãããã¯ãŒã¯
äŸãšããŠã TIFã§Kerasãã¥ãŒã©ã«ãããã¯ãŒã¯ããã¬ãŒãã³ã°ããŠã¿ãŸããããããã¯ã CIFAR-10ããŒã¿ã»ããããç»åãèªèããŸãã ããã¯ãé£è¡æ©ãè»ãé³¥ãç«ã鹿ãç¬ãã«ãšã«ã銬ãè¹ããã©ãã¯ã®10ã¯ã©ã¹ã®ãªããžã§ã¯ãã®å°ããªç»åãå«ãäžè¬çãªããŒã¿ã»ããã§ãã ã¯ã©ã¹ã¯äº€å·®ããŸãããç»åå ã®åãªããžã§ã¯ãã¯1ã€ã®ã¯ã©ã¹ã«ã®ã¿å±ããŸãã
Kerasã䜿çšããŠCIFAR-10ããŒã¿ã»ãããããŠã³ããŒãããŸãã
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
ãã¥ãŒã©ã«ãããã¯ãŒã¯ãäœæããããã«ãå¥ã®é¢æ°ãååŸããŸããã åãã¢ãã«ã2åäœæããŸããæåã®ããŒãžã§ã³ã®TPUã¢ãã«ã§ãã¬ãŒãã³ã°ãè¡ãã2çªç®ã®ã¢ãã«ã§CPUã®ãªããžã§ã¯ããèªèããŸãã
def create_model(): input_layer = Input(shape=(32, 32, 3), dtype=tf.float32, name='Input') x = BatchNormalization()(input_layer) x = Conv2D(32, (3, 3), padding='same', activation='relu')(x) x = Conv2D(32, (3, 3), activation='relu', padding='same')(x) x = MaxPooling2D(pool_size=(2, 2))(x) x = Dropout(0.25)(x) x = BatchNormalization()(x) x = Conv2D(64, (3, 3), padding='same', activation='relu')(x) x = Conv2D(64, (3, 3), activation='relu')(x) x = MaxPooling2D(pool_size=(2, 2))(x) x = Dropout(0.25)(x) x = Flatten()(x) x = Dense(512, activation='relu')(x) x = Dropout(0.5)(x) output_layer = Dense(10, activation='softmax')(x) model = Model(inputs=[input_layer], outputs=[output_layer]) model.compile( optimizer=tf.train.AdamOptimizer(0.001), loss=tf.keras.losses.sparse_categorical_crossentropy, metrics=['sparse_categorical_accuracy']) return model
ãããŸã§ã®ãšãããKerasãªããã£ãã€ã¶ãŒã¯TPUã§äœ¿çšã§ããªããããã¢ãã«ã®ã³ã³ãã€ã«æã«TensorFlowã®ãªããã£ãã€ã¶ãŒãæå®ãããŸãã
CPUã®Kerasã¢ãã«ãäœæããŸããããã¯ã次ã®ã¹ãããã§TPUã®ã¢ãã«ã«å€æãããŸãã
cpu_model = create_model()
Kerasãã¥ãŒã©ã«ãããã¯ãŒã¯ãTPUã¢ãã«ã«å€æãã
Kerasããã³TensorFlowã®ã¢ãã«ã¯ãå€æŽãªãã§GPUã§ãã¬ãŒãã³ã°ã§ããŸãã TPUã§ã¯ãŸã ãããè¡ãããšãã§ããªããããäœæããã¢ãã«ãTPUã®ã¢ãã«ã«å€æããå¿ èŠããããŸãã
ãŸããå©çšå¯èœãªTPUã®å Žæã確èªããå¿ èŠããããŸãã å ±åãã©ãããã©ãŒã ã§ã¯ãããã¯æ¬¡ã®ã³ãã³ãã§å®è¡ã§ããŸãã
TPU_WORKER = 'grpc://' + os.environ['COLAB_TPU_ADDR']
ç§ã®å ŽåãTPUã¢ãã¬ã¹ã¯æ¬¡ã®ããã«ãªããŸãã
grpc://10.102.233.146:8470
ã æã¡äžãããšã«ã¢ãã¬ã¹ã¯ç°ãªããŸããã
ããã§ã
keras_to_tpu_model
é¢æ°ã䜿çšããŠTPUã®ã¢ãã«ãååŸã§ããŸãã
tf.logging.set_verbosity(tf.logging.INFO) tpu_model = tf.contrib.tpu.keras_to_tpu_model( cpu_model, strategy=tf.contrib.tpu.TPUDistributionStrategy( tf.contrib.cluster_resolver.TPUClusterResolver(TPU_WORKER)))
æåã®è¡ã«ã¯ãæ å ±ã¬ãã«ã§ã®ãã®ã³ã°ãå«ãŸããŸãã ã¢ãã«å€æãã°ã¯æ¬¡ã®ãšããã§ãã
INFO:tensorflow:Querying Tensorflow master (b'grpc://10.102.233.146: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
...
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.
å ã»ã©æå®ããã¢ãã¬ã¹ã§TPUãèŠã€ãã£ãããšãããããŸãã8ã³ã¢ã§ãã ãŸãã
tpu_model
ã¯å®éšçã§ããããã€ã§ãå€æŽãŸãã¯åé€ãããå¯èœæ§ããããšããèŠåã
tpu_model
ãããŸãã æéããããŠãå€æããã«Kerasã¢ãã«ãTPUã§çŽæ¥ãã¬ãŒãã³ã°ã§ããããšãé¡ã£ãŠããŸãã
TPUã§ã¢ãã«ããã¬ãŒãã³ã°ããŸã
TPUã®ã¢ãã«ã¯ã
fit
ã¡ãœãããåŒã³åºãããšã§Kerasã®éåžžã®æ¹æ³ã§ãã¬ãŒãã³ã°ã§ããŸãã
history = tpu_model.fit(x_train, y_train, batch_size=128*8, epochs=50, verbose=2)
ããã®æ©èœã¯äœã§ããã TPUãå¹æçã«äœ¿çšããã«ã¯ããããµã³ãã«ãµã€ãºã128ã®åæ°ã§ããå¿ èŠããããŸããããã«ããããµã³ãã«ã®ãã¹ãŠã®ããŒã¿ã®8åã®1ã䜿çšããŠåTPUã³ã¢ã§ãã¬ãŒãã³ã°ãå®è¡ãããŸãã ãããã£ãŠããã¬ãŒãã³ã°äžã®ãããµã³ãã«ã®ãµã€ãºã128 * 8ã«èšå®ããåTPUã³ã¢ã«å¯ŸããŠ128æã®ç»åãååŸããŸãã 256ãŸãã¯512ãªã©ã®ãã倧ããªãµã€ãºã䜿çšã§ããããã©ãŒãã³ã¹ãåäžããŸãã
ç§ã®å Žåã1ã€ã®æ代ã®èšç·Žã«ã¯å¹³å6ç§ããããŸãã
50äžçŽã®æè²ã®è³ªïŒ
Epoch 50/50
- 6s - loss: 0.2727 - sparse_categorical_accuracy: 0.9006
ãã¬ãŒãã³ã°çšããŒã¿ã«å¯Ÿããæ£è§£ã®å²åã¯90.06ïŒ ã§ããã TPUã䜿çšããŠãã¹ãããŒã¿ã®å質ããã§ãã¯ããŸãã
scores = tpu_model.evaluate(x_test, y_test, verbose=0, batch_size=batch_size * 8) print(" : %.2f%%" % (scores[1]*100))
: 80.79%
ããã§ãåŠç¿æžã¿ã¢ãã«ã®éã¿ãä¿åããŸãã
tpu_model.save_weights("cifar10_model.h5")
TensorFlowã¯ãéã¿ãTPUããCPUã«è»¢éããããšããã¡ãã»ãŒãžãæäŸããŸãã
INFO:tensorflow:Copying TPU weights to the CPU
èšç·Žããããããã¯ãŒã¯ã®éã¿ã¯ãå ±åç 究仮æ³ãã·ã³ã®ãã£ã¹ã¯ã«ä¿åãããããšã«æ³šæããŠãã ããã ä»®æ³ãã·ã³ãåæ¢ãããšããã®ä»®æ³ãã·ã³ããã®ãã¹ãŠã®ããŒã¿ãæ¶å»ãããŸãã èšç·Žãããééã倱ããããªãå Žåã¯ãã³ã³ãã¥ãŒã¿ãŒã«ä¿åããŸãã
from google.colab import files files.download("cifar10_model.h5")
CPUäžã®ãªããžã§ã¯ããèªèãã
CPUã䜿çšããŠç»åå ã®ãªããžã§ã¯ããèªèããããã«ãTPUã§ãã¬ãŒãã³ã°ãããã¢ãã«ã䜿çšããŠã¿ãŸãããã ãããè¡ãã«ã¯ãã¢ãã«ãå床äœæããTPUã§ãã¬ãŒãã³ã°ããããŠã§ã€ããã¢ãã«ã«ããŒãããŸãã
model = create_model() model.load_weights("cifar10_model.h5")
ã¢ãã«ã¯äžå€®åŠçè£ çœ®ã§äœ¿çšããæºåãã§ããŠããŸãã CIFAR-10ãã¹ãã¹ã€ãŒãã®ç»åã®1ã€ããã®å©ããåããŠèªèããŠã¿ãŸãããã
index=111 plt.imshow(toimage(x_test[index])) plt.show()

åçã¯å°ããã§ãããããã¯é£è¡æ©ã§ããããšãç解ã§ããŸãã èªèãéå§ããŸãã
# CIFAR-10 classes=['', '', '', '', '', '', '', '', '', ''] x = x_test[index] # , .. Keras x = np.expand_dims(x, axis=0) # prediction = model.predict(x) # print(prediction) # prediction = np.argmax(prediction) print(classes[prediction])
ãã¥ãŒãã³ã®åºåå€ã®ãªã¹ããååŸããŸãããã¬ãŒã³ã«å¯Ÿå¿ããæåã®å€ãé€ããã»ãšãã©ãã¹ãŠã®ãã¥ãŒãã³ã¯ãŒãã«è¿ãå€ã§ãã
[[9.81738389e-01 2.91262069e-07 1.82225723e-02 9.78524668e-07
5.89265142e-07 6.76223244e-10 1.03252004e-10 9.23009047e-09
3.71878523e-05 3.16599618e-08]]
èªèã«æåããŸããïŒ
ãŸãšã
Colaboratoryãã©ãããã©ãŒã ã§TPUã®æäœæ§ãå®èšŒããããšãå¯èœã§ãããKerasã®ãã¥ãŒã©ã«ãããã¯ãŒã¯ã®ãã¬ãŒãã³ã°ã«äœ¿çšã§ããŸãã ãã ããCIFAR-10ããŒã¿ã»ããã¯å°ãããããããTPUãªãœãŒã¹ãå®å šã«ããŒãããã«ã¯äžååã§ãã GPUãšæ¯èŒããå éã¯å°ããããšãå€æããŸããïŒTPUã®ä»£ããã«GPUãã¢ã¯ã»ã©ã¬ãŒã¿ãŒãšããŠéžæããã¢ãã«ãå床ãã¬ãŒãã³ã°ããããšã§ç¢ºèªã§ããŸãïŒã
Habréã«ã¯ãResNet-50ãããã¯ãŒã¯ã®ãã¬ãŒãã³ã°ã«é¢ããTPUããã³GPU V100ã®ããã©ãŒãã³ã¹ã枬å®ããèšäºããããŸã ã ãã®ã¿ã¹ã¯ã§ãTPUã¯4ã€ã®V100 GPUãšåãããã©ãŒãã³ã¹ã瀺ããŸããã Googleããã®ãããªåŒ·åãªãã¥ãŒã©ã«ãããã¯ãŒã¯åŠç¿ã¢ã¯ã»ã©ã¬ãŒã¿ãç¡æã§æäŸããŠããã®ã¯ãã°ãããããšã§ãã
TPUã§ã®Kerasãã¥ãŒã©ã«ãããã¯ãŒã¯ãã¬ãŒãã³ã°ã瀺ããããªã
䟿å©ãªãªã³ã¯
- å®å šãªKeras TPUã¢ãã«åŠç¿ã³ãŒããåããå ±åç 究çšã©ããããã ã
- ãã¡ãã·ã§ã³MNISTã®æãšéŽãèªèããããã®Keras TPUãã¬ãŒãã³ã°ãµã³ãã«ä»ãã®å ±åããŒã ã
- Google Cloudã®Tensorããã»ããµ ã
- ã¢ãŒããã¯ãã£ã®ç¹åŸŽãšãã³ãœã«ããã»ããµã®äœ¿çš ã