部分特異値分解(SVD)のメモリー効率の高い実装


10

モデルの縮小のために、行列の最大20の特異値に関連付けられた左特異ベクトルを計算したい RNk、 どこ N106 そして k10。残念ながら、私のマトリックス どんな構造もなしで密になります。

このサイズのランダムマトリックスに対してPython svdnumpy.linalgモジュールからルーチンを呼び出すだけの場合、メモリエラーが発生します。これは、VRNN 分解のために =VSU

この落とし穴を回避するアルゴリズムが周りにありますか?たとえば、非ゼロの特異値に関連付けられた特異ベクトルのみを設定します。

計算時間と精度をトレードする準備ができています。


1
興味深いことに、NumpyはシンSVDの実行方法を知らないようです...
JM

ヒントをありがとう。実際、numpy.linalg.svdには、full_matrices「ゼロ以外」の部分のみが計算されるようにFalseに設定するオプションがあります。それにもかかわらず、計算をさらに減らす方法はありますか?

3
numpyバックエンドは、Fortranコードを使用して LAPACKE_dgesvd、標準SVDルーチンを。ただし、通常、マトリックスはC_CONTIGOUS(で確認matrix.flags)です。したがって、Fortranアラインメントのデータをコピーします。さらに、lapackルーチンdgesvdの実行中に、マトリックスの別のコピー(または少なくともそのためのメモリ)が必要です。最初からメモリアラインメントがFortranスタイルであることを確認すると、1つのコピーを削除できます。
2013年

回答:


6

少数の特異値/ベクトルのみが必要な場合は、ARPACKがうまくいくはずです。SVDドキュメントは素晴らしいではありません、そして、この分布は、より最新です。

編集:これをPythonで実行したい場合、SciPyにはラッパーがあります。マトリックスが密集しているため、ブロックスパース行(BSR)形式を試すことができます。


ARPACKがどのようにPythonと統合されるかを見ていきます...
Jan

1
scipyにはラッパーがあるようです。回答の本文に追加します。
Max Hutchinson

2

見てみましょうsklearn.decomposition.TruncatedSVDscikit-学ぶ 0.14-RCを。
(scikit-learnの人々はstackoverflow.com/questions/tagged/scikit-learnをフォローして いると思うので、そこで詳細な質問をします。)

(どのくらいのメモリがありますか?106+ doublesはすでに8Gです。)


ご回答有難うございます。今では、私はscipyのルーチンでうまくやっています。また、私はまで行っていません106×10しかし、その約半分までは、私のラップトップでまだ実現可能なことです。必要に応じて、32 GBのRAMを搭載した稼働中のマシンを使用できます。

2

多分これを試すことができます。

https://github.com/jakevdp/pypropack

これは、PROPACKパッケージのPythonラッパーであり、大規模なスパース行列と線形演算子の効率的な部分特異値分解を実装します。


2

インテルMKLは新しいJacobi-SVDアルゴリズムを実装しています。実装の詳細は次のとおりです。http//www.netlib.org/lapack/lawnspdf/lawn169.pdf http://www.fernuni-hagen.de/MATHPHYS/veselic/downloads/j02.pdf

そして、LAPACKルーチン:http : //software.intel.com/sites/products/documentation/hpc/mkl/mklman/GUID-732F9EE1-BCEC-4D9B-9B93-AF5499B21140.htm#DRMAC08-1

ワークサイズはもちろん調節可能です。Cython、SWIG、またはその他のラッピングメカニズムを使用して、PythonからC関数を簡単に呼び出すことができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.