CS231n-2017 Lecture7訓練神經網絡(二)筆記

本節主要是神經網絡的動態部分,也就是神經網絡學習參數和搜索最優超參數的過程

梯度檢查:

進行梯度檢查,就是簡單地把解析梯度與數值計算梯度進行比較,防止反向傳播的邏輯出錯,僅在調試過程中使用。有如下技巧 :

使用中心化公式:

在使用有限差值近似計算數值梯度時,常見的公式是:

\frac{df(x)}{dx} = \frac{f(x+h)-f(x)}{h}?h是一個很小,近似為1e-5的數,但這個公式不常用且不好用

經常使用的是下方的中心化公式:

\frac{df(x)}{dx} = \frac{f(x+h)-f(x-h)}{2h}

該公式在檢查每個梯度的維度的時候,要求計算兩次損失函數,但梯度的近似值會準確很多,因為使用泰勒展開(這里假設原函數可以泰勒展開),則中心化公式的誤差近似O(h^2)

使用相對誤差來比較:

比較數值梯度f^{'}_n與解析梯度f_a^{'}有哪些需要注意的細節,進而知道他們不匹配呢?

通常使用相對誤差來進行量化,即:

\frac{|f_a^{'}-f_n^{'}|}{max(|f_a^{'}|,|f_n^{'}|)}

當然,還必須注意兩個式子的梯度都為0的情況

量化閾值如下:

相對誤差>1e-2:通常意味著梯度出錯

1e-2>相對誤差>1e-4:較有可能出錯

1e-4>相對誤差:對有不可導點的目標函數可以接受,但若目標函數中沒有(tanh和softmax),這個相對誤差還是太高

1e-7>相對誤差:認為正常

以上的浮點數運算都要使用雙精度浮點數

目標函數的不可導點(kinks):

在進行梯度檢查時,不可導點是導致不準確的原因之一,可能是由ReLU,SVM損失、Maxout神經元等引入,也就是x+h在不可導點的一側,而x-h在不可導點的另一側導致的。在計算損失的過程中,是可以知道不可導點有沒有被跨過的,在具有max形式的函數中持續追蹤保留梯度的變量身份,就可以實現這一點,若在計算f(x+h)和f(x-h)的時候,至少有一個變量其梯度保留情況變了,就說明不可導點被越過了,數值梯度會不準確

使用少量數據點:

解決上述不可導點問題的一個方法,因為含有不可導點的損失函數的數據點越少,在計算梯度時越過不可導點的概率就越小,所以使用少量數據點,可以使梯度檢查變高效

設置合適的步長h:

數值計算梯度的h并不是越小越好,當h特別小時,很可能會遇到數值精度問題,當梯度檢查出問題時,不妨將h調大一點,可能會恢復正常

梯度檢查的時間:

梯度檢查時在參數空間中的一個特定單獨點(往往隨機取)進行的,即使是在該點梯度檢查成功了,也不能馬上確保全局上的梯度實現都是正確的,且隨機的初始化可能不是參數空間中最優的代表性的點,這可能會導致梯度表面上正確實現。比如,SVM使用小數值權重初始化,就會把一些接近于0的得分分配給所有的數據點,而梯度將會在所有的數據點中展現出某種模式,不正確實現的梯度也許仍然能夠產生出這種模式,但是其無法泛化到更具代表性的操作模式,比如在一些數據點的得分比另一些要大的時候失效。因此,最好讓網絡學習先“預熱”一小段時間,等到損失函數開始下降之后,再進行梯度檢查。在第一次迭代就進行梯度檢查的話,若此時處于不正確的梯度邊界情況,無法被察覺,從而掩蓋了梯度沒有正常實現的事實

正則化蓋過數據損失:

Loss通常是數據損失和正則化損失的和,在某種情況,正則化損失的梯度有可能會遠大于數據損失,進而掩蓋掉數據損失梯度的不正確實現。因此,推薦先關掉正則化,單獨對數據損失做梯度檢查,然后再對正則化損失做梯度檢查

關閉Dropout和數據擴張(augmentation):

在進行梯度檢查時,需要關閉具有不確定效果的操作,比如Dropout和隨機數據擴展,否則會在計算數值梯度時導致巨大誤差。但是,關閉這些操作,會導致無法對這些操作進行梯度檢查,所以,更好的方法是在計算f(x+h)和f(x-h)之前,強制增加一個特定的隨機種子,確保偽隨機

檢查少量的維度:

實際模型中,梯度可以有上百萬的參數,這種情況下只能夠檢查其中的一些維度,然后假設其他維度是正確的,但是要確認在所有不同的參數中都抽取一部分來梯度檢查,比如可能偏置會占掉權重矩陣的一部分,則隨機有概率只隨機到偏置參數

