稀疏矩陣
科學上有句諺語:歸根結底,一切都歸結為矩陣乘法。不管你是在物理或工程中解偏微分方程,還是在用經典模型或深度神經網路進行機器學習,最後,在數值上,都是矩陣和向量的相乘,按一定順序重複。
這些矩陣通常非常大,比如1000000 x 1000000。在這種情況下,如果矩陣沒有特定的結構,那麼你就必須在記憶體中儲存大量的值,而且運算也非常耗時。這叫做稠密矩陣。然而,在許多科學應用中,矩陣確實有一定的結構。
通常,矩陣的大部分值都是零,這樣的矩陣就叫做稀疏矩陣。例如,如果1000000 x 1000000矩陣是對角線的,那麼只需要儲存10^6個值而不是10^12個值。如果用10^6個維向量乘以它,只需要做10^6次乘法而不是10^12次乘法和加法。
差別是巨大的!即使矩陣不是對角的,只要大多數值是零,記憶體和速度優勢是巨大的,因為只需儲存相對較少的非零值,而與向量的乘法只需要考慮那些非零值。
如何使用稀疏矩陣
Python的SciPy包有一個專門用於稀疏矩陣實現的子包。根據你的稀疏矩陣的結構和你想用稀疏矩陣做什麼,包中有針對給定任務最佳化的不同表示。只要使用任何稀疏矩陣類,通常可以獲得99%的速度和記憶體優勢。
首先,考慮一個大的密集矩陣。我們用隨機值填充它,都在-0.5和0.5之間:
然後使用numpy的matmul函式將⋅相乘
這在我的電腦上需要7.07秒。現在讓我們以同樣的方式使用一個對角矩陣,並將其儲存為一個普通矩陣:
這在我的電腦上花了7秒,幾乎是同一時間,儘管我們知道大多數乘法肯定是零。現在我們用同樣的方法來處理稀疏矩陣。因為這裡的矩陣是對角線的,我們可以使用scipy.sparse.diag:
如果你輸出A_sparse,它會說:
所以它實際上是一個10000x10000的矩陣,但是稀疏並且以一種特殊的對角線格式儲存。我們再做一次同樣的乘法:
這在我的電腦上只花了0.003秒,比使用密集矩陣快了2000多倍。