RTX3090でtensorflow1.15を動かす

前の[記事　RTX3090Tiで機械学習マシンを自作しtensorflowを動かすまで](https://qiita.com/mikoaisa/items/62fcc7194768b155d8a2)で RTX3090でTensorflow 1.15が動かないと書きました。一般にtensorflow 1.xはcuda 10までしかサポートせず、RTX30xxがcuda11以上でないと動かないという記事が多いです。
でもあれこれ調べてやったらそれほど難しくなくAnaconda環境下でなんとか動いたので報告します。

<H1>NVidiaのwheel</H1>

[RTX3000番台のGPUでTensorFlow v1.15を動かす](https://touch-sp.hatenablog.com/entry/2022/08/04/183551)というまんま欲しい内容の記事を発見したのでその通りやればさくっと…とはいきませんでした。しかし大きなヒントを貰えました。

ようするにNVidiaさんが用意してくれてるセットというのがあるということです。Dockerはあるとは聞いていたのですが普通にpipで入るものもあるとは思っていませんでした。(Dockerのことをよくわかってないのでこのへん混乱しています）

NVidiaのこの[ページ TensorFlow Release Notes](https://docs.nvidia.com/deeplearning/frameworks/tensorflow-release-notes/index.html)を見るとなんかセットがあるらしいことが色々書いてあります。で、これの実体がどこにあるかというと、どうやってたどり着いたか覚えていないのですが、[ここにありました。](https://developer.download.nvidia.com/compute/redist/nvidia-tensorflow/)
このページを開いてみるとこんな風にwheelの一覧が出てきます(@2022.11.11)。
~~~
nvidia_tensorflow-1.15.2+nv20.06-cp36-cp36m-linux_x86_64.whl
nvidia_tensorflow-1.15.3+nv20.07-cp36-cp36m-linux_x86_64.whl
nvidia_tensorflow-1.15.3+nv20.08-cp36-cp36m-linux_x86_64.whl
nvidia_tensorflow-1.15.3+nv20.09-cp36-cp36m-linux_x86_64.whl
nvidia_tensorflow-1.15.4+nv20.10-cp36-cp36m-linux_x86_64.whl
nvidia_tensorflow-1.15.4+nv20.11-cp36-cp36m-linux_x86_64.whl
nvidia_tensorflow-1.15.4+nv20.12-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv21.02-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv21.03-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv21.04-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv21.05-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv21.06-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv21.07-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv21.08-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv21.09-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv21.10-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv21.11-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv21.12-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv22.01-3720650-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv22.02-3927706-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv22.03-4138614-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv22.04-4387458-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv22.05-4761017-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv22.06-5077300-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv22.07-5236135-cp36-cp36m-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv22.07-5236135-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv22.08-5542765-cp36-cp36m-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv22.08-5542765-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv22.09-6040196-cp36-cp36m-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv22.09-6040196-cp38-cp38-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv22.10-6183310-cp36-cp36m-linux_x86_64.whl
nvidia_tensorflow-1.15.5+nv22.10-6183310-cp38-cp38-linux_x86_64.whl
~~~
理由はよくわかりませんが、全部1.15です。
それでこのwheelのどれかをダウンロードしてpipでinstallします。
anaconda下ですが、どうやらconda install と pipを混在させなければいいらしいことがわかったので今回はpipだけでいってみます。

<H1>インストール</H1>

はじめ上の記事の人に習って
nvidia_tensorflow-1.15.5+nv21.06-cp38-cp38-linux_x86_64.whl
でやってみたのですが、バージョンが古いらしく他のライブラリとprotobufとかnumpyとかあれこれバージョンが競合してしまいやめました。
それで現時点(2022.11.11)で最新の
nvidia_tensorflow-1.15.5+nv22.10-6183310-cp38-cp38-linux_x86_64.whl
でやりました。
初め、適当にダウンロードしてpipしたらplatformが合ってない的なエラーがでてしまって、調べてみたらpythonのバージョンが合ってないということでした。wheelのファイル名にcp38とかcp36とかありますがこれがまんまpythonのバージョンらしいです。なので今回のwheelはpython3.8ということになります。

というわけで
~~~
conda create -n tf115 python=3.8

conda activate tf1115
~~~
としたあと、ダウンロードしておいたwheel(./wheelに置きました)を
~~~
pip install ./wheel/nvidia_tensorflow-1.15.5+nv22.10*.whl
~~~
少しかかりますがあれこれダウンロードしてインストールしてくれます。

そして例によってnotebookのため
~~~
pip install jupyter
~~~

あと1.15ではkerasは入らなかったため
~~~
pip install keras==2.3.1
~~~

これは自分のモデルの学習で使ってるライブラリ。このへんは使う人の必要に応じて。
~~~
pip install matplotlib
pip install opencv-python
~~~

array_to_img()で
~~~
ImportError: Could not import PIL.Image. The use of `array_to_img` requires PIL.
~~~
が出てしまいました。
そこで
~~~
pip install pillow
~~~
すると
~~~
Looking in indexes: https://pypi.org/simple, https://pypi.ngc.nvidia.com
Requirement already satisfied: pillow in ./anaconda3/envs/tf115/lib/python3.8/site-packages (9.3.0)
~~~
なんかもう入ってるっぽい？
これはnotebookを開きながら足りないものをインストールしていったのが原因でした。
一旦jupyter notebookを終了し再起動したら問題なくarray_to_img()は動作しました。

<H1>学習してみる</H1>

そして前の記事でも使った256x256の画像から点を検出するモデルを学習させてみます。
パラメータ1300万、weight(hdf5)のサイズで50MBくらいの比較的軽いresNetモデルです。

~~~
batch_size=8
steps_per_epoch=1000
Epoch 1/1000
1000/1000 [==============================] - 129s 129ms/step - loss: 0.1435 - accuracy: 0.9626 - val_loss: 0.0937 - val_accuracy: 0.8750
Epoch 2/1000
1000/1000 [==============================] - 128s 128ms/step - loss: 0.0477 - accuracy: 0.9857 - val_loss: 0.0918 - val_accuracy: 0.8750
~~~
2.8.2のときが
~~~
1000/1000 [==============================] - 173s 173ms/step - loss: 0.0853 - accuracy: 0.9785 - val_loss: 0.0836 - val_accuracy: 0.8750 
~~~
なんか129ms < 173msで1.15のほうが速い（しかもかなり）？

実行中のnvidia_smiを見ると
| ファン| 温度 | 電力 | VRAM | GPU使用率 |
|:-:|:-:|:-:|:-:|:-:|
|31%   |60度  | 166W / 480W |23209MiB / 24564MiB   | 40%  |

なんかGPU使用率が2よりも高くなってます。しかも温度も電力もファンもほとんど変わらない。

<H1>保存したweight</H1>
学習の結果出来たhdf5とjsonを使って実装環境にもっていく実験をしたところうまくいったみたいです。
Colabのtensorflow1.15でやってときと互換性のある結果が得られました。