進行參數學習之前的合理性檢查:

1.尋找特定情況的正確損失值

在使用小參數進行初始化時,確保得到的損失值與期望一致。最好先單獨檢查數據損失(令正則化損失為0),若跑出來損失值與期望不一致,那么可能在初始化中就出了問題

2.提高正則化強度時,觀察損失值是否變大

3.對小數據子集過擬合:

在整個數據集進行訓練之前,嘗試在一個很小的數據集上進行訓練,然后確保能到達0的損失值,最好令正則化強度為0。除非能通過這一個過擬合檢查,否則對整個數據集進行訓練時沒有意義的。但是,能對小數據子集進行過擬合,不代表完全正確,仍有可能存在不正確的實現,比如,因為某些錯誤原因,數據點的特征是隨機的,這樣算法也有可能對小數據進行過擬合,但在整個數據集上訓練的時候,就不會產生泛化能力。

檢查整個學習過程:

在訓練神經網絡時,需要追蹤多個重要數值

在下方的圖表中,x軸通常表示周期(epochs)單位,該單位衡量了在訓練中每個樣本數據都被觀測過的次數的期望

損失函數:

訓練期間第一個要跟蹤的數字就是Loss,它在前向傳播時對每個獨立的batch數據進行計算

左圖不同曲線對應了不同學習率下loss隨epoch的變化,可以看到,過低的學習率導致loss的下降是現行的,高一些的學習率會看起來呈幾何指數下降。更高的學習率會使Loss下降得很快,但是接下來就會停在一個不好的損失值上(綠線)。這是因為最優化的能量太大,參數只能在混沌中隨機震蕩,無法最優化到一個很好的點上。

右圖顯示了一個經典的隨時間變化的損失函數值

損失值的震蕩程度和batch size有關,當batch size = 1時,震蕩會相對較大,當batch size 就是整個數據集時,震蕩就會最小,因為這時每次梯度更新都是在單調地優化Loss

訓練集和驗證集準確率:

在訓練分類器的時候,需要跟蹤的第二重要的數字就是驗證集和訓練集的準確率,這個圖表能夠使我們了解模型過擬合的程度

訓練集準確率和驗證集準確率之間的間隔指明了模型過擬合的程度,比如

藍色的驗證集正確率相較于訓練集正確率低了很多,就說明模型有很強的過擬合,遇到這種情況,就應該增大正則化強度,或者收集更多的訓練數據

另一種情況是驗證集曲線和訓練集曲線相近,這種情況說明模型參數容量不夠大,需要增大參數數量

權重更新比例:

最后一個需要跟蹤的量是權重中所有更新值的和與全部權重值之和的比例,一個經驗的結論是,這個比例應該要在1e-3左右,如果更低,說明學習率太小,如果更高,說明學習率過高

每層的激活數據及梯度分布:

一個不正確的初始化可能使學習過程變慢,甚至停止。其中一個檢查方法就是輸出網絡所有層的激活數據和梯度的柱狀圖,直觀的來說,如果看到任何奇怪的分布情況,那很可能有異常。如,對使用tanh的神經元,我們應該看到激活數據的值在整個[-1,1]區間中都有分布,如果看到神經元的輸出全都是0,或者全都聚集在-1/1,那就肯定有問題了

第一層可視化:

如果數據是圖像像素數據,那么把第一層特征可視化會有幫助,如圖:

這是將神經網絡第一層權重可視化的例子,可以發現左側的特征中充滿了噪聲,這暗示網絡可能出現了問題:網絡沒有收斂、學習率設置不恰當,正則化懲罰的權重過低等

而右圖的特征就不錯,平滑干凈且種類繁多,說明訓練過程良好進行

參數更新:

在能使用反向傳播計算梯度的前提下,梯度就能夠被用來進行參數更新了

隨機梯度下降及各種更新方法:

普通更新:

最簡單的更新形式就是沿著負梯度方向改變參數(因為梯度指向的是上升方向,但我們通常希望最小化損失函數),假設有參數向量x和梯度dx,則簡單的更新形式為:

x+= - learning_rate * dx

動量(Momentum)更新:

這個方法在深度網絡中幾乎總能得到更好的收斂速度

原理:

我們將Loss理解為山的高度(而重力勢能是U=mgh,所以有U正比于h),用隨機數字初始化參數等同于在某個位置給質點設置初速度為0,則最優化過程可以看作是模擬參數向量(質點)在地形上滾動的過程

