天天看點

BP算法完整推導 2.0 (上)

BP再次推導, 重點了解BP過程及變量定義, 尤其是将誤差, 定義為 梯度, 這腦洞太大了.

前面的筆記已經把 BP算法給推導了, 那4大公式, 核心就是 求偏導數的鍊式法則, 這篇, 再來跟着大佬來推一波, 目的是為了加深印象. 關于記憶這個話題, 心理學家,其實早已經給出了答案, 最好的記憶方式, 就是重複, 寫了這麼多的筆記, 其實大多内容都是重複的, 交叉的, 反複了, 但不同是, 每次反複, 其實都是一個認知了解上升的過程, 覺得還是很有必要的.

BP算法-變量聲明

回顧曆史

還是跟之前一樣的, 先做一個簡單的介紹, 然後對變量進行聲明, 力求跟寫代碼的邏輯一樣, 嚴謹, 規範, 有注釋, 邏輯清晰, 子產品化和面向對象

先是來簡單介紹一波BP算法.

最早在1970年代就已經有人提出了, 直到1986年, 深度學習的大佬們才在論文中闡述其重要性.

在80年代中期, 這些大佬分别獨立發現了 誤差反向傳播算法 (Error Back Propagation Training) 簡稱BP, 解決了, 多層神經網絡, 隐含層連接配接權值學習問題.

BP 用來幹嘛: 根據訓練的誤差, 來 動态 更新節點之間的 權值 .

分别獨立發現: 好比牛頓和萊布尼茲 分别從各自領域建立了微積分.

不由感慨, 成功的大佬, 都是類似的, 我等凡人失敗的借口, 總是各有各的說辭, 真的好紮心, 而又無可奈何呀.

BP算法相對于其他的神經網絡學習算法會快很多, 這樣就擴充了神經網絡的解決問題的能力和領域. 直到目前, BP算法依然是深度學習的主要基石.

BP算法的核心是 求解誤差函數 Loss 相對于權重 weights 和偏置 bias 的偏導, 來揭示 一旦改變 w, b 如何影響網絡的整體行為.

而求解過程呢, 從數學上來說, 就是 多元變量求偏導的鍊式法則. 大一的微積分基礎呀, 沒錯, 其實一點都不複雜的.

變量聲明

重點是了解 反向 即從 從右到左 的方向哦;

BP算法完整推導 2.0 (上)
  • \(w^l_{jk}\) 第 l 層, 第 j 個節點, 到 第 \((l-1)\)
  • \(w^l\) 第 l 層, 的權值矩陣, 第 j 行, 第 k 列 為 \(w^l_{jk}\)
  • \(b_j^l\)
  • \(b^l\)
  • \(a^l_j\)
  • \(a^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\)

再定義一個中間變量 \(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)\)
  • \(a^L = a^L(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算法完整推導 2.0 (上)

上篇就先到這吧, 一次不适合寫太長, 資訊太多會吸收不了的, 主要是了解BP到底在幹嘛, 誤差如何定義等這些概念的了解, 下篇就具體的公式推導和代碼, 隻有充分了解了上篇, 才能搞明白下篇的公式是是在做什麼, 才能實作後面的手撸BP的呀.

繼續閱讀