Uber提出損失變化分配方法LCA,揭秘神經網路「黑盒」

  • 2019 年 10 月 7 日
  • 筆記

作者 | Janice Lan,Rosanne Liu等

譯者 | 清兒爸

責編 | 夕顏

出品 | AI科技大本營(ID: rgznai100)

【導讀】神經網路(Neural networks,NN)在過去十年來碩果累累,推動了整個行業的機器學習進程。然而,雖然許多神經網路在一些任務中表現相當出色,但網路本質上是一個複雜的系統,之前的研究已經分析了神經網路訓練的過程,但它在很大程度上仍然是一個黑盒子,我們對其訓練和操作模式仍然知之甚少。因此,產學研界都在為更好地理解網路屬性和模型預測而不懈努力。 針對這個問題,Uber 在論文中提出了一種稱為損失變化分配 (Loss Change Allocation,LCA)的方法,為神經網路訓練過程提供了豐富的觀察窗口,有望提高神經網路的可解釋性。

在 Uber,工程師們將神經網路用於各種目的,包括檢測和預測自動駕駛車輛的目標運動,更快地響應客戶,以及構建更好的地圖。

在神經網路訓練過程中,儘管數以百萬計的參數在訓練期間可以通過簡單的規則進行調整,但我們對過程本身的看法仍然局限於標量損失量,這嚴重限制了我們對豐富、高維處理過程的了解。例如,可能網路的一部分正在執行所有的學習,而另一部分卻是無用的,但是僅僅觀察損失,永遠不會揭示這一點。

在 Uber 的論文《LCA:神經網路訓練的損失變化分配》(LCA: Loss Change Allocation for Neural Network Training)中,Uber 提出的 LCA 方法可以將損失的變化分配給各個參數,從而度量每個參數的學習量。使用 LCA,Uber 提出了三個關於神經網路有趣的觀察,包括噪音、層貢獻和層同步。

LCA方法詳解

揭示神經網路訓練過程的詳細見解的一種方法是,度量神經網路的每個可訓練參數在任何時間點的學習量。此處 Uber 將「學習」視為對網路的改變,從而降低訓練集的損失。請注意,他們考慮的是整個訓練集的損失,而不僅是一批;在 SGD 中,雖然批量驅動參數更新,但他們衡量的是整個訓練集的學習。

假設正在訓練一個網路,在一次訓練迭代中,參數向量從

移動到

。由於這一運動,損失從 1.85 減少到 1.84。在這種

情況下,可以說網路「學會了」將損失減少 0.01。我們可以通過一階泰勒級數來近似這種損失的變化:

一個與我們可以直接計算近似的量似乎毫無意義,但近似並非 Uber 的最終目標:Uber 用近似來將標量損失的變化分解成單個的分量。在這種情況下,方程的右側是兩個向量的點積,其長度等於參數的數量。Uber 可以將這個點積分解成它的分量總和:

其中,

是參數向量或梯度向量上的索引。通過在每個訓練迭代中對此進行度量,能夠將標量損失的變化分配給各個參數。Uber 將其稱為損失變化分配(Loss Change Allocation,LCA):參數在迭代中的移動造成的損失上升或下降的程度。下面是 LCA 的一些直觀屬性:

  • 如果參數具有零梯度或者不移動,那麼它的 LCA 為零,如圖 1b 所示。
  • 如果參數具有非零梯度並沿著負梯度方向移動,那麼它具有負 LCA,如圖 1c 所示。Uber 稱這些參數為「幫助」,因為它們減少了迭代中的損失。
  • 如果參數沿著梯度的正方向移動,它就會因為增加損失而「受傷」。這可能是由於嘈雜的小批量或動量導致的參數移動錯誤方向引起的。

圖 1. 損失表面的虛構示例 (a) 描述了兩個參數的 LCA。一個參數 (b) 移動但不影響損失,另一個參數 (c) 具有負 LCA,因為它的移動導致損失減少。