因為作用于質點的力與梯度的潛在能量有關(Fh = W = -U = -mgh \Rightarrow F=-\nabla U),質點所受的力就是損失函數的負梯度,又因為F=ma,所以負梯度與質點的加速度是成比例的。即梯度影響加速度,加速度影響質點的速度,速度再影響質點在山中的位置

更新形式:

v = mu * v - learning_rate * dx // 更新速度
x += v //更新位置

這里引入了一個初始化為0的變量v,和一個超參數mu,mu被看作動量(一般設置為0.9),其有效地抑制了速度,降低了系統的動能(即質點上次的速度方向會影響該次的速度方向)

mu通常設置為[0.5, 0.9, 0.95, 0.99]中的一個,動量隨時間慢慢提升有時能略微改善最優化的結果

Nesterov動量:

與不同變量不同,其核心思想是,觀察上文的動量公式,x會通過mu*v而稍微改變,而mu*v是在還沒計算梯度之前就已經確定的,我們可以將未來的近似位置x+mu*v看作是“預測未來”,x+mu*v這個點一定在我們等會梯度下降更新后要停止的位置附近,因此,我們不妨計算x+mu*v的梯度,而不是x的梯度

如圖所示,既然我們知道mu*v會把我們帶到綠色箭頭指向的點,我們就不在原地(紅色點)計算梯度了,我們在綠色箭頭所指的點計算梯度

#易于理解的實現版本
x_ahead = x + mu * v
v = mu * v - learning_rate * dx_ahead
x += v#實際實現版本
v_prev = v
v = mu * v - learning_rate * dx
x += -mu * v_prev + (1 + mu) * v

學習率退火:

在訓練深度網絡的時候,讓學習率隨著時間退火(逐漸減小)通常是有幫助的。因為如果學習率很高,系統的動能就過大,參數向量就會無規律地跳動,不能夠穩定到損失函數更深更窄的局部極值去。

實現學習率退火的方式:

1.隨步數衰減:

每進行幾個epoch就根據一些因素降低學習率。典型的是每過5個epoch就將學習率減少一半,或者每20個epoch將學習率減少到之前的0.1,具體數字設定嚴重依賴于具體問題和模型。

經驗做法:使用一個固定的學習率來進行訓練的同時觀察驗證集的錯誤,每當驗證集錯誤率停止下降時,就乘一個常數(例如0.5)來降低學習率

2.指數衰減:

公式為\alpha = \alpha_0e^{-kt},其中\alpha_0為初始學習率,k是超參數,t是迭代次數,也可以使用epoch

3.1/t衰減

公式為\alpha = \frac{\alpha_0}{1+kt}

在實踐中,隨步數衰減的dropout更受歡迎,因為它使用的超參數可解釋性比k更強,若有足夠的計算資源,可以讓衰減更緩慢一些,讓訓練時間更長

逐參數適應學習率方法:

前面討論的方法都是對學習率進行全局的操作,且對所有參數,其學習率都是一樣的,下面要介紹的方法是能夠適應性地根據參數來調整其對應的學習率,從而使得每個參數的學習率可能都不一樣。

Adagrad:

cache += dx**2
x += -learning_rate * dx / (np.sqrt(cache) + eps)

cache與梯度矩陣size一致,跟蹤了每個參數梯度的平方和,被用來歸一化參數更新步長(學習率),這樣一來,高梯度值的權重的學習率被減弱,低梯度值的權重的學習率被增強。平方根的操作非常重要,加入eps噪聲是為了防止除0,該算法的缺點是學習率單調變小通常過于激進,且過早停止學習

RMSprop:

是Adagrad的改進

cache = decay_rate * cache + (1 - decay_rate) * dx**2
x += - learning_rate * dx / (np.sqrt(cache) + eps)

decay_rate是取值在[0.9, 0.99, 0.999]的超參,cache變成了梯度平方的滑動平均,從而使學習率不會單調變小

Adam:

m = beta1 * m + (1 - beta1) * dx
v = beta2 * v + (1 - beta2) * dx ** 2
x += - learning_rate * m / (np.sqrt(v) + eps)

這里的更新方法和RMSProp很像,但其使用的是平滑版的梯度m

超參數調優:

訓練一個神經網絡會遇到很多的超參數設置,常用的有:

初始學習率

學習率衰減方式

正則化強度

實現:

更大的神經網絡需要更長的時間去訓練,所以調參可能幻幾天甚至幾周。一個設計代碼的思路是:

