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

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

ただいまの
回答率

90.61%

  • Python 2.7

    1239questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

  • OpenCV

    1021questions

    OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

認識エンジン(createEigenFaceRecognizer)での大規模データの高速化について

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 1,740

n2.arts

score 12

顔認識システムを作ろうと思い、
OpenCV2.4のcreateEigenFaceRecognizerを使用して、実現しようとしています。

48,333枚の画像に対して、7944ラベルで学習させ、saveメソッドでパラメータを格納したxmlファイルを出力しました。
このxmlファイルの容量が5GBを超えて、非常に大きく、loadメソッドで読み込みをしようにも、3分程度の時間を要してしまい、システムとして使いものになりません。

createEigenFaceRecognizerを使った大規模データの取り扱いを高速化する方法はないのでしょうか?
(EigenFaceにとらわれずとも、大規模データを高速に認識する代替手段でも可)
また、こういった大規模データで認識エンジンを作る際にシステム構築のアプローチの定石のような物が存在するのでしょうか?

どうか、お力添えをよろしくお願い致します。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

checkベストアンサー

+2

門外漢のインフラ屋より。

3分で5GByteのファイルをロードしているという事は、秒間約28.4MByte読みだしている事になります。
大体7200rpmのHDDでのベンチマーク上でのシーケンシャルReadが100MByte/s程度ありますが、
ランダムReadは30MByte/s程度なので、この5GByteのファイルというのが複数に細かくわかれていた場合、ディスク性能限界に達している可能性があります。
(ファイルが断片化している場合も同じ)
また、仮にベンチマークレベルの速度でシーケンシャルに読み出せたとしても、4倍弱辺りが物理的な限界速度になってしまいます。

この為、xmlファイル内のデータ構造は分かりませんが、正規化するなりデータ形式を変えるなりして、
CPU使用率が上がったとしてもデータ圧縮率を上げるのが先決ではないかと思います。
この意味で言えば、その5Gが全てメモリに載って且つ余裕があるなら、gzip等で保存し、
読み込み時にプログラム側で解凍して読むだけで相当な高速化を図れる可能性があります。

尚、これはデータ保存時にも同じことが言えます。(保存時の方がむしろ効果が高いかもです)

また、別の手として、「SSD上に保存する」「HDDをRAIDで高速化する」等も考えられます。

恐らくはn2.artsさんが求められていた回答ではないと思いますが、
ご参考になれば幸いです。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2014/11/26 10:01

    utun様

    返信ありがとうございます.
    とても勉強になりました.
    インフラに詳しいという事で,併せてお伺いしたいんですが,

    webアプリとして実装する事を考えた場合,上記のxmlファイルのような大容量ファイルをサーバ起動時にインスタンスとして読み込んでおく事は可能でしょうか?

    ユーザが画像認識を実行する度に,逐一ファイルを読み込んでいたのでは,レスポンスが非常に遅くなります.
    (フロー:ユーザが画像認識開始 -> xmlファイル読み込み -> クラス分類計算 ->認識結果出力)
    一方で,サーバが起動したタイミングで,インスタンスに格納しておけば,あとはクラス分類計算と出力だけで済むので非常に高速になると考えられます.
    (フロー:ユーザが画像認識開始 -> クラス分類計算 ->認識結果出力)

    キャンセル

  • 2014/11/26 15:00

    サーバ側で事前読み込みしておくことは可能です。
    PHPであればAPCを使えばできますし、単一プロセスで捌く系のもの(Ruby、Nodejs等)であれば、単純に読み込んで専用クラスに放り込んでおけばOKです。

    ただ、多くのユーザの顔認識を行う場合(webアプリやスマホアプリ等のバックエンドとして利用するような場合)で、且つデータの更新が頻繁に入る場合は、分散を考えてmemcacheやredis等のオンメモリDBを別途用意した方がいいかもしれません。
    データ更新が入らない静的データであれば、各サーバ内のメモリに、最初の方法で載せておくだけで事足りるかと思います。

    キャンセル

  • 2014/11/26 17:06

    utun様

    返信ありがとうございます.
    でしたら,事前読み込みする事にします.
    また,createFisherFaceクラスでは,ラベルの数を増やさなければ,画像の枚数によらず学習器が計算するパラメータの数も増加しないと考えおりましたが,
    どうやら,ラベルの数よりも画像の枚数がパラメータ数に影響を与えるようなので,データサイズを減らす方針もとろうと思います.
    ご丁寧にありがとうございました.

    キャンセル