LCA 分量具有很好的接地特性,這意味著它們是損失的實際變化的總和(對近似方法作了一些修改,考慮了曲率,並保證精度,正如 Uber 在論文所揭示的那樣)。在整個訓練過程中,度量每個參數和迭代的 LCA。對參數進行求和,將得到每次迭代的總損失變化量;如果對迭代進行求和,將得到每個參數的總 LCA。

通過訓練顯微鏡進行可視化

有了如上所述定義的 LCA 度量,Uber 就可以將其作為顯微鏡,用於訓練數據集(例如 MNIST 或 CIFAR-10)的一些示例網路的訓練過程。對於 MNIST,Uber 訓練了兩個網路:FC(一個三層全連接網路)和 LeNet(一個帶有兩個卷積層,然後是兩個全連接層的網路)。對於 CIFAR-10,Uber 訓練了 ResNet(一個 20 層的殘差網路)。本文中所有的網路都使用 SGD 進行訓練(要了解其他網路和優化器的結果,請參閱 Uber 的論文)。

在下面的影片中,Uber 將直接對 LCA 數據進行可視化,每個幀給定迭代中所有參數的 LCA。FC 在本例中表示,每個像素代表一個參數,以層的形式布置。

影片 1. Uber在 MNIST 上為 FC 訓練的前 400 次迭代製作了動畫。綠色表示負 LCA(幫助),紅色表示正 LCA(受傷)。

在上面的影片中,Uber看到了一些趨勢:

  • 迭代 1-10:在開始時,損失急劇下降,Uber看到許多綠色參數。
  • 迭代 10-100:經過幾次迭代之後,Uber看到綠色和紅色的嘈雜混合,表明一些參數是有幫助的,而另一些參數正在受傷。
  • 迭代 100+:一旦損失接近其最終值,Uber看到大多數像素接近白色,表明參數不再具有明顯的幫助或傷害。

本文的第 S2 節提供了更多直接可視化的示例。這樣的可視化很吸引人,可以幫助表面缺陷或識別死亡的神經元和無用的參數,但很難從中得出更多的定量結論。為了更好地理解更高級別的 LCA 模式,Uber 接下來嘗試一些定量聚合。

結果 1:訓練很嘈雜

Uber 考慮的第一個聚合是 LCA 值在所有參數和所有迭代上的分布。下面的圖 2 顯示了 ResNet 的 LCA 分布,其中綠色條表示有助於損失的分量,紅色條表示傷害損失的分量:

圖 2. 顯示所有 LCA 元素分布情況的直方圖(所有迭代中的所有參數),顯示只有不到一半是負數(幫助)。相應的直方圖以對數刻度(左)顯示,以查看分布的尾部和常規刻度(右),以便更清楚地顯示負 / 正比率。

LCA 分布有幾個有趣的屬性。在繪製這張圖之前,Uber 已經知道這個分布的均值是多少:平均 LCA 僅為(總損失變化)/(參數數量 x 訓練步驟數量)。對於圖 2 中的運行,平均值為 -2.4e-9,用藍線高亮顯示。假設平均值是 -2.4e-9,Uber可能已經預期在該值附近會有一個狹窄的正態分布。相反,他們看到的是一個非常廣泛的分布。事實上,它是如此之寬,以至於在這種細節層面上,它的均值與 0 無法區分。這意味著,並非所有的網路參數都在單一方向上移動,將網路推向更低的損耗,而是在訓練過程中充滿了幫助和受傷的參數之間的競爭。LCA 也是重尾分布的:如果它是正態分布的,那麼對數空間中的直方圖就會呈現出倒拋物線的形狀。

Uber 可以通過計算幫助(綠色)而不是受傷(紅色)的權重百分比來量化這種張力。他們發現,在給定的迭代中,只有 80.7% 的權重對該網路有幫助。換言之,在任何給定的時間裡,所有參數只有不到一半對網路訓練是有幫助的,其餘的參數都朝著錯誤的方向移動!

