【秒速で無料GPUを使う】TensorFow(Keras)/PyTorch/Chainer環境構築 on Colaboratory

> **2019/5/11 PR:** こちらの内容を含め、2019年5月11日発刊の :books: [図解速習DEEP LEARNING](https://amzn.to/2J0QNGF)という本ができました。[[2019年5月版] 機械学習・深層学習を学び、トレンドを追うためのリンク150選 - Qiita](https://qiita.com/tomo_makes/items/cd036e2444a938416316)でも、一部内容をご覧いただけます :smile:

> **19/1/11** 18年1月の公開後、TensorFlow本体にKeras統合、Chainerがデフォルトで提供となるなど、状況が変化したため、大幅に加筆しました。TensorFlow 2.0 Previewについても追記しました。

> **19/1/31** PyTorchが標準インストールとなったこと、PyTorch/ TensorFlowのColab版チュートリアルを追記。

> **2019/3/9** [Colaboratoryに関する情報交換Slack](https://join.slack.com/t/colab-jp/shared_invite/enQtNTcxNzAzMzM5OTg2LTY1ZWI4NTVkNDNjMGMxNjI3ZDM0NmZlZTg1OTFjZDcwOGUxNTY5MGQ0NWZiMWU0NWQ5MTZhMWQxZGRjMWZlYjQ)を試験的に立ち上げました。リンクより、登録・ご参加ください。


# TL;DR

- Google Colabで新たに無料でGPU環境が使えるようになった
    - K80, 連続12hr利用可能
- お金も構築時間もショートカット
    - クラウドで自分でGPUインスタンス借りて構築しなくていい
    - GPUパソコン組み立てなくてもいい
- こんな感じで、ノー準備で下記代表的なフレームワークが動かせる
    - ![image.png](https://qiita-image-store.s3.amazonaws.com/0/64608/c12e0e12-8cce-77dc-8777-773ac14e2643.png)
- ちょっとしたhands onをやったりするのに最適
- 実践時のTipsをまとめました - [【秒速で無料GPUを使う】深層学習実践Tips on Colaboratory - Qiita](https://qiita.com/tomo_makes/items/b3c60b10f7b25a0a5935)

# はじめに

Google Colabで、【無料で】FreeでK80相当GPUを1回12hrまで使えるっていうすばらしいtweetが流れてきた。

<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Ummmm, Colab now lets you use GPUs to accelerate your notebooks? In the cloud? For free? 😍🤓😍🤓😍🤓 Step-by-step how to: <a href="https://t.co/CENGVweaTy">https://t.co/CENGVweaTy</a></p>&mdash; Rachael Tatman (@rctatman) <a href="https://twitter.com/rctatman/status/954434142531276800?ref_src=twsrc%5Etfw">January 19, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

クラウドでGPUインスタンス借りなくてもいいし、最初からGPUパソコン組み立てなくてもいい。お金も構築時間もショートカットできる。

初学者のハードルがめちゃ下がる。すばらしい。なので軽いTutorialを書く。


# 前提
## 割当てリソース

- [What's the hardware spec for Google Colaboratory? - Stack Overflow](https://stackoverflow.com/questions/47805170/whats-the-hardware-spec-for-google-colaboratory)

などを参考に、colaboratoryの提供環境は下記の通り(20181016更新):

- n1-highmem-2 instance
- Ubuntu 18.04
- 2vCPU @ 2.2GHz
- **13GB RAM**
- **(GPUなし/ TPU)40GB, (GPUあり)360GB Storage**
- **GPU NVIDIA Tesla K80 12GB**
- **アイドル状態が90分続くと停止**
- **連続使用は最大12時間**
- **Notebookサイズは最大20MB**

雑感としては:

- それなりのサイズのdatasetをdisk上に持ってこれる
- RAMはそんなにないので、Pythonのarrayでメモリ上に持っておく量は加減が必要
    - epochで使うdatasetが大量ならbatch毎に読み込むとか
- tutorialとかをこなすには十分

という感じ。


`!cat /etc/issue`

```bash
Ubuntu 18.04.1 LTS \n \l
```

`!df -h` (GPUありでの例)

```bash
Filesystem      Size  Used Avail Use% Mounted on
overlay         359G  9.4G  331G   3% /
...
```

`!free -h`

```
              total        used        free      shared  buff/cache   available
Mem:            12G        391M        6.6G        828K        5.7G         12G
Swap:            0B          0B          0B
```

`!cat /proc/cpuinfo` (GPUありでの例)

```bash
processor	: 0
...
model name	: Intel(R) Xeon(R) CPU @ 2.20GHz
...
cpu MHz		: 2200.000
cache size	: 56320 KB
...

processor	: 1
...
model name	: Intel(R) Xeon(R) CPU @ 2.20GHz
...
cpu MHz		: 2200.000
cache size	: 56320 KB
...
```

`!cat /proc/driver/nvidia/gpus/0000:00:04.0/information`　 (GPUありでの例)

```bash
Model: 		 Tesla K80
IRQ:   		 33
...
```

```py3
from tensorflow.python.client import device_lib
device_lib.list_local_devices()

[name: "/device:CPU:0"
 device_type: "CPU"
 memory_limit: 268435456
 locality {
 }
 incarnation: 14142945018355836735, name: "/device:GPU:0"
 device_type: "GPU"
 memory_limit: 358416384
 locality {
   bus_id: 1
 }
 incarnation: 7915847976140889213
 physical_device_desc: "device: 0, name: Tesla K80, pci bus id: 0000:00:04.0, compute capability: 3.7"]
```

`!nvcc -v` (GPUありでCUDAバージョンの確認)

```
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2018 NVIDIA Corporation
Built on Tue_Jun_12_23:07:04_CDT_2018
Cuda compilation tools, release 9.2, V9.2.148
```

`!nvidia-smi` (GPUありでアサインGPU、Driverの確認)

```
Thu Jan 31 xx:xx:xx 2019       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 396.44                 Driver Version: 396.44                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla K80           Off  | 00000000:00:04.0 Off |                    0 |
| N/A   30C    P8    26W / 149W |     11MiB / 11441MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+
```

# 試し方
## Google Colabを開く

https://colab.research.google.com/

## 新規ノートブックを作成

`ファイル` > `Python3の新しいノートブック` を選ぶ。

## GPUをアサイン

- 画面上部のメニュー `ランタイム` > `ランタイムのタイプを変更` で、 `ノートブックの設定` を開く
- ハードウェアアクセラレータに `GPU` を選択し、 `保存` する

## GPUが正しくアサインされたか確認

- `[+]コード` から、コード入力用のセルを追加する
- セルに下記を入力

```py3
import tensorflow as tf
tf.test.gpu_device_name()
```

- 下記が出力されると、正しくGPUがアサインされている(backend GPUが足りないとエラーになることもあるらしい)

```
'/device:GPU:0'
```


# TensorFlow
## 環境準備

TensorFlow 1.x系は、準備不要ですぐ使える。
2.0系はPreviewが始まっています。興味がある方は、[TensorFlow 2.0 Previewを最速で試す on Colaboratory - Qiita](https://qiita.com/tomo_makes/items/9c22f306f1b781e8a7c2)から試してみてください。

## CPU/GPUのパフォーマンスを比較

畳み込みをCPUとGPUで比較する下記コードを実行する。同様にコード入力用セルを追加し、コードを貼り付け、実行する。

> https://www.kaggle.com/getting-started/47096#post271139 より引用

```py3
import tensorflow as tf
import timeit

# See https://www.tensorflow.org/tutorials/using_gpu#allowing_gpu_memory_growth
config = tf.ConfigProto()
config.gpu_options.allow_growth = True

with tf.device('/cpu:0'):
  random_image_cpu = tf.random_normal((100, 100, 100, 3))
  net_cpu = tf.layers.conv2d(random_image_cpu, 32, 7)
  net_cpu = tf.reduce_sum(net_cpu)

with tf.device('/gpu:0'):
  random_image_gpu = tf.random_normal((100, 100, 100, 3))
  net_gpu = tf.layers.conv2d(random_image_gpu, 32, 7)
  net_gpu = tf.reduce_sum(net_gpu)

sess = tf.Session(config=config)

# Test execution once to detect errors early.
try:
  sess.run(tf.global_variables_initializer())
except tf.errors.InvalidArgumentError:
  print(
      '\n\nThis error most likely means that this notebook is not '
      'configured to use a GPU.  Change this in Notebook Settings via the '
      'command palette (cmd/ctrl-shift-P) or the Edit menu.\n\n')
  raise

def cpu():
  sess.run(net_cpu)

def gpu():
  sess.run(net_gpu)

# Runs the op several times.
print('Time (s) to convolve 32x7x7x3 filter over random 100x100x100x3 images '
      '(batch x height x width x channel). Sum of ten runs.')
print('CPU (s):')
cpu_time = timeit.timeit('cpu()', number=10, setup="from __main__ import cpu")
print(cpu_time)
print('GPU (s):')
gpu_time = timeit.timeit('gpu()', number=10, setup="from __main__ import gpu")
print(gpu_time)
print('GPU speedup over CPU: {}x'.format(int(cpu_time/gpu_time)))

sess.close()
```

下記のような結果が得られる。GPUで、9倍速かったって。

```
Time (s) to convolve 32x7x7x3 filter over random 100x100x100x3 images (batch x height x width x channel). Sum of ten runs.
CPU (s):
8.584801190000007
GPU (s):
0.8974968620000254
GPU speedup over CPU: 9x
```

## チュートリアル

[TensorFlow Tutorials](https://www.tensorflow.org/tutorials/)は、各項目の `Run in Google Colab` ボタンを押すと、すぐに実行して試すことができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/64608/45302bf4-06c3-de47-e879-da81f3bcf0b0.png)


## 色々な事例を試す

[【即スマホで試せる】55の深層学習実装 on Google Seedbank - 画像分類から翻訳、音楽生成まで - Qiita](https://qiita.com/tomo_makes/items/e5a309687f5054ba471f)から、様々な事例を試してみましょう。

# Keras
## 環境準備

Kerasは、公式にTensorFlowに含まれるモジュールとなったため、別途インストールする必要はなくなりました。

```py3
from tensorflow import keras
```

## Fashion MNIST分類を試す

[Seedbank: "Fashion MNIST with tf.keras"](https://research.google.com/seedbank/seed/5648554290839552)こちらから、Kerasを用いた画像分類を試すことができます。



# PyTorch
## 環境準備

19年1月から、PyTorchが、準備不要ですぐに使えるようになりました。

~~必要なライブラリをpip installする。~~
~~ただし、OS/Python/CUDAバージョン毎にインストール方法が異なることがある。Python/CUDAバージョンをチェックのうえ、[PyTorch](https://pytorch.org/)から、~~

- ~~Pytorch build: (選びたいver.)~~
- ~~Stable OS: Linux~~
- ~~Package: Pip~~

~~を選んだ上で、該当のPython/CUDAバージョンに合ったインストールコマンドを確認する。~~


## バージョン、GPUがenabledか確認

下記を実行する。

```py3
import torch
torch.cuda.is_available()
```

`True` が返ればGPUがPyTorchから使えている。

```py3
print(torch.__version__)
```

`1.0.0` など、プリインストールバージョンが表示される。


## サンプルコードの実行(CIFAR10 CNN Classifier)

[Training a classifier — PyTorch Tutorials 1.1.0 documentation](http://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html#loading-and-normalizing-cifar10) のコードを、 [【詳細（？）】pytorch入門　〜CIFAR10をCNNする〜 - Qiita](https://qiita.com/kazetof/items/6a72926b9f8cd44c218e) を参考に逐次実行してみる。

正しく学習できることが確認できた。

```
[1,  2000] loss: 2.220
[1,  4000] loss: 1.863
[1,  6000] loss: 1.697
[1,  8000] loss: 1.588
[1, 10000] loss: 1.509
[1, 12000] loss: 1.466
[2,  2000] loss: 1.375
[2,  4000] loss: 1.357
[2,  6000] loss: 1.339
[2,  8000] loss: 1.306
[2, 10000] loss: 1.306
[2, 12000] loss: 1.288
Finished Training
```

## チュートリアル

PyTorchは、[公式ページのチュートリアル](https://pytorch.org/tutorials/)が充実しています。
また、その内容をColaboratoryへポーティングしているリポジトリ([param087/Pytorch-tutorial-on-Google-colab: PyTorch Tutorial on google colaboratory.](https://github.com/param087/Pytorch-tutorial-on-Google-colab))があり、便利です。


# Chainer
## 環境準備

18年12月より、Chainer, バックエンドのCuPy, iDeepが準備不要ですぐ使えるようになりました。

```py3
import chainer
chainer.print_runtime_info()
```

下記が返されます。

```py
Platform: Linux-4.14.79+-x86_64-with-Ubuntu-18.04-bionic
Chainer: 5.0.0
NumPy: 1.14.6
CuPy:
  CuPy Version          : 5.0.0
  CUDA Root             : /usr/local/cuda
  CUDA Build Version    : 9020
  CUDA Driver Version   : 9020
  CUDA Runtime Version  : 9020
  cuDNN Build Version   : 7201
  cuDNN Version         : 7201
  NCCL Build Version    : 2213
iDeep: 2.0.0.post3
```


## チュートリアル

[Chainer community](https://chainer.connpass.com/)ではColabを使ったハンズオンを作成されています。

github: [chainer-community/chainer-colab-notebook](https://github.com/chainer-community/chainer-colab-notebook)
google drive: [chainer-colab-notebook](https://drive.google.com/drive/u/0/folders/1GdwW9HmKfKfo6E-K81YKuURh-XheCGDR)

また、2018年12月には、このような素晴らしい資料が公開されました。

- [メディカルAI専門コース オンライン講義資料 — メディカルAI専門コース オンライン講義資料 ドキュメント](https://japan-medical-ai.github.io/medical-ai-course-materials/)


# 他のプリインストールパッケージ

下記コマンドで確認できます。

```bash
!pip list
```


# まとめ

- Google Colabで新たに無料でGPU環境が使えるようになった
    - K80, 連続12hr利用可能
- お金も構築時間もショートカット
    - クラウドで自分でGPUインスタンス借りて構築しなくていい
    - GPUパソコン組み立てなくてもいい
- 下記代表的なフレームワークが動かせる
    - TensorFlow (Keras)
    - PyTorch
    - Chainer
- ちょっとしたhands onをやったりするのに最適
- 実践時のTipsをまとめました - [【秒速で無料GPUを使う】深層学習実践Tips on Colaboratory - Qiita](https://qiita.com/tomo_makes/items/b3c60b10f7b25a0a5935)


# 次のステップ

Colaboratory関係のリンク集です。次何やろうかな、のネタになりましたら幸いです。また、こんなんやったよ!ネタをぜひお寄せください。


- はやぶさの技術ノート
    - 懇切丁寧な解説で注目を集めた[【深層学習入門】画像処理の基礎(画素操作)からCNN設計まで](https://cpp-learning.com/operate_pixel/)の著者 はやぶささんのColaboratory解説記事。本記事では触れられていないところも含めスクリーンショットをふんだんに使った分かりやすいガイドで始められます。
    - [環境構築不要でPython入門！Google Colaboratoryの使い方を分かりやすく説明](https://cpp-learning.com/python_colaboratory/)
    - [ColaboratoryでChainer使ってYoloを動かす](https://cpp-learning.com/colaboratory_chainer_yolo/)
    - [【深層学習入門】超実践！Chainerと深層学習でシステム解析する方法](https://cpp-learning.com/deep-learning_analysis/)
- [ディープラーニングに入門するためのリソース集と学習法（2018年版） - Qiita](https://qiita.com/keitakurita/items/df3a07135c9cfad810c7)
    - はじめやすいのはわかったけど、何から始めたらよいか、という方にはこちらがおすすめです。プロジェクトを通した学習、fast.ai推しなど、私も同様にはじめたので共感するところが多くありました。
- [【無料】4大深層学習フレームワークをGPU版Colaboratoryとlocaltunnelで使い倒そう【簡単】 - Qiita](https://qiita.com/stakemura/items/1761be70a06fa8ee853f)
    - 同一条件下での各フレームワーク比較、Tensorboardの使用方法などコンパクトにまとまった良記事です。MXNet, Sonnetの導入方法もあり
- [【秒速で無料GPUを使う】深層学習実践Tips on Colaboratory - Qiita](https://qiita.com/tomo_makes/items/b3c60b10f7b25a0a5935)
    - 使い始めたら色々と出るハマりどころについてTipsをまとめました
- [Google Colaboratoryが便利・高速で凄過ぎる - Itsukaraの日記](http://itsukara.hateblo.jp/entry/2018/02/05/214949)
    - Wide Residual Networks。Google Driveへのファイル退避を使った12+4=16時間の学習事例
- [ChainerRL を Colaboratory で動かす - Qiita](https://qiita.com/ikeyasu/items/ec3c88ce13a2d5e41f26#_reference-8177d44ddfcaf525a6cd)
    - Chainerを使った強化学習、Colaboratory上でのアニメーション確認まで行えます
- [Colaboratoryで10秒で起動できる、ChainerのGitHubレポジトリ作ってみた - Qiita](https://qiita.com/keisuke-umezawa/items/4e99c2a4f5f07567444c)
    - GitHub上でnotebookをどうバージョン管理するか。また、Travis CIでGoogle Driveへ連携する方法、ハマりどころの解説。[chainer-colab-notebook](https://github.com/chainer-community/chainer-colab-notebook)へ今後tutorialが集積されていくとのこと。

# 参考

下記の記事を参考にさせていただきました。ありがとうございます!

- [Kaggle: Your Home for Data Science](https://www.kaggle.com/getting-started/47096#post271139)
    - Google中の人? Michael Piatekさんが色々制約など答えてくれているkaggle forumスレッド
- [Training a classifier — PyTorch Tutorials 0.3.0.post4 documentation](http://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html#loading-and-normalizing-cifar10)
    - pytorchのサンプルコードに活用しました
- [【詳細（？）】pytorch入門　〜CIFAR10をCNNする〜 - Qiita](https://qiita.com/kazetof/items/6a72926b9f8cd44c218e)
    - 上記tutorialへのポインタ、詳細の説明を参照しました