前面的筆記已經把 BP算法給推導了, 那4大公式, 核心就是 求偏導數的鏈式法則, 這篇, 再來跟着大佬來推一波, 目的是為了加深印象. 關於記憶這個話題, 心理學家,其實早已經給出了答案, 最好的記憶方式, 就是重復, 寫了這么多的筆記, 其實大多內容都是重復的, 交叉的, 反復了, 但不同是, 每次反復, 其實都是一個認知理解上升的過程, 覺得還是很有必要的.
BP算法-變量聲明
回顧歷史
還是跟之前一樣的, 先做一個簡單的介紹, 然后對變量進行聲明, 力求跟寫代碼的邏輯一樣, 嚴謹, 規范, 有注釋, 邏輯清晰, 模塊化和面向對象
先是來簡單介紹一波BP算法.
最早在1970年代就已經有人提出了, 直到1986年, 深度學習的大佬們才在論文中闡述其重要性.
在80年代中期, 這些大佬分別獨立發現了 誤差反向傳播算法 (Error Back Propagation Training) 簡稱BP, 解決了, 多層神經網絡, 隱含層連接權值學習問題.
BP 用來干嘛: 根據訓練的誤差, 來 動態 更新節點之間的 權值 .
分別獨立發現: 好比牛頓和萊布尼茲 分別從各自領域創建了微積分.
不由感慨, 成功的大佬, 都是類似的, 我等凡人失敗的借口, 總是各有各的說辭, 真的好扎心, 而又無可奈何呀.
BP算法相對於其他的神經網絡學習算法會快很多, 這樣就擴展了神經網絡的解決問題的能力和領域. 直到目前, BP算法依然是深度學習的主要基石.
BP算法的核心是 求解誤差函數 Loss 相對於權重 weights 和偏置 bias 的偏導, 來揭示 一旦改變 w, b 如何影響網絡的整體行為.
而求解過程呢, 從數學上來說, 就是 多元變量求偏導的鏈式法則. 大一的微積分基礎呀, 沒錯, 其實一點都不復雜的.
變量聲明
重點是理解 反向 即從 從右到左 的方向哦;
- \(w^l_{jk}\) 第 l 層, 第 j 個節點, 到 第 \((l-1)\) 層的 第 k 個節點的 權值 (weight) ( 反向, 反向, 方向, 反向, 說了4遍)
- \(w^l\) 第 l 層, 的 權值矩陣, 第 j 行, 第 k 列 為 \(w^l_{jk}\)
- \(b_j^l\) 第 l 層, 第 j 個節點 的 bias (偏置)
- \(b^l\) 第 l 層, 的 bias 向量
- \(a^l_j\) 第 l 層, 第 j 個節點的 激勵 (activation)
- \(a^l\) 第 l 層, 的 激勵 向量
假設激活函數是 \(\sigma\) , 根據網絡 層次間的 映射(加權求和) 的關系, (每個神經元的模型):
單個神經元: \(a^l_j = \sigma(\sum\limits _k w^l_{jk} \ a^{l-1}_k + b^l_j)\)
該層的神經元: \(a^l = \sigma (w^l a^{l-1} + b^l)\)
如不能理解每個變量代表的意義, 就看圖, 非常直觀的呀
\(z^l = w^l a^{l-1} + b^l\)
\(z^l\) The weighted input to the neurons in layer l.
再定義一個中間變量 \(z^l\) 即 第 l 層神經元的 加權求輸入向量, 其分量, \(z^l_j\) 為第 l 層, 第 j 個神經元的 加權求和輸入.
\(z^l_j =\sum \limits_k w_{jk} a_k ^{l-1} + b^l_j\)
於是呢, 對於每個節點的輸出, 就可以簡單表示為 (向量形式哈) :
\(a^l = \sigma(z^l)\)
然后來看定義 損失函數, 采用咱最熟悉的 平方損失 的形式:
-
\(y = y(x)\) 樣本 x 的標簽向量 (期望輸出)
-
\(a^L = a^L(x)\) 樣本 x 的網絡輸出激勵向量
-
n : 表示樣本數量; L 表示網絡層數
樣本 x 表示向量, 每個分量也是一個向量(多特征), 對應於數據的每一行. 因此, x 寫出來就是 nxp的矩陣
\(C = \frac {1}{2n} \sum \limits_x ||y(x) - a^L(x)||^2\)
這個 0.5 都懂哈, , 沒啥特定意義. 就是求導的時候, 式子的2范數, 要把2拿下來 再 乘0.5, 就為1 , 形式上美觀而已.
代價函數2大假設
假設一:
上面的, 具體到每個值(樣本) , 代價函數可以表示為, 每個訓練樣本 x (是個向量哈) 的代價函數 \(C_x\) 的平均值
\(C_x = \frac {1}{2} ||y - a^L||^2\)
\(C = \frac {1}{n} \sum\limits_x C_x\)
假設二:
代價函數可以表示為, 神經網絡 輸出層的 函數
\(C = \frac{1}{2} ||y-a^L||^2 = \frac {1}{2} \sum\limits_j (y_j - a_j^L)^2\)
這里的 \(y_j 是標簽值, 表示一個常量, a^L_j 表示輸出層向量 a^L 的第 j 個分量, 也是一個常量; C 是輸出層向量 a的函數\)
矩陣的 哈達瑪積 (Hadamard Product)
定義為, 兩個 同維度 的矩陣 / 向量, 對應位置的元素的乘積, 組成的一個新的矩陣/ 向量, 記為 \(A \odot B\)
case:
假設 \(\alpha, \beta\) 是兩個同維度的向量, 其 哈達瑪積 為, 向量各位置的分量 的逐元素相乘.
\((\alpha \odot \beta)_j = \alpha_j * \beta_j\)
\([1, 2] \ \odot \ [3, 4] = [1*3, 2*4] = [3, 8]\)
BP算法 - 四大公式
理解 梯度的反方向
首先就是看看, 網絡中, 一個神經元節點的 權值 變化的話, 對整個網絡的 代價會產生什么樣而影響.
假設, 給第 l 層的 第 j 個神經元的節點值 \(z^l_j\) 加上一個增量, 則對應的 激勵輸出變化為
\(\sigma(z^l_j) \rightarrow \ \sigma(z^l_j + \Delta z^l_j)\)
經過網絡傳播呢, 代價函數的 變化量 為: \(\frac {\partial C} {\partial z^l_j} \Delta z^l_j\)
變化量, 這個式子就是, 微分和導數的關系, \(df(x) = f'(x) dx\) 嗯, 或者理解為, 泰勒級數一階近似也可以.
假設該 梯度 (偏導數值) \(\frac {\partial C} {\partial z^l_j}\) 非常大 (可正, 可負)
始終牢記咱的目標是使得代價函數 C 的值越小越好, 也就是要找到 某一個點, 使得在該點導數值 == 0
- \(\frac {\partial C} {\partial z^l_j}\) 非常大, 則表示 \(z^l_j\) 對於整個網絡的損失函數影響很大, 然后我們會選擇與梯度符號相反的增量. (目的是讓 "df" 接近 0, 接近函數 極值 的位置)
- \(\frac {\partial C} {\partial z^l_j}\) 非常小, 則表示擾動的增量, 不論取何值, 對代價函數的影響很小, 則該神經元對於代價函數傾向於最優 , 也是是到達了函數的 局部極值點.
梯度方向
梯度: 多元函數的偏導數做組成的向量, 本質是一個向量函數.
方向導數: 與偏導數更廣的概念, 偏導是沿着固定的軸方向, 是方向導數的特定情景
方向: 是針對向量來說的, 向量具有大小和方向
- 方向導數最大的方向, 為梯度方向, 其導數值就是梯度的模.
- 方向導數最小的放倆, 為梯度反方向, 其導數方向是梯度的摸
在 ML 中我們絕大多數場景是要 尋找梯度的最小, 最好是零向量, 這樣就是函數的 "極值" 所在的位置.
因此我們總是嘗試沿着 梯度的負方向去求值最小的導數值, 因而求解函數的 極值.
這些就是很基礎的, 高等數學的概念呀, 真的越接近本質, 越發現世界就是有基本的元素0, 1構成的, 也許. "道生一, 一生二, 二生三, 三生萬物" 這是多么朴素的真理呀, 現在想想.
即想說明的是, 因為是要顧及整個網絡結構嘛, 絕對不允許, 特別牛逼的節點存在 對損失函數影響很大的那種, 嗯, 這種思想和 集成學習是一樣的, 都是平凡普通, 才能構成偉大, 不允許突出的兄弟.
梯度大則說訓練得不夠好, 因為在這個節點方向, 只要一稍微擾動該神經元, 就會對代價造成很大的影響;
反之, 梯度小則說明訓練的比較好, 都是同一水平的兄弟, 然后不論這個普通的兄弟發生了什么事情, 都不會對整個代價造成特別大的影響.
這點就特像一些大公司里的螺絲釘, 多你一個不多, 少你一個也不太影響, 整個結構來時還是相對均衡和穩固的呀.
根據梯度的這種特性, 於是, 我們可以定義, 第 l 層, 第 j 個神經元 的誤差為:
\(\delta ^l_j = \frac {\partial C}{\partial z^l_j}\)
tips: 算是第一遇見, 將導數值, 作為誤差, 來訓練, 這個腦洞, 真滴是可以的哦.
於是呢, BP算法就通過, 先求出各層神經元的偏導數,作為誤差, 即相當於對代價C 求關於 權重和偏置 梯度
\(\frac {\partial C} {\partial w^l_{jk}}\) , 以及 \(\frac {\partial C}{\partial b_j^l}\)
上篇就先到這吧, 一次不適合寫太長, 信息太多會吸收不了的, 主要是理解BP到底在干嘛, 誤差如何定義等這些概念的理解, 下篇就具體的公式推導和代碼, 只有充分理解了上篇, 才能搞明白下篇的公式是是在做什么, 才能實現后面的手擼BP的呀.