令人驚訝的是,正 LCA 參數朝著錯誤的方向移動,這引發了一些額外的問題:

  • 隨著訓練網路的時間越來越長,損失最終會停止下降,可以想像,有幫助的參數百分比將會收斂到 50%。因此,他們不禁要問:這個接近 50% 的比例,僅僅是否因為網路訓練時間過長而產生的?然而,下面的圖 3a 表明,情況並非如此:在訓練期間的大多數時間點,這個比率僅略高於 50%,在最速學習的早期迭代中,這一比例略高,但仍然低於 60%。
  • 其次,鑒於許多函數的幫助被許多參數的傷害所抵消,那麼一些參數是否一直在「幫忙」,如果是,它們是否一直被其他參數的傷害所抵消?換句話說,是否有一些「英雄」參數幾乎一直在幫助,而「惡棍」參數卻不斷造成傷害?但圖 3b 顯示並非如此:幫助最多的參數通常在 53% 的時間內有幫助,而幫助最少的參數仍然有 48% 的時間幫助。

圖 3. 研究發現:(a) 在所有迭代中,參數的幫助率接近 50%;(b) 所有參數的幫助大約為一半時間。

這兩個觀察結果在很大程度上可以解釋為訓練中普遍存在的震蕩現象。在下面的圖 4 中,Uber展示了兩個示例參數隨時間變化的運動、底層梯度和結果 LCA。在這些圖標中,可以清楚看到震蕩現象:

圖 4. 顯示了 ResNet 最後一層的兩個參數:在給定的迭代過程中,一個參數傷害最大(頂部),另一個參數幫助最大(底部)(net LCA 分別為 +3.41e-3 和 -3.03e-3)。權重(橙色)和梯度(藍色)軌跡都在震蕩,導致 LCA(綠色和紅色)在幫助和傷害之間交替。

除了震蕩權重和梯度之外,圖 4 還揭示了參數的運動和底層梯度有同時波動的趨勢。這表明震蕩是由於參數在局部極小值上來回擺動所致,與小批量雜訊驅動無關。

雖然圖 4 中只顯示了兩個參數,但震蕩在整個訓練和整個網路中是普遍存在的。例如,在所描述的運行期間,權重值平均每 7 次迭代改變方向,梯度每 10 次迭代改變符號。事實上,即使調整學習率、批量大小和動量值,使網路能夠合理地訓練,仍然可以觀察到震蕩普遍存在,並測量出近一半的參數會受到傷害(詳情請參閱 Uber 的論文)。

通過這些實驗,LCA 揭示了關於神經網路訓練的第一個見解:在任何給定的時間,幾乎將近一半的參數都會受到傷害,或者在訓練梯度上出現偏差。網路之所以能夠進行整體學習,只是因為許多有雜訊的 LCA 分量的平均值略微為負。

結果 2:有些層是向後的

Uber 不僅可以使用自己方法來研究低層次的、每個參數的 LCA,也可以在更高層次的分解上聚合 LCA。Uber 期望,通過這種方式能夠看到不同的見解;在參數級別上有很多噪音,但總體來說,網路是有學習能力的。聚合 LCA 的一種方法是對每一層中所有參數和所有時間進行求和。這可以度量每一層在訓練過程中的學習量,如下面的圖 5 中兩個網路所示:

圖 5. Uber對 FC(左)和 LeNet(右)的每個層中的所有參數進行 LCA 求和。不同的層學習不同的數量,每層 LCA 的差異主要可以通過層中參數的數量來解釋。

如果按照參數的數量將每一層的 LCA 進行歸一化,不出意外的話,我們會看到相反的效果,其中較小的層的參數平均具有更多的 LCA。接下來,我們來看看 ResNet 是否表現出不同的行為:

圖 6.ResNet 揭示了一個不同的模式:第一層和最後一層具有正 LCA,這意味著它們的移動實際上增加了訓練過程的損失。這很讓人驚訝,因為網路總體上是有學習能力的,而且對於一大組參數的 LCA 總和而言,持續為正是沒有意義的。

