python並列処理による機械学習の高速化の試み

機械学習をしていると処理の遅さに悩まされることが多々ある.
私は画像系のdeep learningを扱うことが多いので,頻繁に悩まされている.

高速化するにあたってNetworkの処理自体はGPUに任せるしかないので,それ以外でGPUの足を引っ張らないようにするのが大事だと思う.
今回は画像の読み込みを並列で行うことで処理時間の短縮ができるのではないかと思い,やってみた.

この記事でやったこと
* multiprocessingモジュールの簡単な使い方の説明
* Poolクラスを用いて,画像読み込みの並列化&速度測定
* Process, Queueクラスを用いたCNNの処理時間高速化の試み

注意点

Desktop(Ubuntu)とMacBookProで試したのですが,結果が異なってしまったので,あっているのか自信がない…
実装の参考までにしてください.
間違っている点があれば教えていただけると幸いです.

環境

Ubuntu 16.04
プロセッサ: 3.0GHz Core i7
コア数: 16

Pythonにおける並列処理

並列処理には大きく,Threadによる並列化(メモリ共有)とProcessによる並列化(共有なし)があるが,pythonではGIL (Global Interpreter Lock)というインタプリタ上で一度に一つのスレッドのみが動作することを保証する機能があり,Threadによる並列化ができないらしい.

そのため基本的にProcessによる並列化を行う.

multiprocessingモジュール

pythonではmultiprocessingモジュールが提供されており,これを用いることで並列化できる.
[document]

使い方

基本的にはPoolというクラスを用いて以下のように使う.
並列化してもちゃんと順番通りに処理してくれる.

画像読み込みの並列化

以下のように実装した.

結論としては,マルチプロセスにすることで処理速度は向上したがそれほど大きな違いはなかったので,”絶対に並列化するべき!”というほどではない.
が,そんなに難しくない処理なので導入しておくにこしたことはないと思う.

ちなみに,画像読み込み枚数を100, 500, 1000としつこいくらいに細かく調べているのは初めにMacBookProで試したときに想定外の結果がでたので,細かく調査していた名残です.
プロセス数を4にしているのも同様の理由.16にするともっと大きな差がついていた.

CNNでの予測処理高速化の試み

process,queueを用いて,画像の読み込みとCNNでの推定処理を並列に行った.
実装は以下のようにした.(CNNでの推定用コードは省略)

結論としては,並列で画像を読み込んだほうが速いということがわかった.
Process, Queueの導入は逆効果である.という結果がでたのだが,ちょっと納得いかない..
もう少しうまく処理する方法はないのだろうか..

まとめ

multiprocessingモジュールのPool, Process, Queueクラスを用いた並列処理の実装サンプルを示した.
結果,並列化することで処理の高速化を実現できることがわかった.
一番良い方法が並列で画像を読み込む方法だったのだが,Process,Queue等他の方法でもっとうまくやれる方法がある気がする.
間違いがあればご指摘いただけると幸いです.

おまけ

Ubuntuで行う前にMacBookProで試した結果.
Macでは並列化することで悪影響を与えていたので,もしかすると環境次第では並列化しないほうが速いかもしれないので,ご注意ください.

Macで行ったときの結果

Macの環境

Mac Book Pro
プロセッサ: 2.7GHz Core i5
コア数: 4