ディープラーニングをやるときに,もともとTensorFlowバックエンドのKerasを使っていたのですが,そろそろ別のライブラリを使えるようになりたいと思ってPyTorchを使い始めました。
そのときに,画像処理の部分で処理速度が遅すぎてドツボにハマったので,そのときの試行錯誤の結果を残しておきたいと思います。
画像処理がボトルネック
PyTorchで簡単なCNNの実装をしていて画像を扱うときに,画像の処理の部分がどうもボトルネックになっていそうだということが分かりました。
普段は画像処理にはOpenCVを使っているのですが,そのときだけはPyTorchのチュートリアルを参考にして,scikit-imageを使っていました。
結果から言うと,それがめちゃくちゃ処理が遅い原因でした。
という訳で,
- 画像の読み込み
- 画像のリサイズ
の2点についてscikit-imageとOpenCVの処理速度を比較しました。
ソース
こんな感じで,それぞれのライブラリで①読み込みと②リサイズにかかる時間を計測しました。
import time import skimage import cv2 # Load image by scikit-image start = time.time() for _ in range(100): skimage.io.imread('test.jpg') time_spent = time.time() - start print('Time to load image by scikit-image:', time_spent) # Load image by OpenCV-python start = time.time() for _ in range(100): cv2.imread('test.jpg') time_spent = time.time() - start print('Time to load image by OpenCV-python:', time_spent) # Resize image by scikit-image img = skimage.io.imread('test.jpg') start = time.time() for _ in range(100): skimage.transform.resize(img, (100, 100), mode='reflect', preserve_range=True, anti_aliasing=True) time_spent = time.time() - start print('Time to resize image by scikit-image:', time_spent) # Resize image by OpenCV-python img = cv2.imread('test.jpg') start = time.time() for _ in range(100): cv2.resize(img, (100, 100)) time_spent = time.time() - start print('Time to resize image by OpenCV-python:', time_spent)
計測結果
上のソースを実行した結果は以下の通りです。
>python time_calc.py Time to load image by scikit-image: 1.0180296897888184 Time to load image by OpenCV-python: 1.1121129989624023 Time to resize image by scikit-image: 10.839929342269897 Time to resize image by OpenCV-python: 0.01561880111694336
読み込み速度は scikit-image > OpenCV
読み込みの速度は若干ですが,scikit-imageの方が速いという結果になりました。
ざっくり1割くらいは差がありますので,大量の画像を読み込む場合にはscikit-imageを使って,画像が少ない場合はまぁ好きな方でいいという感じですかね。
リサイズ速度は OpenCV >> scikit-image
一方,リサイズについてはかなり差が大きくなりました。
ざっと1000倍はOpenCVの方が速くなっています。
正直ここまで差がつくとは思っていませんでしたが,PyTorchを使ってみていたときに,scikit-imageだとやたら計算が遅かったので,そういう意味ではこのくらい差があるのも納得です。
まとめ
という訳で,もし画像処理がボトルネックになっている場合は,以下のようにライブラリを使い分けると処理速度が改善されるかもしれません。
- 画像の読み込み:scikit-imageを使用
- 画像のリサイズ:OpenCVを使用