fast.ai で deep learning を勉強しよう(5)Performance Tips and Tricks
fast.ai を WindowsPC で勉強する時の環境整備の話です。
Windows10 Python3.7.1 fastai 1.0.57 Pytorch1.2.0 (py3.7_cuda100_cudnn7_1) cudatoolkit10.0.130 cudnn7.6.0
画像読込の高速化
fast.ai に書かれている Performance Tips and Tricks を解説します。
Performance Tips and Tricks | fastai
Jupyter から下記を実行すると、ここに書かれている環境がすでに整っているかどうかの確認ができます。
import fastai.utils fastai.utils.check_perf()
Anaconda Prompt から確認する時は次のようになります。
python -c "import fastai.utils; fastai.utils.check_perf()"
実行するとチェック結果が表示されます。
・推奨項目がある場合
*** libjpeg-turbo status ✘ libjpeg-turbo is not on. It's recommended you install libjpeg-turbo to speed up JPEG decoding. See https://docs.fast.ai/performance.html#libjpeg-turbo *** Pillow-SIMD status ✘ Running Pillow 5.4.1; It's recommended you install Pillow-SIMD to speed up image resizing and other operations. See https://docs.fast.ai/performance.html#pillow-simd *** CUDA status ✘ You are running pytorch built against cuda 8.0, your NVIDIA driver 431.36 supports cuda10. See https://pytorch.org/get-started/locally/ to install pytorch built against the faster CUDA version.
・既に対応済の場合
*** libjpeg-turbo status ✔ libjpeg-turbo is on *** Pillow-SIMD status ✔ Running Pillow-SIMD 6.0.0.post0 *** CUDA status ✔ Running the latest CUDA 10.0 with NVIDIA driver 431.36
チェック結果に対応すると、CPUでJPEG画像を読み込んで解凍する部分が高速化されるので、機械学習のトレーニング時間が短縮されると言っています。
libjpeg-turbo のインストール
SIMD instructions (MMX, SSE2, AVX2, NEON, AltiVec) を使用して JPEG の圧縮/回答を libjpeg よりも高速で実行するライブラリーとの事です。
libtiff を uninstall して libjpeg-turbo をインストールします。 Jupyter から作業をする時には「!」を先頭につけてコマンドを実行します。
!conda uninstall --force jpeg libtiff -y !conda install -c conda-forge libjpeg-turbo
Pillow-SIMD のインストール
SIMD instructions (MMX, SSE2, AVX2, NEON, AltiVec) を使用して 画像処理を高速化する為に、Pillow を Pillow-SIMD に置き換えます。 Pillow-SIMD のベンチマークがここにあります。
バイナリーの入手とインストール
Windows用はコンパイルされたものが用意されていないので、次の非公式サイトから対応するものをダウンロードします。 Python Extension Packages for Windows - Christoph Gohlke
ダウンロードしたファイルの保存先を指定してPillow-SIMDをインストールします。 以下はpython3.7のダウンロードファイルを Jupyter からインストールする場合です。
!pip install 保存ディレクトリ\Pillow_SIMD‑6.0.0.post0+avx2‑cp37‑cp37m‑win_amd64.whl
Pillow-SIMD インストールの確認方法
Pillow-SIMD が使われるようになったかどうかは、次の様にして Pillow のバージョンを表示してみます。
from PIL import Image print(Image.PILLOW_VERSION)
Pillow のバージョンに .postX が付いているならば SIMD版が使われています。
CUDAバージョンアップ
現時点での Pytorch の CUDA 対応バージョンは 10.0 のようなので、CUDA10.0.130 をダウンロードしてインストールします。cudnnも対応するものをNVIDIAからダウンロードして対応するフォルダーにコピーします。
cudnn-10.0-windows10-x64-v7.6.2.24.zip
以前のバージョンのCUDAとは別のフォルダーにインストールされるので、前バージョンはそのまま残しておいても問題ありません。 新しいバージョンがインストールされると、環境変数にそれがセットされるので、通常は新しい方が使用される環境となります。
旧バージョンを削除したい場合には、「設定」の「アプリと機能」から削除したいものをアンインストールします。アンインストールしても手動でコピーしたcudnnはそのまま残るので、消したい場合には、フォルダーを開いて手動で削除します。
cudatoolkit のバージョンを CUDAのバージョンに合わせます。
GPU Notes CUDAメモリー量の確認
fastai のライブラリーをインストールします。
!conda install nvidia-ml-py3 -c fastai
次の様に実行すると有効なGPUデバイスがリストアップされます。
from pynvml import * nvmlInit() try: deviceCount = nvmlDeviceGetCount() for i in range(deviceCount): handle = nvmlDeviceGetHandleByIndex(i) print("Device", i, ":", nvmlDeviceGetName(handle)) except NVMLError as error: print(error)
また、次のように実行するとDevice0のメモリーの使用量を見ることができます。
from pynvml import * nvmlInit() handle = nvmlDeviceGetHandleByIndex(0) info = nvmlDeviceGetMemoryInfo(handle) print("Total memory:", info.total) print("Free memory:", info.free) print("Used memory:", info.used)
ただ確認するだけならば、ELSA System Graph を使用した方が簡単です。
下記のコマンドで確保されたGPUメモリーを開放する事ができます。
import torch torch.cuda.empty_cache()
メモリー不足対策
CUDA out of memory が出てエラーで実行できない時はメモリーの消費量を抑える必要があります。
バッチサイズを小さくする
DataBunch の引数のバッチサイズ bs の値を小さくします。
バッチサイズは省略されると64です。
画像サイズを小さくする
引数のリサイズ画像サイズを小さくします。
data = ImageDataBunch.from_name_re(path_img, fnames, pat, ds_tfms=get_transforms(), size=224, bs=bs ).normalize(imagenet_stats)
size = 224 は 224x224画素にすることを表しています。
計算を16bit にする
トレーニング時の計算精度を16bitに落とすことで、メモリーの消費量を少なくすることができます。 例えば
learn = Learner.create_unet(data,models.resnet34,metrics).to_fp16()
の様に to_fp16( ) を付けます。
CPUで処理したい時
GPUのメモリーが少なくて処理できないのでメインメモリーで処理したい時には
はじめに
defaults.device = torch.device('cpu')
を追加します。
使用済メモリーの解放
restartせずに別の事をしたい時に使用しないGPUメモリーを開放したい時には次の様にlearnerをdestroyする事で解放されます。
learn.destroy()
learnerを保存する時にオプションを付けて開放することも出来ます。
learn.export('raind_model.pkl', destroy = true)
fastai用 Jupyter の起動バッチファイル作成
ショートカットを作成してワンクリックで fastai 環境の Jupyter を立ち上げるには、リンク先を次のようにします。
C:\A3\python.exe C:\A3\cwp.py C:\A3\envs\fastai C:\A3\envs\fastai\python.exe C:\A3\envs\fastai\scripts\jupyter-notebook-script.py C:\Python
リンク先の文字の意味は以下のようなものなので、各自の環境で修正する必要があります。
C:\A3 : Anacondaインストールフォルダー
fastai : fastai仮想環境
C:\Python : Jupyter で開くフォルダー
学習結果を保存して使用する時
学習後、結果をファイルに保存しておきます。
learn.export('trained_model.pkl')
使用する時に、それを読み出します。
from fastai.vision import * path = Path('data/bears') learn = load_learner(path,'trained_model.pkl')
判定したい画像を読み込んでpredictに渡します。
img = open_image(path/'black'/'00000022.jpg') pred_class, pred_idx, outputs = learn.predict(img) pred_class