Marsアルゴリズムの実践-顔認識


Marsは行列に基づく統一分布計算フレームワークであり,以前の論文ではMarsが何であるか,およびMars分布実行について述べ,MarsはGitHubでオープンソースである.Marsの紹介を見て何ができるかを聞くかもしれませんが、これはほとんどあなたが何をしたいかにかかっています.Marsは最下位の演算ライブラリとしてnumpy 70%の一般的なインタフェースを実現しているからです.この文章では、Marsを使ってやりたいことを完成する方法を紹介します.
特異値分解(SVD)
煩雑なデータを処理する時、データ処理者として、まず思いつくのは降次元で、SVDはその中の1種の比較的によくある降次元方法で、numpy.linalgモジュールの中でsvd方法があって、私達が20000個の100次元のデータが処理する必要がある時、SVDインタフェースを呼び出します:
In [1]: import numpy as np

In [2]: a = np.random.rand(20000, 100)

In [3]: %time U, s, V = np.linalg.svd(a)
CPU times: user 4min 3s, sys: 10.2 s, total: 4min 13s
Wall time: 1min 18s

Numpyがmklアクセラレータを使用しても、1分以上の実行時間がかかり、データ量が大きい場合、単機のメモリは処理できないことがわかります.
MarsはSVDも実現したが,マトリクスブロック計算のアルゴリズムを用いて並列計算が可能であるため,Numpyよりも速い速度を示した.
In [1]: import mars.tensor as mt

In [2]: a = mt.random.rand(20000, 100, chunk_size=100)

In [3]: %time U, s, V = mt.linalg.svd(a).execute()
CPU times: user 5.42 s, sys: 1.49 s, total: 6.91 s
Wall time: 1.87 s

同じデータ量の場合,Marsは数十倍の速度で向上し,わずか1秒余りで20000データ量の次元ダウン問題を解決できることが分かった.タオバオのユーザーデータがマトリクス分解を行うと,分布式のマトリクス演算がその価値を示すことを想像してみてください.
主成分分析(PCA)
降次元といえば、主成分分析も重要な手段である.PCAは情報量が最も多い方向を選択してデータを投影し、その投影方向は分散を最大化するか投影誤差を最小化するかの2つの角度から理解できる.すなわち,低次元キャラクタリゼーションベクトルと特徴ベクトル行列により,対応する元の高次元ベクトルを基本的に再構成できる.最も主要な式は次のとおりです.
xiは各サンプルのデータであり、μjは新しい投影方向であり,我々の目標は投影分散を最大化し,主特徴を見つけることである.上記式中の行列Cは数学では共分散行列で表すことができ,もちろんまず入力したサンプルを中心化して調整する.ランダムに生成された配列で、NumpyがPCAの次元ダウン操作をどのように実現しているかを見ることができます.
import numpy as np

a = np.random.randint(0, 256, size=(10000, 100))
a_mean = a.mean(axis=1, keepdims=True)
a_new = a - a_mean
cov_a = (a_new.dot(a_new.T)) / (a.shape[1] - 1)

#  SVD       20    
U, s, V = np.linalg.svd(cov_a)
V = V.T
vecs = V[:, :20]

#              
a_transformed = a.dot(vecs)

ランダムに生成されるデータ自体にはあまり特徴がないため、100次元データの中で上位20次元を象徴的に取り出し、一般的には特徴値の割合で合計の上位99%などの数値をとることができる.
マーズがどのように実現したかを見てみましょう
import mars.tensor as mt

a = mt.random.randint(0, 256, size=(10000, 100))
a_mean = a.mean(axis=1, keepdims=True)
a_new = a - a_mean
cov_a = (a_new.dot(a_new.T)) / (a.shape[1] - 1)

#  SVD       20    
U, s, V = mt.linalg.svd(cov_a)
V = V.T
vecs = V[:, :20]

#              
a_transformed = a.dot(vecs).execute()