雖然 FC 和 LeNet 並沒有給出任何令人驚訝的結論,但 Uber 注意到,ResNet 有些不正常。第一層和最後一層具有正 LCA,這意味著它們的移動實際上增加了訓練過程中的損失!雖然他們已經觀察到個別參數受到傷害,但Uber預計在大群體上進行總和時,LCA 將為負,因為平均 LCA 為負。然而,對於這些有害的層來說,情況並非如此,它們每次運行時,LCA 始終為正(並且 10 次運行時 p-value < 1e-4)。

對於這個奇怪的結果,Uber 想知道:如果一個層受傷了,那麼在初始化時就凍結該層會怎麼樣呢?通過阻止權重移動,Uber 就可以阻止讓它受到傷害或幫助。這會讓網路整體表現變得更好嗎?Uber 在第一層嘗試了這項技術,但最終的損失並沒有變得更好:即使阻止了第一層的傷害,其他的層也沒能起到同樣的作用。因此,儘管 LCA 為正,但第一層的參數移動是很重要的。然而,如果凍結最後一層(如圖 7 所示),它將提高整體網路性能,從而降低整體損失。

圖 7. Uber 展示了 ResNet 中每層的 LCA,用於常規訓練場景(實心柱),以及在初始化時凍結最後一層(陰影線)的場景,平均每個場景超過 10 次運行。通過凍結最後一層,Uber可以防止它受到傷害。雖然其他層的幫助沒有那麼多(LCA 的負面影響較小),但最後一層 LCA 的變化彌補了這一點,從而降低了整體損失(圖右)。

這些結果表明,最後一層最好要凍結。先前的研究已經發現凍結最後一層或者用不同的方法對其進行不同的處理是有好處的。LCA 提供了原則性的提示,即凍結最後一層可能會更好,同時也解釋了它最初的問題所在:它普遍地受到了傷害。

為了理解為何一個層會首先受到傷害,Uber 考慮了一些可能的原因。小批量梯度是整個訓練集梯度的無偏估計,因此,小批量雜訊本身並不能解釋總 LCA 為何為正。Uber 之前觀察到的參數震蕩現象是另一種可能的解釋,但如果沒有其他因素的話,震蕩不應該導致在錯誤的方向上的漂移,因此這也不能解釋為何總 LCA 為正。

在排除這些選項之後,Uber 假設解釋與不同層對優化器相應的速度有關。如果由於各種因素的收斂,各層以不同的延遲進行學習,那麼最後一層可能會一直滯後於其他層,與其他層稍微不同步。由於層間競爭以減少損失,延遲的最後一層可能會喪失收集 LCA 的能力。

幸運的是,Uber 可以通過優化器的動量直接調整每個層的延遲來檢驗這個假設是否正確。由於動量

是過去梯度的指數加權平均值,因此 Uber 使用的平均梯度是

迭代的。到目前為止,Uber 對每一層都使用了動量 0.9,對應 9 次迭代的延遲。動量為 0 時,延遲則為 0。如果減少最後一層的動量,就能夠減少最後一層相對於其他層的延遲。

Uber 可以在不同的最後一層延遲級別下運行同一個網路,從 0 到 9 次進行迭代,而保持所有其他層的持續延遲為 9。正如假設的那樣,最後一層的延遲越少,它的幫助就越大!從傷害到幫助的轉變幾乎與延遲成線性關係。此外,由於其他層相對於最後一層的延遲更大,它們會因為現在的滯後和最後一層向前推進而受到更大的傷害,如下圖 8 所示:

圖 8. Uber 為最後一層訓練了一個具有不同動量的 ResNet,並為每層繪製了總 LCA(為了更好的可視化效果,省略了前十層)。隨著最後一層動量的減少,梯度新區驅動學習相對於其他層的延遲減小,最後一層的 LCA 以其他層的損失為代價向前推進。

