質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.63%

MTCNNの顔検出の実行時間を早くしたい

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 129

napojin

score 6

MTCNNの顔検出に非常に時間がかかる

 困っていること 

顔検出のライブラリのMTCNNを使って、動画から顔のパーツの座標を特徴としてデータフレームを作っていたのですが、1時間50分で画像の197ファイルの検出しかできず、約120000ファイル(全データ)では1ヶ月半ぐらいかかりそうです。処理時間は2,3日以内を目処に考えています。

そこで時間を節約するために、以下に関して知識があれば、アドバイスをいただきたいです。

  1. 処理速度を高める手段の提案(計算リソースの追加など)
  2. MTCNNより、顔検出速度が早いライブラリ(約120000ファイルを1週間以内)
  3. マルチプロセスなどのコード上の工夫の余地
  4. その他の代案

 現在使用しているGCPのVMスペック 
vCPU x 2、メモリ 13 GB
NVIDIA K80 GPUs x 2

 該当コード

import cv2 as cv
from tqdm.notebook import tqdm
from collections import defaultdict
import glob
import pandas as pd
from mtcnn.mtcnn import MTCNN

filenames = glob.glob('video_folder/*.mp4')

data_dict = defaultdict()
for filename in tqdm(filenames):
    fn = filename.split('/')[-1]
    capture_image = cv.VideoCapture(filename)
    if not capture_image.isOpened():
        print("Something Wrong!!")
        break
    ret, frame = capture_image.read()
    detector = MTCNN()
    result = detector.detect_faces(frame)
#  result is empty array when anything detect
    data_dict[fn] = result[0] if len(result)!=0 else None

df_data = pd.DataFrame.from_dict(data_dict)
df_data = df_data.T
display(df_data.head())
...
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+3

1時間50分で画像の197ファイルの検出しかできず、

110分で197ファイルということは1画像あたり34秒となりますが、いくら計算量がかかる CNN とはいえ、時間がかかりすぎな気がします。

今、試しに以下の条件で100枚の推論を試しましたが、1枚あたり0.5秒ぐらいでした。

  • GPU: TITAN X (Pascal)
  • 画像サイズ 2000x1400

考えられる要因

CPU 実行になっている

CUDA/CuDNN のバージョンがあっていない等で GPU が使われていないで、CPU 実行になっていたりしないでしょうか。
実行中に nvidia-smi で GPU が使われているかどうかを確認してみてください。もし、GPU が使われていてその遅さなら、MTCNN の速度向上は改善の見込みがないです。
ちなみに GPU が2枚刺さっていても、複数 GPU を使うように実装されていない限り、通常は1枚の GPU しか使われません。

画像サイズが大きい

また、画像サイズがかなり大きい場合は、検出前にリサイズしておくと早くなるかもしれません。

重みの読み込みは一回でいい

以下のモデルの作成はループの外に出せば、多少早くなるかもしれません。

detector = MTCNN()

以前、以下のライブラリで顔検出を試したことがあります。
正面の顔ならそこそこの精度で検出できたと思います。

GitHub - ageitgey/face_recognition: The world's simplest facial recognition api for Python and the command line

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/14 22:15

    >>>考えられる要因として、CUDA/CuDNN のバージョンがあっていない等で GPU が使われていないで、CPU 実行になっていたりしないでしょうか

    ありがとうございます。実行中のnvidia-smiの実行結果は以下のようになりました。
    GPUのプロセスは一応動いているようです。ただ、GPY Memory Usageが小さすぎるので、MTCNNに使われていないっぽいです。

    $ nvidia-smi
    Fri Feb 14 12:29:31 2020
    +-----------------------------------------------------------------------------+
    | NVIDIA-SMI 418.87.01 Driver Version: 418.87.01 CUDA Version: 10.1 |
    |-------------------------------+----------------------+----------------------+
    | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
    | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
    |===============================+======================+======================|
    | 0 Tesla K80 Off | 00000000:00:04.0 Off | 0 |
    | N/A 73C P0 70W / 149W | 68MiB / 11441MiB | 0% Default |
    +-------------------------------+----------------------+----------------------+
    | 1 Tesla K80 Off | 00000000:00:05.0 Off | 0 |
    | N/A 66C P8 33W / 149W | 11MiB / 11441MiB | 0% Default |
    +-------------------------------+----------------------+----------------------+

    +-----------------------------------------------------------------------------+
    | Processes: GPU Memory |
    | GPU PID Type Process name Usage |
    |=============================================================================|
    | 0 19886 C ...om/anaconda3/envs/ml_env/bin/python 57MiB |
    +-----------------------------------------------------------------------------+

    >>> GPU が2枚刺さっていても、複数 GPU を使うように実装されていない限り、通常は1枚の GPU しか使われません。
    おっしゃる通り、GPUは一枚しか動いてませんでした。pytorchを使えば、GPUを稼働させてMTCNNを使えそうなので、試してみます。

    現在使用中 https://github.com/ipazc/mtcnn


    Pytorch
    https://github.com/timesler/facenet-pytorch

    from facenet_pytorch import MTCNN
    mtcnn = MTCNN(post_process=False, device='cuda')


    >>> 画像サイズがかなり大きい場合は、検出前にリサイズしておくと早くなるかもしれません。
    ありがとうございます。画像サイズはかなり大きく、幅1920, 高さ1080の動画がほとんどです。
    一切手を加えずデータフレームに変換していました。

    >>> 以前、以下のライブラリで顔検出を試したことがあります
    これは知りませんでした。今、openCVのCascadeClassifierを試したのですが、かなり誤認してたので、まずMTCNNでGPUを設定する方法を探してみて、それで改善しなければ試してみます。

    キャンセル

check解決した方法

+1

無事解決できました!
結論から言うとGPUが使われていませんでした。

$ conda install -c anaconda tensorflow-gpu
をしたところ、
from tensorflow.python.client import device_lib
device_lib.list_local_devices()
で確認して、gpuが認識されるようになりました。

しかし、
Error
TypeError: softmax() got an unexpected keyword argument 'axis'
が出るようになり、おそらくバージョンによるエラーが表示されました。
tensorflowのバージョンを2.0から1.3に落としたところ、カーネルが勝手にシャットダウンするようになりました。
その後、色々バージョンを試しましたが、結局アプデートとした結果、競合なく読み込まれました。

$ conda update conda -n root
$ conda update tensorflow
$ conda update tensorflow-gpu

$ pip freeze | grep tensorflow
tensorflow==1.15.0
tensorflow-estimator==1.15.1

[mtcnnバージョン]
import mtcnn
mtcnn.version
'0.1.0'

コード実行後、無事GPU2つの稼働を確認できました。
$ nvidia-smi
Fri Feb 14 15:34:25 2020       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.87.01    Driver Version: 418.87.01    CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla K80           Off  | 00000000:00:04.0 Off |                    0 |
| N/A   73C    P0    70W / 149W |  11033MiB / 11441MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla K80           Off  | 00000000:00:05.0 Off |                    0 |
| N/A   73C    P0    75W / 149W |     69MiB / 11441MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0     32578      C   ...om/anaconda3/envs/my_env/bin/python 11020MiB |
|    1     32578      C   ...om/anaconda3/envs/my_env/bin/python    58MiB |
+-----------------------------------------------------------------------------+

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

tiitoiさんがおっしゃった通り、detector = MTCNN()をループの外にして一回きりの読み込みにしたところ、実行速度が約288倍になり、1分あたり、1330ファイルの検出が行えるようになりました。
まさかここまで影響が出るとは思ってませんでした。ありがとうございました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる