關於分類問題中的啟用函式特性影響

2022-08-27 08:00:12 字數 4479 閱讀 2265

哈哈,先原諒這乙個月在重圍中的藉口。有幾次想起還有blogs這件事,也是覺得可能這個月沒有publication留下。結果剛才debug發現了些有趣的事情,當然,現象是表面,insight是關鍵。由此的事情遠沒有完成,先在這裡記下,探索也是部分的需要計畫的:)

事情源於之前做的乙個分類問題,由於牽涉了新設想的結構和函式,於是只是在固定的極小樣本集裡面先train一下,看看是否能夠達到飽和。但是從後面的結果來看,acc在0.6-0.7範圍中就停止了(由於樣本數量只有128個作為一次性的batch-data輸入,進行多次的反覆update,檢查了abs-grad-sum,發現在長時段內趨於0)。

最開始,我以為是容量不夠,於是擴大了寬度,發現效果輕微;後面又引入低層的特徵進行擴容嘗試,收穫了相同的結果。

今天下午又拿出來試了下,卻意外的把gradblock放在了這個子項(classification)的最終啟用函式之後(後面檢查時才發現的),結果發現很快就收斂到飽和狀態。

檢查了幾遍系統後,我只將block那行注釋,確定系統不能達到飽和。於是開始關注啟用層,用tanh替換了所有夾在預訓練model的conv層以外的relu,並取消對grad的block,發現系統較快的就達到飽和(在abs-grad-sum還沒有低於10的時候);之後有將系統逐漸縮小引數規模,發現在最開始的規模上,同樣可以達到飽和。

一些觀點需要在這裡整理。

先來整理下除錯的路徑。

乙個比較關鍵的現象是切斷grad在最末的啟用函式與後續(全連線)的系統後,系統出現了預期的飽和狀態;

另外,替換relu為tanh後,系統收斂較慢,但依然在短期內到達飽和。

全部使用relu,在更長時間的將abs-grad-sum趨於0的嘗試的末尾,依然收斂在較低水平。

在這裡說些看法。

從以上的debug中,容易產生這樣的想法,問題的產生源於兩種啟用函式的不同。但具體是怎樣的一種特性解釋,需要討論。

一種想法是,relu的死區使大量單元陷入,導致效能下降,這種看法可能成立(後面與大師兄談論,大師兄的第一反應是relu的死區丟失了資訊);但1的觀測說明在relu之前的系統即使通過隨機初始化,後面的資訊也是足夠用來使之飽和。

另一種,想法是:不可導的特性,使以此啟用函式為節點的前後兩個子系統在梯度下降的優化策略中,出現了前後不一致

後續的系統通過梯度計算出前面的系統應該做出的調整,但後向傳播通過relu時卻帶上了某種程度的不可預見性(不能根據梯度資訊來確定調整後會出現的狀態),造成的結果就是優化過程變得不穩定(可能前後一致性不統一聽起來更慎重),也就是說前後子系統的優化方向發生偏差。

另外,從最終收斂,但效能較低的情況看,死區的存在也是有貢獻的。

說道此處,順帶說下,我對relu於分類問題的看法。

還想得起之前在畢業設計文中,寫到不動點對映特性是解決分類問題的關鍵(當時還沒有了解到relu的存在)。而relu正是具備這樣的特性,死區的存在使得有更大的機會進行不動點對映系統的構建。稍微牽強些,是否可以認為這種特性正好是利於進行特徵提取的?而對分類問題可能還需要對特徵的敏感性?但這樣看,對於分類問題,到底是否還是乙個單純的不動點對映問題?

在這種觀點下,是否可以認為relu類的帶有某種不動點特性的函式,更適宜進行定性,而於回歸問題,存在這缺陷;

還有些路徑需要執行才能驗證上文的部分猜測。

替換relu為leaky-relu,重新測試

若干未列明,跑路要緊。。。

今早試了下用leaky-relu進行替換的試驗。

按照昨天的觀點,由於函式導數的不連續性,後向傳播方式下的梯度優化將產生不穩定現象。

看到結果之前我的猜測是中途可能出現不穩定,但由於死區特性得到了弱化,在後期會出現收斂(飽和)。但結果卻出現了gradient explosion,以下是每次更新後,計算的abs-grad-sum結果:

info: 2017-10-31 09:56:14,343 clip.py [line: 7]  gradient sum: 2570469.820984

info: 2017-10-31 09:56:18,898 clip.py [line: 7] gradient sum: 7628072.981415

info: 2017-10-31 09:56:23,442 clip.py [line: 7] gradient sum: 104128273.523438

info: 2017-10-31 09:56:27,982 clip.py [line: 7] gradient sum: 1003394306.062500

info: 2017-10-31 09:56:32,531 clip.py [line: 7] gradient sum: 26595445776.000000

info: 2017-10-31 09:56:37,070 clip.py [line: 7] gradient sum: 82864352460.000000

info: 2017-10-31 09:56:41,611 clip.py [line: 7] gradient sum: 2485723173798.000000

info: 2017-10-31 09:56:46,155 clip.py [line: 7] gradient sum: 14795568299674.000000

info: 2017-10-31 09:56:50,706 clip.py [line: 7] gradient sum: 340887166279834.000000

info: 2017-10-31 09:56:55,246 clip.py [line: 7] gradient sum: 1506918417760358.000000

info: 2017-10-31 09:59:05,430 clip.py [line: 7] gradient sum: 119767988743176352.000000

info: 2017-10-31 09:59:09,977 clip.py [line: 7] gradient sum: 217811190464643200.000000

info: 2017-10-31 09:59:14,519 clip.py [line: 7] gradient sum: 9045955479473225728.000000

info: 2017-10-31 09:59:19,065 clip.py [line: 7] gradient sum: 48279445897211805696.000000

info: 2017-10-31 09:59:23,603 clip.py [line: 7] gradient sum: 1324136950814446977024.000000

info: 2017-10-31 09:59:28,138 clip.py [line: 7] gradient sum: 6650622893084393865216.000000

info: 2017-10-31 09:59:32,678 clip.py [line: 7] gradient sum: 137297709636549848596480.000000

info: 2017-10-31 09:59:37,218 clip.py [line: 7] gradient sum: 1513821207037384203436032.000000

info: 2017-10-31 09:59:41,755 clip.py [line: 7] gradient sum: nan

info: 2017-10-31 09:59:46,290 clip.py [line: 7] gradient sum: nan

這個試驗,我在不同時間測試了兩次,最終結果是一致的。看來不穩定狀態是存在的,但最終卻成了誤差振盪器。

對比relu和leaky的結果,更容易使人相信的是,前者沒有產生explosion的原因很有可能是,嚴格死區的存在使系統保持了性質上的穩定;而leaky中,負向性質的死區,給系統埋下了**的機會。

從以上討論來看,在relu的不飽和情況中,有較大的可能,收斂時relu的輸出幾乎全部為0,關於此一點可以參考,abs-grad-sum為0。

我檢查了下,收斂時histogram分布大致是這樣的:

*fig-1:histogram of relu's output(x ranges from .1 to max)*

這個分布橫座標起止:[.1,max],用以對比0的統計量。

此分布橫座標起止:[-.1,.1]。已經可以看出,明顯地就放在0上。

另外,從fig-1中,了解到,已經出現極大的相應值了,說明這個系統已經廢掉。

從原理上看,bn相當於乙個阻尼器,防止引數過快的變化。所以可以部分地預計到,使用bn後優化過程將會更接近理想狀況。從試驗上來看,在conv之後,引入bn,再接入leaky-/relu,兩者都可以達到飽和。這一點,印證了前述的不穩定預計。

先這樣吧。

關於啟用函式的問題

1 sigmoid函式 優點 一是輸出在 0,1 之間,單調連續,輸出範圍有限。二是容易求導。缺點 一是容易產生梯度消失,導致訓練困難。二是其輸出不是以0為中心。三是要進行指數運算,速度相對較慢。建議 基於上面sigmoid的性質,所以不建議在中間層使用sigmoid啟用函式,因為它會讓梯度消失。2...

ACM sum 求和問題(關於問題中的儲存限制)

problem description in this problem,your task is to calculate sum n 1 2 3 n.input the input will consist of a series of integers n,one integer per lin...

關於intval函式的特性

intval函式有個特性 直到遇上數字或正負符號才開始做轉換,再遇到非數字或字串結束時 0 結束轉換 php function intval intval函式處理的流程 base 10 base為10 break case 2 if zend get parameters ex 2,num,arg ...