私のコードでnp.sum()
関数呼び出しのオーバーヘッドを減らすためにこの問題をどのように変換できるか知りたいのですが。コード最適化 - Pythonでの関数呼び出しの数
私は、shape=(1000, 36)
というinput
の行列を持っています。各行はグラフ内のノードを表します。私は、各行に対して繰り返し処理を行い、可変数の他の行に要素的な追加を行う操作を実行しています。これらの「他の」行は、各行について、合算する必要がある行のリストを記録する辞書nodes_nbrs
で定義されています。ここ
nodes_nbrs = {0: [0, 1],
1: [1, 0, 2],
2: [2, 1],
...}
は、ノード0
ノード0
と1
の和に変換されることになる次のような例があります。ノード1
は、ノード1
,0
、および2
の合計に変換されます。残りのノードについても同様です。
私が現在実装している現在の(そして素朴な)方法はそのままです。私は最初、私がしたい最終形状のゼロ配列をインスタンス化し、次いでnodes_nbrs
辞書の各キーと値のペアを反復:
output = np.zeros(shape=input.shape)
for k, v in nodes_nbrs.items():
output[k] = np.sum(input[v], axis=0)
このコードは、小テスト(shape=(1000, 36)
)内のすべてのクールで結構ですが、より大きいテスト(shape=(~1E(5-6), 36)
)では、完了までに2〜3秒かかります。私はこの作業を何千回もやらなければならなくなるので、これを行うためのより最適化された方法があるかどうかを確認しようとしています。
回線プロファイリングを実行した後、ここで重要なキラーはnp.sum
関数を繰り返し呼び出していることに気付きました。これは合計時間の約50%を占めます。このオーバーヘッドを排除する方法はありますか?それとも、これを最適化できる別の方法がありますか?それとは別に
、ここで私が行っているもののリスト、および(非常に簡単に)その結果である:
cython
バージョンは:、オーバーヘッドチェックfor
ループ型を排除し、30%削減時間がかかる。cython
バージョンでは、np.sum
が、壁時計の合計時間の約80%を占め、50%ではなくなります。- を
npsum
として事前に宣言してから、for
ループ内でnpsum
を呼び出します。オリジナルとの違いはありません。 np.sum
をnp.add.reduce
に置き換え、それを変数npsum
に割り当ててから、for
ループ内にnpsum
を呼び出します。壁時計の時間が約10%短縮されますが、次にautograd
と互換性がありません(以下、疎な行列の箇条書きの説明を参照)。numba
JIT-ing:デコレータの追加以上の試みはしませんでした。改善はしなかったが、もっと努力しなかった。nodes_nbrs
辞書を高密度numpy
バイナリアレイ(1と0)に変換してから、np.dot
オペレーションを1回実行します。理論的には良いですが、メモリ使用量が二次的なshape=(10^n, 10^n)
の正方行列を必要とするため、実際には悪いです。
私がしようとしたが、そうすることを躊躇していなかったもの:
scipy
スパース行列を:私はscipy
スパース行列に対してdot
操作の自動微分をサポートしていないautograd
を、使用しています。興味がある人のため
、これは本質的に、グラフ構造データ上の畳み込み演算です。大学院のためにこれを開発することは楽しいですが、知識の最先端にいくらか不満を抱いています。
あなたの例から飛び出ることの1つは、いくつかの構成が他のもののサブセットであるという概念です。例えば、あなたは '0:[0,1]'と '1:[1,0,2]'を持っています。つまり、0を計算し、1を0プライムプラス2元として計算することができます。これは 'np.sum'への呼び出し回数を減らすことはありませんが、呼び出し自体を短縮する可能性があります。それはあなたの状況に「本当の」価値を持っていますか? –
@AustinHstings:返信ありがとうございます!はい、あなたは、部分集合であるいくつかの構成と、いくつかの部分集合によって重複する可能性のあるものがあることは間違いありません。私はそれが価値があると思う。私が今抱えている唯一の懸念は、重複/部分集合であるコンピューティングのオーバーヘッドが、特に数百および数千の行がある場合に、パフォーマンスの向上を上回る可能性があることです。あなたの考えは? – ericmjl
私はそれが(a)どのように "計算可能"なのかに依存していると思います。 (b)あなたの辞書を生成するために使用しているプロセス。特定のタイプのトラバースや何かをしているので、オーバーラップが本当に安価になる場合があります。 –