使用子程序持續地隨機設置參數,然后進行最優化,訓練過程中,子程序會對每個周期后驗證集的準確率進行監控,然后寫下一個記錄點日志。還有一個主程序,他可以啟動或者結束計算群中的子程序,根據篩選條件查看子程序寫下的記錄點,輸出它們的訓練統計數據,所謂海選。

比起交叉驗證,最好使用一個驗證集:

大多數情況下,一個size合理的驗證集可以使代碼更簡單

超參數范圍:

在對數尺度上進行超參數搜索,例如,一個典型的學習率搜索應該是這樣:

learning_rate = 10**uniform(-6,1)

這是因為如果只采取固定的線性步長分布的話,當學習率很小或者很大的話,步長對學習率的相對改變量差異是巨大的,所以我們采取對數尺度。但對于一些特別的參數(比如dropout),我們還是采取在原始尺度上搜索(dropout = uniform(0,1))

隨機搜索優于網絡搜索:

通常有部分超參數比其他超參數更重要,通過隨機化搜索,而不是網格化搜索,可以更精確地發現較重要的超參數的好數值

對于邊界上的最優值要謹慎:

這種情況一般發生在搜索范圍不好的情況,若我們得到的超參數較優值在搜索邊界上,我們就需要調整我們的搜索范圍

從粗到細地分階段搜索:

可以先進行粗略的范圍搜索,然后根據最優值出現的地方,縮小范圍進行搜索。進行粗搜索的時候,訓練一個epoch就可以了,因為很多超參數的設定會讓模型無法學習。搜索的范圍越精細,訓練的epoch越多

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/93070.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/93070.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/93070.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

IntelliJ IDEA 中左上方未顯示項目根目錄問題

問題: 在IDEA中編寫代碼時,發現左上方只顯示項目的子模塊,未顯示根項目名稱。 如圖所示,未顯示子模塊的根項目:問題分析 頂層根目錄未被識別為項目根目錄,需要手動添加識別。 問題解決 進入File – Project…

OpenCV 圖像變換全解析:從鏡像翻轉到仿射變換的實踐指南