從這些實驗中,LCA 揭示了不同層的行為是不同的,有些層甚至在平均水平上逆著梯度移動,並受到傷害。通過資訊延遲的角度來看訓練,似乎是有效的。總之,這些結果表明,對每層進行優化調整可能是有益處的。

層是同步的

現在,Uber 已經了解了每一層的整體學習情況,下一步自然是研究不同層何時進行學習。先前的研究已經發現了層表示的廣泛手鏈模式,但通過使用 LCA,Uber 可以在較小的範圍內檢查層間的學習。

LCA 方法的一個有用的特性是,它讓研究人員可以分析他們所關心的任何損失函數。Uber 可以利用這一點,將訓練集的損失分解成 10 個單獨的損失(每個真相類 1 個),畫出更加細化的訓練過程視圖,使 Uber 能夠確定每一層何時學習對分類有用的概念(在這種情況下,是 MNIST 的每個類)。

為了精確定位最高時間解析度的學習,Uber 將層和類的「學習峰值時刻」定義為該層和類的 LCA 的局部最小值。換句話說,該類的損失由於該層在迭代 t 上的移動而減少,而非由於 t+1 或 t-1 的移動而減少。

在下面的圖 9 中,Uber 為 MNIST-FC 的每個層和每個類繪製了學習的前 20 個峰值時刻:

圖 9. Uber 將 MNIST-FC 的「學習峰值時刻」按層和類進行可視化,每個點代表特定類和層的 LCA 峰值,其中網路中的三個層顯示為三個堆疊的點。當所有個層的學習在同一次迭代中排列起來時,Uber 用紅色標出這些點。

奇怪的是,研究人員經常在一條直線上看到三個點的集合(以紅色高亮表示可見性),這意味著所有三個層都在完全相同的迭代中為同一個類學習了一些東西。假設層是獨立進行的,那麼精確排列的學習峰值時刻的平均數量明顯要高於預期的數量 (p < 0.001)。

這些點的同步不能簡單地使用單個批次在網路中引起大的同步變化來解釋,因為雖然權重運動也是同步的(見 Uber 論文中圖 S18),但峰值權重運動和峰值 LCA 的迭代通常不會重合。每層和類的漸變也是同步的(見論文的圖 S15),這是另一個令人驚訝的觀察結果:對於同一次迭代的所有層,每類訓練集的損失會變得非常大,這無疑有助於時同步學習成為可能。

這就引出了 Uber 最後的結論:層學習在微觀尺度上是同步的。

總結和展望

Uber 已經介紹了損失變化分配(LCA)方法,並通過以各種方式聚合 LCA 來證明,他們可以發現訓練過程中的雜訊,發現某些層對梯度的奇異流動,並揭示增量學習的跨層同步。

在論文中,Uber 詳細闡述了這些發現,分析了更多的網路和優化器,並討論了這項工作的前景。例如:

  • 到目前為止討論的所有實驗都使用了訓練集。如果Uber 也 跟蹤驗證 LCA,可以比較訓練 LCA 和驗證 LCA 來度量哪些參數導致了過擬合。這種分析可以實現有針對性的正則化。
  • LCA 可用於識別沒有幫助的權重,因此是修剪或重新初始化的目標。除了識別要凍結的層之外,LCA 還可能是一個重要的診斷工具,用於識別次優超參數或配置不良的網路結構。
  • 更好的優化器可能能夠考慮到頻繁的參數級的震蕩現象,或者實現每層可調的超參數。

LAC 的可能性多種多樣,可用於任何參數化模型。如果你對這項工作感興趣,可詳讀完整論文,並咋你自己的網路下試驗一下程式碼。

論文鏈接:https://eng.uber.com/research/lca-loss-change-allocation-for-neural-network-training/

GitHub 程式碼:https://github.com/uber-research/loss-change-allocation

原文鏈接:https://eng.uber.com/loss-change-allocation/

(*本文為AI科技大本營編譯文章,轉載請微信聯繫1092722531)