numpys einsum 的不合理用處
介紹
我想向您介紹Python中最有用的方法,np.einsum。
使用 np.einsum(以及 Tensorflow 和 JAX 中的對應項),您可以以極其清晰和簡潔的方式編寫複雜的矩陣和張量運算。 我還發現它的清晰性和簡潔性減輕了許多使用張量帶來的精神負擔。
而且它實際上學習和使用起來相當簡單。 其工作原理如下:
在 np.einsum 中,您有一個下標字串參數,並且有一個或多個運算元:
numpy.einsum(subscripts : string, *operands : List[np.ndarray])
下標參數是一種“迷你語言”,它告訴 numpy 如何操作和組合運算元的軸。 剛開始讀起來有點困難,但是掌握訣竅後也不錯。
單一操作數
第一個範例,讓我們使用 np.einsum 交換矩陣 A 的軸(也稱為轉置):
M = np.einsum('ij->ji', A)
字母 i 和 j 綁定到 A 的第一個和第二個軸。 Numpy 按照字母出現的順序將字母綁定到軸,但如果你是顯式的,numpy 並不在乎你使用什麼字母。 例如,我們可以使用 a 和 b,其工作方式相同:
M = np.einsum('ab->ba', A)
但是,您必須提供與操作數中的軸一樣多的字母。 A 中有兩個軸,因此您必須提供兩個不同的字母。 下一個範例不會工作,因為下標公式只有一個字母要綁定,i:
# broken M = np.einsum('i->i', A)
另一方面,如果操作數確實只有一個軸(即,它是一個向量),那麼單字母下標公式就可以正常工作,儘管它不是很有用,因為它使向量成為原樣:
m = np.einsum('i->i', a)
對軸求和
但是這個操作呢? 右邊沒有 i。 這有效嗎?
c = np.einsum('i->', a)
令人驚訝的是,是的!
這是理解 np.einsum 本質的第一個關鍵:如果一個軸從右側省略,那麼該軸對求和。
代碼:
c = 0 I = len(a) for i in range(I): c += a[i]
求和行為不限於單一軸。 例如,您可以使用下列下標公式同時對兩個軸求和: c = np.einsum('ij->', A):
這是兩個軸上對應的 Python 程式碼:
c = 0 I,J = A.shape for i in range(I): for j in range(J): c += A[i,j]
但它不止於此 - 我們可以發揮創造力,對一些軸進行求和,而忽略其他軸。 例如: np.einsum('ij->i', A) 對矩陣 A 的行求和,留下長度為 j 的行和向量:
代碼:
numpy.einsum(subscripts : string, *operands : List[np.ndarray])
同樣,np.einsum('ij->j', A) 對 A 中的列進行求和。
代碼:
M = np.einsum('ij->ji', A)
兩個操作數
我們用單一運算元可以做的事情是有限的。 使用兩個操作數,事情會變得更加有趣(並且有用)。
假設您有兩個向量 a = [a_1, a_2, ... ] 和 b = [a_1, a_2, ...]。
如果 len(a) === len(b),我們可以這樣計算內積(也稱為點積):
M = np.einsum('ab->ba', A)
這裡同時發生兩件事:
- 因為 i 與 a 和 b 都綁定,所以 a 和 b 會「排列」然後相乘:a[i] * b[i]。
- 因為索引 i 被排除在右側,所以對軸 i 進行求和以消除它。
如果將(1)和(2)放在一起,您將得到經典的內積。
代碼:
# broken M = np.einsum('i->i', A)
現在,假設我們沒有從下標公式中省略i,我們將所有a[i]和b[i]相乘,並且不總和除以i:
m = np.einsum('i->i', a)
代碼:
c = np.einsum('i->', a)
這也稱為逐元素乘法(或矩陣的哈達瑪積),通常透過 numpy 方法 np.multiply 完成。
下標公式還有第三種變體,稱為外積。
c = 0 I = len(a) for i in range(I): c += a[i]
在此下標公式中,a 和 b 的軸綁定到單獨的字母,因此被視為單獨的「循環變數」。 因此,C 對所有 i 和 j 都有條目 a[i] * b[j],排列成矩陣。
代碼:
c = 0 I,J = A.shape for i in range(I): for j in range(J): c += A[i,j]
三個操作數
將外積更進一步,這是一個三操作數版本:
I,J = A.shape r = np.zeros(I) for i in range(I): for j in range(J): r[i] += A[i,j]
我們的三操作數外積的等效 Python 程式碼是:
I,J = A.shape r = np.zeros(J) for i in range(I): for j in range(J): r[j] += A[i,j]
更進一步,沒有什麼可以阻止我們省略軸來對它們求和,除了轉置通過在右側寫ki而不是ik來計算結果->:
numpy.einsum(subscripts : string, *operands : List[np.ndarray])
等效的 Python 程式碼為:
M = np.einsum('ij->ji', A)
現在我希望您可以開始了解如何輕鬆地指定複雜的張量運算。 當我更廣泛地使用 numpy 時,我發現每當我必須實現複雜的張量運算時,我都會使用 np.einsum。
根據我的經驗,np.einsum 讓以後的程式碼閱讀更加容易- 我可以輕鬆地直接從下標讀出上述操作:“三個向量的外積,中間軸相加,最終結果轉置” 。 如果我必須閱讀一系列複雜的 numpy 運算,我可能會發現自己張口結舌。
一個實際的例子
舉一個實際的例子,讓我們實現法學碩士的核心方程,來自經典論文「注意力就是你所需要的」。
等式。 1 描述注意力機制:
我們將把注意力集中在這個字上 KTT >QKTdkk> >1
申請起來很簡單。的 KTT >QKTT
term 表示
m 個查詢與 n
m 個 d 維行向量堆疊成矩陣的集合,因此 Q 的形狀為 md。同樣,K 是 n 個 d 維行向量堆疊成矩陣的集合,因此 K 的形狀為 md。 單一 Q 和 K 之間的乘積可寫為: np.einsum('md,nd->mn', Q, K)
請注意,由於我們寫下標方程式的方式,我們避免了在矩陣乘法之前轉置 K! 所以,這看起來非常簡單 - 事實上,它只是一個傳統的矩陣乘法。 然而,我們還沒有完成。 注意力就是你所需要的使用多頭注意力,這意味著我們確實有k這樣的矩陣乘法在Q矩陣和K矩陣的索引集合上同時發生.為了讓事情更清楚一些,我們可以將產品重寫為 Q我 我T
numpy.einsum(subscripts : string, *operands : List[np.ndarray])
. 這表示我們對於 Q 和 K 都有一個額外的軸 i。 更重要的是,如果我們處於訓練環境中,我們可能正在執行批量這樣的多頭注意力操作。 因此大概想要沿著批次軸 b 對一批範例執行操作。 因此,完整的產品將類似於: 我將跳過這裡的圖表,因為我們正在處理 4 軸張量。 但是您也許可以想像「堆疊」早期的圖表以獲得我們的多頭軸 i,然後「堆疊」這些「堆疊」以獲得我們的批次軸 b。 我很難理解如何使用其他 numpy 方法的任意組合來實現這樣的操作。 然而,經過一些檢查,就很清楚發生了什麼事:在一個批次中,在矩陣 Q 和 K 的集合上,執行矩陣乘法 Qt(K). 現在,這不是很棒嗎? 無恥的插頭 在創辦人模式磨練了一年之後,我正在找工作。 我在各種技術領域和程式語言方面擁有超過 15 年的經驗,並且還有管理團隊的經驗。 數學和統計學是重點領域。 DM 我,讓我們談談!
以上是numpys einsum 的不合理用處的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Python更易學且易用,C 則更強大但複雜。 1.Python語法簡潔,適合初學者,動態類型和自動內存管理使其易用,但可能導致運行時錯誤。 2.C 提供低級控制和高級特性,適合高性能應用,但學習門檻高,需手動管理內存和類型安全。