importの違いに加えて、最後にデータを必要とする変数に対してexecuteメソッドを呼び出し、将来eagerモードを完了した後もexecuteを省くことができ、以前Numpyで書かれたアルゴリズムはほとんどシームレスにマルチプロセスや分布式のプログラムに変換することができ、自分で手動でMapReduceを書く必要はありません.
顔認識
ベースアルゴリズムがMarsによって実現されると、実際のアルゴリズムシーンに使用することができる.PCAの最も有名な応用は人の顔の特徴の抽出と人の顔の識別で、単一の人の顔のピクチャーの次元はとても大きくて、分類器は処理しにくくて、早起きして比較的に有名な人の顔の識別EigenfaceアルゴリズムはPCAアルゴリズムを採用します.本論文では,簡単な顔認識プログラムを例として,Marsがどのようにこのアルゴリズムを実現したかを見た.
本論文の顔データベースはORL face databaseを用い,40人の異なる人の400枚の顔画像があり,各画像は92*112画素の階調画像である.ここでは、各グループの最初の顔画像をテスト画像として選択し、残りの9枚の画像をトレーニングセットとして選択します.
まずpythonのOpenCVのライブラリを利用して、すべての画像を大きなマトリクス、つまり360*10304サイズのマトリクスに読み込み、各行は各人の顔の階調値で、360枚のトレーニングサンプルがあります.PCAトレーニングデータを用いて、data_matは入力マトリクスであり、kは保持する必要がある次元である.
import mars.tensor as mt
from mars.session import new_session

session = new_session()

def cov(x):
    x_new = x - x.mean(axis=1, keepdims=True)
    return x_new.dot(x_new.T) / (x_new.shape[1] - 1)

def pca_compress(data_mat, k):
    data_mean = mt.mean(data_mat, axis=0, keepdims=True)
    data_new = data_mat - data_mean

    cov_data = cov(data_new)

    U, s, V = mt.linalg.svd(cov_data)
    V = V.T
    vecs = V[:, :k]

    data_transformed = vecs.T.dot(data_new)
    return session.run(data_transformed, data_mean, vecs)

その後予測認識を行うため,低次元のデータに変換するだけでなく,平均値および低次元空間ベクトルを返す必要がある.中間過程の平均顔の様子が見られますが、数年前に人気があった各地の平均顔はこのようにして入手できます.もちろん、ここの次元やサンプルは少なく、個人の顔の様子しか見えません.
実はdata_transformedに保存されている特徴顔も画素順に並べてみると特徴顔の形がわかります.図には15個の特徴的な顔があり、一人の顔分類器として使用するのに十分です.
また、関数PCAにはsession.runという関数が使われています.これは、3つの返さなければならない結果が互いに独立しているわけではないためです.現在の遅延実行モードでは、3回の演算をコミットすると演算量が増加し、同じコミットはできません.もちろん、すぐにモードを実行し、演算した部分図の枝切り作業も行われています.
訓練が完了すると,降次元後のデータを用いて顔認識を行うことができる.以前の非訓練サンプルの画像入力を降次元後の次元表示に変換し,ここでは以前の訓練サンプルの顔データとの差を簡単なヨーロッパ式距離で判断し,距離が最も小さいのは認識した顔であり,もちろんある閾値を設定し,最小値が閾値を超えると認識失敗と判断する.最終的にこのデータセットの下で飛び出した精度は92.5%であり,簡単な顔認識アルゴリズムの構築が完了したことを意味する.
#       
def compare(vec1, vec2):
    distance = mt.dot(vec1, vec2) / (mt.linalg.norm(vec1) * mt.linalg.norm(vec2))
    return distance.execute()

将来
上記では、Marsを使用して顔認識の小さなアルゴリズムを一歩一歩完成させる方法を示しています.MarsクラスのNumpyのインタフェースはアルゴリズム開発者に非常に友好的で、アルゴリズムの規模が単機能力を超えている場合、分散環境に拡張すると、Marsが背後にあるすべての並列論理を処理するのに役立ちます.
もちろん、MarsにはPCAでの共分散行列の分解など、改善できる点がたくさんあります.特徴値、特徴ベクトルで計算することができ、計算量はSVD法よりはるかに小さいですが、現在、線形代数モジュールはまだ特徴ベクトルを計算する方法を実現していません.これらの特性は、SciPyの様々な上位アルゴリズムインタフェースの実現を含めて、一歩改善します.GitHubでissueを提案したり、Marsを共同で構築したりする必要があります.
Marsはオープンソースのプロジェクトとして、他のアイデアと提案を歓迎しています.私たちはみんなが参加して、Marsをますますよくする必要があります.
著者:継盛
原文を読む
本文は雲栖コミュニティのオリジナル内容で、許可を得ずに転載してはならない.