tensorflowでGPUを使う設定(Anacondaを使用)

# はじめに

tensorflowでGPUを使用するためには、使用するtensorflowのバージョンに合わせてCUDAやcuDNNをインストールする必要がある。

以前にその設定をする記事も書いていた。

https://qiita.com/tatsuki1119/items/f56c4dfdcdfe55e8341e

しかし、[こちらの記事](https://qiita.com/ktokey/items/7ee9c112198a6b0b5709)を見てみると、Anacondaで仮想環境ごとにcudatoolkitとcudnnが付属したtensorflowをインストールして使用できるとのこと。

ということで実際に試してみた。

**※先に結論から言うと、めっちゃ簡単にGPU使って学習ができる。condaが天才すぎた。**

# CUDAとcuDNN付きのtensorflowのインストール方法

バージョン2.10のtensorflowをインストールする場合、

```
conda install tensorflow=2.10.*=gpu_*
```

と実行することで、CUDAとcuDNNが付属した状態のtensorflowがインストールできる。


# 試してみる

## バージョン

Python 3.9.15
tensorflow 2.10.0
cudatoolkit 11.3.1(自動)
cudnn 8.2.1(自動)

## 仮想環境の作成

```
conda create -n tf210 python=3.9

conda activate tf210
```

## tensorflowのインストール

```
conda install tensorflow=2.10.*=gpu_*
```

多くのパッケージがインストールされる。`conda list`すると、cudatoolkitやcudnnが入っていることが分かる。

## GPUの確認

適当にpyファイルを作成して以下のコードを実行する。

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

```:output
2023-01-15 23:14:59.181193: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2023-01-15 23:14:59.826244: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1616] Created device /device:GPU:0 with 3976 MB memory:  -> device: 0, name: NVIDIA GeForce GTX 1660 SUPER, pci bus id: 0000:01:00.0, compute capability: 7.5
```

GPU（私が使っているのは、GeForce GTX 1660 SUPER）が正しく認識されていることが分かる。

## 試しにmnistで学習してみる

```python:mnist_test.py
import time
import tensorflow
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras.callbacks import EarlyStopping

(x_train, y_train), (x_test, y_test) = tensorflow.keras.datasets.mnist.load_data()

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255

y_train = tensorflow.keras.utils.to_categorical(y_train, 10)
y_test = tensorflow.keras.utils.to_categorical(y_test, 10)

start_time = time.time()  # スタート時間計測

model.compile(loss='categorical_crossentropy',
              optimizer=RMSprop(),
              metrics=['accuracy'])


history = model.fit(x_train, y_train,
                    # batch_size=128,
                    epochs=10,
                    verbose=1,
                    validation_data=(x_test, y_test),
                    callbacks=[EarlyStopping(patience=1, verbose=1)])

score = model.evaluate(x_test, y_test, verbose=0)
print('loss:', score[0])
print('accuracy:', score[1])

end_time = time.time() - start_time  # 終了時間を計測
print("学習時間：", str(round(end_time, 3)), "秒でした。")
```

```:output
2023-01-15 23:18:30.770655: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2023-01-15 23:18:31.392013: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1616] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 3976 MB memory:  -> device: 0, name: NVIDIA GeForce GTX 1660 SUPER, pci bus id: 0000:01:00.0, compute capability: 7.5
Epoch 1/10
2023-01-15 23:18:33.175721: I tensorflow/stream_executor/cuda/cuda_dnn.cc:384] Loaded cuDNN version 8201
1875/1875 [==============================] - 16s 7ms/step - loss: 0.1762 - accuracy: 0.9468 - val_loss: 0.0530 - val_accuracy: 0.9830
Epoch 2/10
1875/1875 [==============================] - 13s 7ms/step - loss: 0.0853 - accuracy: 0.9748 - val_loss: 0.0525 - val_accuracy: 0.9838
Epoch 3/10
1875/1875 [==============================] - 13s 7ms/step - loss: 0.0784 - accuracy: 0.9776 - val_loss: 0.0429 - val_accuracy: 0.9864
Epoch 4/10
1875/1875 [==============================] - 13s 7ms/step - loss: 0.0791 - accuracy: 0.9778 - val_loss: 0.0537 - val_accuracy: 0.9826
Epoch 4: early stopping
loss: 0.053737200796604156
accuracy: 0.9825999736785889
学習時間： 54.875 秒でした。
```

きちんとGPU使って学習できているスピード感で良い感じ。



## conda search（おまけ）

```
conda search tensorflow
```

と実行すると、

```:output
# Name                       Version           Build  Channel
tensorflow                     1.7.0               0  pkgs/main
tensorflow                     1.7.1               0  pkgs/main
tensorflow                     1.8.0               0  pkgs/main
・・・省略・・・
tensorflow                     2.9.1 mkl_py39hc9ebea8_1  pkgs/main
tensorflow                    2.10.0 eigen_py310h1d93ef9_0  pkgs/main
tensorflow                    2.10.0 eigen_py37h0b514e4_0  pkgs/main
tensorflow                    2.10.0 eigen_py38h465b00b_0  pkgs/main
tensorflow                    2.10.0 eigen_py39hfced716_0  pkgs/main
tensorflow                    2.10.0 gpu_py310h4d27e69_0  pkgs/main
tensorflow                    2.10.0 gpu_py37h5d22f32_0  pkgs/main
tensorflow                    2.10.0 gpu_py38h51559ff_0  pkgs/main
tensorflow                    2.10.0 gpu_py39h9bca9fa_0  pkgs/main
tensorflow                    2.10.0 mkl_py310hd99672f_0  pkgs/main
tensorflow                    2.10.0 mkl_py38ha5c4042_0  pkgs/main
tensorflow                    2.10.0 mkl_py39ha510bab_0  pkgs/main
```

のようにビルドの一覧が出力される。ここから、`gpu_`で始まるものを選択してインストールしても同じことができる。

# まとめ

NVIDIAのGPU使って機械学習したいならAnacondaから環境構築。

# 参考

https://qiita.com/ktokey/items/7ee9c112198a6b0b5709

https://qiita.com/ktokey/items/7e083c43d83e21545bd8#comment-248f1d1cd320589678ab

https://qiita.com/tatsuki1119/items/f56c4dfdcdfe55e8341e