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

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

新規登録して質問してみよう
ただいま回答率
85.50%
OpenCV

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

Python 2.7

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

Q&A

解決済

3回答

3013閲覧

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

n2.arts

総合スコア14

OpenCV

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

Python 2.7

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

1グッド

1クリップ

投稿2014/11/25 07:20

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

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

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

どうか、お力添えをよろしくお願い致します。

afroscript👍を押しています

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

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

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/25 12:12

utun

総合スコア384

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

n2.arts

2014/11/26 01:01

utun様 返信ありがとうございます. とても勉強になりました. インフラに詳しいという事で,併せてお伺いしたいんですが, webアプリとして実装する事を考えた場合,上記のxmlファイルのような大容量ファイルをサーバ起動時にインスタンスとして読み込んでおく事は可能でしょうか? ユーザが画像認識を実行する度に,逐一ファイルを読み込んでいたのでは,レスポンスが非常に遅くなります. (フロー:ユーザが画像認識開始 -> xmlファイル読み込み -> クラス分類計算 ->認識結果出力) 一方で,サーバが起動したタイミングで,インスタンスに格納しておけば,あとはクラス分類計算と出力だけで済むので非常に高速になると考えられます. (フロー:ユーザが画像認識開始 -> クラス分類計算 ->認識結果出力)
utun

2014/11/26 06:00

サーバ側で事前読み込みしておくことは可能です。 PHPであればAPCを使えばできますし、単一プロセスで捌く系のもの(Ruby、Nodejs等)であれば、単純に読み込んで専用クラスに放り込んでおけばOKです。 ただ、多くのユーザの顔認識を行う場合(webアプリやスマホアプリ等のバックエンドとして利用するような場合)で、且つデータの更新が頻繁に入る場合は、分散を考えてmemcacheやredis等のオンメモリDBを別途用意した方がいいかもしれません。 データ更新が入らない静的データであれば、各サーバ内のメモリに、最初の方法で載せておくだけで事足りるかと思います。
n2.arts

2014/11/26 08:06

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

0

その後、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/26 14:03

n2.arts

総合スコア14

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sho_cs

2014/11/27 01:35

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

2014/11/27 05:13

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

0

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

投稿2014/11/26 01:20

sho_cs

総合スコア3541

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

n2.arts

2014/11/26 03:14

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問