+1

その後、EigenFaceのアルゴリズムを理解したので、
この質問に対する根本的な問題と本質的な回答を提示しておきます。

まず、
なぜEigenFaceを使って大量の画像を学習させると、
モデルパラメータファイル(xml or yaml)が莫大な容量になるのかについて。
EigenFaceは主成分分析を行って、画像毎に主成分(固有ベクトル:Eigen vector)と平均ベクトル:Mean vectorを生成します。
つまり、画像毎にパラメータを記憶しておく必要があるため、画像の枚数に比例して容量がかさむのです。

次に、読み込み高速化の方法です。
1:学習させる画像を減らす
2:データベースにパラメータを書き込み、それを読みこむ
1について、
上記のように画像の枚数に比例するため、学習させる画像の枚数を減らせば当然パラメータ量は減ります。
1つのラベルに大量の画像を割り当てて学習しても大して精度は変わりません(この理由は後述します)
2について、
画像毎にパラメータを持つわけなので、データベースへの登録も容易です。
しかし、OpenCVの関数をいじる事はなかなか骨が折れるので、使用している言語で学習、認識エンジンを再実装するのが早いと思われます。
基本的には主成分分析をしたものをパラメータとして扱っているので、実装は手軽にできると思います。
データベースに登録して、認識アルゴリズムをどうすれば良いのだ?という心配には及びません。
というのも、EigenFaceはただの最近傍探索(1-NN)だからです。
認識対象画像のパラメータを計算して、単に学習させた画像のパラメータとのユークリッド距離を計算して、最も近い画像のラベルを出力しているだけです。
このクエリを実装するのは調べればすぐに分かると思います。
また、最近傍探索(1-NN)であるが故、1つのラベルに大量の画像を割り当てても、精度が劇的に向上するわけではありません。基本的に同じ人物の顔であれば、画像の各パラメータはパラメータ空間上の近くにマッピングされるわけで、識別境界は画像を増やしても大きく変化しないからです。

蛇足:
私は画像処理を専攻していたわけではないのですが、機械学習的な観点から見ると、1-NNはかなり暴力的な識別方法(汎化性能が皆無に等しい)なので、画像認識の分野でこれがメジャーな方法という事に驚きを禁じ得ません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2014/11/27 10:35

    蛇足について
    それだけ人の顔の固有ベクトルが人それぞれの特徴を持っていて、十分識別できるということではないでしょうか。
    また、EigenFaceがメジャーだと言われているのは、EigenFaceがシンプルであるので拡張、発展させやすいためではないかと思います。

    キャンセル

  • 2014/11/27 14:13

    sho_cs様

    コメントありがとうございます.
    確かに,EigenFaceを元にして様々なアルゴリズムが研究されているようですね.
    勉強になりました.

    キャンセル

0

XMLではなくYAML形式で保存すると少しは負荷が減るかもしれません。
また、DBで読み書きできるのであれば、こちらもやってみる価値はあると思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2014/11/26 12:14

    sho_cs様

    返信ありがとうございます。
    YAML形式で保存したのですが、逆にファイル容量が増加し、読み込みにさらに時間がかかってしまいました。

    キャンセル

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

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

関連した質問

同じタグがついた質問を見る

  • Python 2.7

    1239questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

  • OpenCV

    1021questions

    OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

関連ワード: createeigenfacerecognizer