c++向量和数组的区别_向量,矩阵和张量的导数 | 简单的数学
前段時間看過一些矩陣求導的教程,在看過的資料中,尤其喜歡斯坦福大學CS231n卷積神經網絡課程中提到的Erik這篇文章。循著他的思路,可以逐步將復雜的求導過程簡化、再簡化,直到發現其中有規律的部分。話不多說,一起來看看吧。
撰文 | Erik Learned-Miller
翻譯 | 寫代碼的橘子
來源 | 橘子AI筆記(ID:datawitch)
本文旨在幫助您學習向量、矩陣和高階張量(三維或三維以上的數組)的求導方法,以及如何求對向量、矩陣和高階張量的導數。
01. 簡化,簡化,再簡化
在求關于數組的導數時,大部分困惑都源自于我們想要一次同時做好幾件事。這“幾件事”包括同時對多個元素求導、在求和符號下求導以及應用鏈式法則。至少在我們積累豐富的經驗之前,想要同時做這么多件事情是很容易犯錯的。
1.1 寫出矩陣中單個元素的表達式
為了簡化給定的計算,有一種方法是:寫出輸出中單個標量元素的表達式,這個表達式只包含標量變量。一旦寫出了輸出中單個標量元素與其他標量值的表達式,就可以使用標量的微積分求導方法,這比同時進行矩陣的求和、求導要容易得多。
例子 假設我們有一個長度為C的列向量
,它是由 行 列的矩陣 與長度為 的向量 計算得到的:式(1)假設我們想求
對 的導數。完整的求導過程需要計算 中的每一個元素對 中的每一個元素的(偏)導數,在這種情況下,我們會算出 個元素,因為 中有 個元素而 中有 個元素。讓我們先從計算其中一個元素開始,比如,
中的第3個元素對 中的第7個元素求導。也就是說,我們要計算也就是一個標量對另一個標量求導。
在求導之前,我們要先寫出
的表達式。根據矩陣-向量乘法的定義,矩陣 的第3行與向量 的點積就是 的值。式(2)此時,我們已經將原始矩陣方程式(1)簡化為了一個標量方程,從而更容易計算所需的導數。
1.2 去掉求和符號
雖然我們可以嘗試直接求式(2)的導數,但包含求和符號(
)或連乘符號( )的表達式在求導時很容易出錯。為了確保萬無一失,在剛開始的時候最好去掉求和符號,把各項相加的表達式寫出來。我們可以寫出以下表達式,下標由“1”開始當然,這個表達式中包括了含有
的項,這一項正是我們求導需要的項。現在不難看出,在求 對 的偏導數時,我們只關心這個表達式中的一項, 。由于其他項都不包括 ,他們對 的導數都是0。由此,我們寫出式(3)-式(6)通過把關注點放在y中的一個元素對x中的一個元素的求導過程,我們盡可能地簡化了計算。以后當你在矩陣求導計算中產生困惑時,也可以試著將問題簡化到這個最基本的程度,這樣便于看清哪里出了問題。
1.2.1 完成求導:雅可比矩陣
別忘了,我們的終極目標是計算
中每個元素對 中每個元素的導數,這些導數總共有 個。以下矩陣可以表示所有這些導數:在這種特殊情況下,它被稱為雅可比矩陣(Jacobian maxtirx),但這個術語對理解我們的目的而言并不那么重要。
注意,對于公式
對 的偏導數可以簡單地用 來表示。如果挨個兒檢查整個矩陣中的所有元素,就不難發現,對所有的 和 來說,都有也就是說,偏導數的矩陣可以表示為
現在可以看出,這個矩陣當然就是矩陣
本身。因此,推導了這么半天,我們終于能得出,對
求
對 的導數相當于2. 如果是行向量該怎么算
在使用不同的神經網絡庫時,留意權重矩陣、數據矩陣等矩陣的具體表達形式是非常重要的。例如,如果一個數據矩陣
包含許多不同的向量,那么,在這個矩陣中,是一個行向量表示數據集中的一個樣本,還是一個列向量表示一個樣本?在第一部分的例子中,我們計算的向量
是一個列向量。然而,當 是行向量的時候你也得明白該怎么算。2.1 第二個例子
假設
是含有 個元素的行向量,它是由含有 個元素的行向量 與 行 列的矩陣 計算得到的:雖然
和 中的元素數量都和之前一樣,但矩陣 的形狀相當于我們在第一個例子中使用的矩陣 的轉置(transpose)。尤其是因為我們現在是矩陣 左乘 ,而不是之前的右乘,現在的矩陣 必須是第一個例子中矩陣 的轉置。在這個例子中,寫出
的表達式會得到
注意這個例子中的元素序號與第一個例子中相反。如果寫出完整的雅可比矩陣,我們仍然可以得出
式(7)3. 超過二維的情形該怎么算
現在假設一個與前兩部分密切相關的情形,如下式
在這個情況下,
沿一個坐標軸變化,而 沿兩個坐標軸變化。因此,整個導數自然會是一個三維數組。在這里,我們避免使用“三維矩陣”這樣的術語,因為尚不清楚矩陣乘法和其他矩陣運算在三維數組中是如何定義的。在處理三維數組的時候,嘗試去找出展示它們的方法可能會帶來不必要的麻煩。相反,我們應該簡單地用表達式寫出結果,用這些表達式可以計算出所需三維數組中的任何元素。
讓我們繼續以標量導數的計算開始,比如y中的一個元素
和 中的一個元素 。我們先用其他標量寫出 的表達式,這個表達式還要體現出 在其計算中所起的作用。然而,我們發現
在 的計算中沒有起到任何作用,因為式(8)也就是說
不過,
對 中第3列元素求導的結果一定是非零的。例如 對 的偏導數為式(9)其實仔細看式(8)就很容易發現這一點。
一般情況下,當
中元素的下標等于 中元素的第二個下標時,這個偏導數就是非零的,反之則為零。我們由此寫出:除此以外,三維數組中的其他元素都是0。如果用
表示 對 求導得出的三維數組其中
但是
中的其他項都為0。最終,如果我們定義一個新的二維數組
就可以看出,我們需要的所有關于
的信息實際上都可以用 來儲存,也就是說, 的非零部分其實是二維的,而不是三維的。以緊湊的形式表示導數數組對于神經網絡的高效實現而言至關重要。
4. 有多條數據該怎么算
前面的例子已經是很好的求導練習了,但如果需要用到多條數據,也就是多個向量
堆疊在一起構成矩陣 時,又該如何計算呢?我們假設每個單獨的 都是一個長度為 的行向量,矩陣 是一個 行 列的二維數組。而矩陣 ,和之前的例子一樣,是一個 行 列的矩陣。 的定義如下它是一個
行 列的矩陣。因此, 的每一行將給出一個與輸入 的相應行相關的行向量。按照我們寫出給定元素表達式的方法,可以寫出
我們馬上就能從這個式子中看出,對于偏導數
只有
的時候計算結果才不為零。也就是說,因為 中的每一個元素都只對 中相應的那一行求導, 與 的不同行之間的偏導數都為0。我們可以進一步發現
式(10)完全不依賴于我們比較的是
和 的哪一行。事實上,矩陣
完整包含了所有的偏導數——我們只需要根據式(10)和下標來找到我們想要的特定偏導數。如果用
表示 中的第 行,用 表示 中的第 行,可以發現正是對之前式(7)的一個簡單的普遍化形式。
5. 向量和矩陣中的鏈式法則
我們已經通過幾個例子學會了一些基本形式的計算,現在通過鏈式法則把這些例子結合在一起。再次假設
和 是兩個列向量,讓我們從下式開始嘗試計算
對 的導數。我們可以簡單地觀察到兩個矩陣 和 的乘積就是另一個矩陣 ,因此可以寫出然而,我們想通過鏈式法則來定義中間結果,以觀察在非標量求導過程中是如何應用鏈式法則的。
我們把中間結果定義為
于是有
然后我們可以運用鏈式法則寫出
為了確保我們確切地知道該式的含義,再次采用每次分析一個元素的老辦法,從
中的一個元素和 中的一個元素開始:右邊的乘積該怎么解釋呢?鏈式法則的思想是將
對每個標量中間變量的導數與中間變量對 的導數相乘。特別地,如果 有 個元素,那么可以寫出回憶之前關于向量對向量求導的計算方法,發現
其實是
,而其實是
。所以可以寫出這就是用
中的元素寫出的求導表達式,至此我們得出了答案。綜上所述,我們可以用鏈式法則來表示向量和矩陣的導數,只需要注意:
- 清楚說明中間結果和表示中間結果的變量,
- 表示出最終導數中各個元素的鏈式法則,
- 對鏈式法則表達式中的中間結果適當求和。
總結
以上是生活随笔為你收集整理的c++向量和数组的区别_向量,矩阵和张量的导数 | 简单的数学的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++五子棋_Java五子棋实现
- 下一篇: s3c2440移植MQTT