前言處理圖像時,翻轉、旋轉、平移等操作很常用。OpenCV 提供了簡單的方法實現這些變換,本文帶你快速學會用它做圖像翻轉和仿射變換。1 圖像翻轉(圖像鏡像旋轉)在OpenCV中,圖片的鏡像旋轉是以圖像的中心為原點進行鏡像翻轉的。cv2.flip(img,fl…

【運維】Linux運維命令記錄

重置root密碼使用命令重新設置一下root賬戶的密碼 passwd root根據提示設置一下密碼,然后使用sudo -i 時輸入密碼就可以切換到root賬戶了ssh登陸以后,要用sudo -i命令給用戶提權,提到超級管理員,然后輸入密碼才有用

PandasAI連接LLM進行智能數據分析

1. 引言 Pandas是一個數據分析開源組件庫,提供了高性能、易用的數據結構和數據分析工具。它的核心的功能是其DataFrame對象,這是一個帶有行和列標簽的二維表格數據結構,支持缺失數據處理、時間序列功能、靈活的數據輸入輸出方法、數據對齊和…

Spring之【Bean的生命周期】

目錄 1、生成BeanDefinition BeanDefinitionRegistry接口 DefaultListableBeanFactory實現類 2、合并BeanDefnition AbstractBeanFactory類 3、BeanFactoryPostProcessor的方法回調 AbstractApplicationContext類 PostProcessorRegistrationDelegate類 4、BeanPostPro…

搜狐新聞直播間適配HarmonyOs實現點贊動畫

01背景介紹隨著新聞客戶端鴻蒙單框架系統適配工作的推進,從原來的基礎功能到現在已經適配全功能的85%以上。與此同時,我們也在持續深入挖掘鴻蒙系統的特性,以提升整體應用的質量與用戶體驗。在這一過程中,動畫作為增強交互與視覺體…

83、設置有人DTU設備USR-M100采集傳感器數據,然后上傳阿里云服務

基本思想:設置M100 采集傳感器數據 一、首先將DTU設備USR-M100連接路由器上,然后使用python代碼搜索同一局域網設備, import platform import sys import os import time import threadinglive_ip = 0def get_os():os = platform.system()if os == "Windows":re…

P1019 [NOIP 2000 提高組] 單詞接龍

題目描述單詞接龍是一個與我們經常玩的成語接龍相類似的游戲,現在我們已知一組單詞,且給定一個開頭的字母,要求出以這個字母開頭的最長的“龍”(每個單詞都最多在“龍”中出現兩次),在兩個單詞相連時&#…

詳解力扣高頻SQL50題之1633. 各賽事的用戶注冊率【簡單】

傳送門:1633. 各賽事的用戶注冊率 題目 用戶表: Users -------------------- | Column Name | Type | -------------------- | user_id | int | | user_name | varchar | -------------------- user_id 是該表的主鍵(具有唯一值的列)。 該表中的每行包…

FROM stakater/java8-alpine 構建cocker鏡像

在 Dockerfile 中,FROM stakater/java8-alpine 是第一條也是最核心的指令,它定義了構建新鏡像所基于的「基礎鏡像」。以下是逐層解析:🔍 關鍵字拆解 1. FROM —— 起點指令 ? 作用:聲明當前鏡像的起點(父鏡…

Word2Vec模型訓練全流程解析:從數據預處理到實體識別應用

請添加圖片描述 訓練Word2Vec模型 概述 問題 我們如何訓練Word2Vec模型?在特定數據集上訓練Word2Vec模型何時是有利的? 目標 理解在自有數據上訓練Word2Vec模型而非使用預訓練模型的優勢 Colab環境配置 運行以下代碼以啟用輔助函數并重新讀取數據…

在Ubuntu上使用QEMU學習RISC-V程序(2)gdb調試

文章目錄一、準備工作二、基本調試流程1. 設置斷點2. 執行程序3. 查看源代碼/匯編三、查看寄存器1. 查看通用寄存器2. 查看特殊寄存器四、查看內存1. 內存查看命令2. 內存修改命令五、調試實戰示例六、高級調試技巧1. 條件斷點2. 自動顯示3. 內存斷點(觀察點&#x…

不止于“亮”:一盞智慧路燈的技術進化史——塔能科技用“落地性”定義行業標準

在凌晨3點的園區道路之上,路燈會隨著車輛的靠近而自動亮起,待車輛逐漸遠去之后,又會緩緩地調暗下來;當電纜意外被觸碰的時候,系統能夠在短短3秒之內自動發出報警信息,并且推送出維修工單;而當一…

Redis的String數據類型底層實現

redis就是用c語言寫,但redis的string并沒有直接用c語言的string,而是自己搞了一個 SDS 結構體來表示字符串。SDS 的全稱是 Simple Dynamic String,中文叫做“簡單動態字符串”。想知道為什么這么做,我們先看看c語言的string是什么…

【音視頻學習】四、深入解析視頻技術中的YUV數據存儲方式:從原理到實踐

文章目錄 引言 1. YUV 基礎:為什么它比 RGB 更適合視頻? 1.1 YUV 與 RGB 的核心區別 1.2 YUV色度下采樣簡介 2. YUV 的三大存儲方式 方式一:平面格式(Planar) 方式二:半平面格式(Semi-Planar ) 方式三:打包格式(Packed YUV) 三種存儲方式對比: 3. 如何選擇合適的 Y…

前端項目組成

一、前端項目常見模塊及功能(以 Vue/React 通用結構為例) 前端項目的模塊本質是「按功能拆分的代碼文件/文件夾」,就像蓋房子的「磚、梁、窗」各司其職:模塊類型功能說明(大白話)舉個例子pages(…

聚觀早報 | 猿編程推動中美青少年AI實踐;華為Pura 80數字版售價公布;iPhone 17 Air電池曝光

聚觀早報每日整理最值得關注的行業重點事件,幫助大家及時了解最新行業動態,每日讀報,就讀聚觀365資訊簡報。整理丨肖羽7月24日消息猿編程推動中美青少年AI實踐華為Pura 80數字版售價公布iPhone 17 Air電池曝光亞馬遜收購AI初創公司Bee蜂巢半固…

unittest 案例執行順序詳解

unittest 案例執行順序詳解在 unittest 框架中,測試用例的執行順序有默認規則,也可通過自定義方式調整。以下是具體說明:一、默認執行順序規則unittest 對測試用例的執行順序遵循 “按測試方法名的 ASCII 碼排序” 原則,具體邏輯如…

【web大前端】001_前端開發入門:創建你的第一個網頁

前端開發入門:創建你的第一個網頁 在當今數字化時代,網頁已經成為人們獲取信息和交流的重要平臺。對于想要學習編程的人來說,前端開發往往是一個不錯的起點。本文將帶你通過簡單的兩步,創建屬于你的第一個網頁程序。 點擊這里去…

HTTP性能優化終極指南:從協議原理到企業級實踐

前言:為什么性能優化是Web開發的生命線?根據Google研究數據,當頁面加載時間從1秒增加到3秒時,跳出率提升32%;當達到5秒時,轉化率下降90%。本文將通過七層優化體系,帶您掌握HTTP性能優化的核心技…