每天學習Python兩個小時是否足夠?這取決於你的目標和學習方法。 1)制定清晰的學習計劃,2)選擇合適的學習資源和方法,3)動手實踐和復習鞏固,可以在這段時間內逐步掌握Python的基本知識和高級功能。

Python在開發效率上優於C ,但C 在執行性能上更高。 1.Python的簡潔語法和豐富庫提高開發效率。 2.C 的編譯型特性和硬件控制提升執行性能。選擇時需根據項目需求權衡開發速度與執行效率。

Python和C 各有優勢,選擇應基於項目需求。 1)Python適合快速開發和數據處理,因其簡潔語法和動態類型。 2)C 適用於高性能和系統編程,因其靜態類型和手動內存管理。

pythonlistsarepartofthestAndArdLibrary,herilearRaysarenot.listsarebuilt-In,多功能,和Rused ForStoringCollections,而EasaraySaraySaraySaraysaraySaraySaraysaraySaraysarrayModuleandleandleandlesscommonlyusedDduetolimitedFunctionalityFunctionalityFunctionality。

Python在自動化、腳本編寫和任務管理中表現出色。 1)自動化:通過標準庫如os、shutil實現文件備份。 2)腳本編寫:使用psutil庫監控系統資源。 3)任務管理:利用schedule庫調度任務。 Python的易用性和豐富庫支持使其在這些領域中成為首選工具。

Python在科學計算中的應用包括數據分析、機器學習、數值模擬和可視化。 1.Numpy提供高效的多維數組和數學函數。 2.SciPy擴展Numpy功能,提供優化和線性代數工具。 3.Pandas用於數據處理和分析。 4.Matplotlib用於生成各種圖表和可視化結果。

Python在Web開發中的關鍵應用包括使用Django和Flask框架、API開發、數據分析與可視化、機器學習與AI、以及性能優化。 1.Django和Flask框架:Django適合快速開發複雜應用,Flask適用於小型或高度自定義項目。 2.API開發:使用Flask或DjangoRESTFramework構建RESTfulAPI。 3.數據分析與可視化:利用Python處理數據並通過Web界面展示。 4.機器學習與AI:Python用於構建智能Web應用。 5.性能優化:通過異步編程、緩存和代碼優
