深度學習基礎課:“判斷性別”Demo需求分析和初步設計(下2)
大家好~我開設了“深度學習基礎班”的線上課程,帶領同學從0開始學習全連接和卷積神經網絡,進行數學推導,并且實現可以運行的Demo程序
線上課程資料:
本節課錄像回放1
加QQ群,獲得ppt等資料,與群主交流討論:106047770
本系列文章為線上課程的復盤,每上完一節課就會同步發布對應的文章
本文為第二節課:“判斷性別”Demo需求分析和初步設計(下2)的復盤文章
本課程系列文章可進入索引查看:
深度學習基礎課系列文章索引
回顧相關課程內容
- 第二節課:“判斷性別”Demo需求分析和初步設計(下1)
- 為什么引入損失函數?
- 損失函數的表達式是什么?
- 有了損失函數,如何具體判斷得到一組權重、偏移是合適的呢?
- 什么是隨機梯度下降?
- 更新權重、偏移的梯度下降公式是什么?
主問題:如何求梯度
-
對于“判斷性別”的Demo,??可以是什么函數?
答:
-
如何求\(\frac{dE}{dw_{53}}\)?
答:

參考上面的公式,可知:

-
如何求\(\frac{dE}{db_{5}}\)?
答:與上面類似 -
如何求\(\frac{dE}{dw_{31}}\)?
答:
任務:根據梯度下降算法實現訓練
-
標簽、特征是什么?
標簽是我們要預測的事物,即男/女;
特征是輸入變量,即身高和體重; -
已知4個有標簽樣本(同時包含特征和標簽)用于訓練,2個無標簽樣本用于推理
-
請根據梯度下降算法,實現NeuralNetwork_train的train函數?
- 如何判斷是否達到了希望的結果(即收斂)?
答:打印損失函數返回的誤差loss,如果小于0.1,則收斂 - 如何實現?
答:答案:NeuralNetwork_train_answer
- 如何判斷是否達到了希望的結果(即收斂)?
-
請運行程序
- 有什么問題?
第一輪開始的loss就無限大
- 有什么問題?
任務:改進訓練,使其收斂
- 請找出loss無限大的原因?
答:輸出(y5)太大 - 應該如何改進?
答:改進激活函數,使用sigmoid替代線性函數:


它的導數為:

- 修改代碼,運行結果?
答:修改后的相關代碼為:
let _activateFunc = x => {
1. /. (1. +. Js.Math.exp(-.x))
}
let _deriv_Sigmoid = x => {
let fx = _activateFunc(x)
fx *. (1. -. fx)
}
修改后的完整代碼為:NeuralNetwork_train_fix_activate_answer
運行結果:loss一直不變
(補充:完整代碼有bug:Neural_forward_answer->_activateFunc應該使用sigmoid函數。修改后的完整代碼為:NeuralNetwork_train_fix_activate_answer_fix。修改后的運行結果是loss會先下降到0.25然后就不變了,而不是一直不變)
-
為什么loss一直不變?
答:輸入太大->隱藏層的激活函數的導數為0->梯度為0->loss不變 -
應該如何改進?
答:將樣本零均值化 -
修改代碼,運行結果?
答:修改后的相關代碼為:
let _mean = values => {
values->ArraySt.reduceOneParam((. sum, value) => {
sum +. value
}, 0.) /. ArraySt.length(values)->Obj.magic
}
let _zeroMean = features => {
let weightMean = features->ArraySt.map(feature => feature.weight)->_mean->Js.Math.floor->Obj.magic
let heightMean = features->ArraySt.map(feature => feature.height)->_mean->Js.Math.floor->Obj.magic
features->ArraySt.map(feature => {
weight: feature.weight -. weightMean,
height: feature.height -. heightMean,
})
}
let features = features->_zeroMean
let state = state->train(features, labels)
let featuresForInference = [
{
weight: 89.,
height: 190.,
},
{
weight: 60.,
height: 155.,
},
]
featuresForInference->_zeroMean->Js.Array.forEach(feature => {
inference(state, feature)->Js.log
}, _)
這里的內容是錯誤的,可忽略
運行結果:loss可能會逐漸增大
- 為什么會出現loss逐漸增大的情況?
答:學習率太大
如下圖所示:

因為步長過大,可能會跨過谷底 - 如何解決?
答:有兩個方法:
減小學習率,增加輪數;
使用優化算法動態調整學習率。
這里使用前者 - 修改代碼,運行結果?
答:修改后的相關代碼為:
let train = (state: state, features: array<feature>, labels: array<label>): state => {
//let learnRate = 0.1
//let epochs = 1000
let learnRate = 0.001
let epochs = 100000
...
修改后的完整代碼為:NeuralNetwork_train_fix_zeroMean_answer
運行結果:大部分情況下loss會收斂
(補充:完整代碼仍然有同樣的bug:Neural_forward_answer->_activateFunc應該使用sigmoid函數。修改后的完整代碼為:NeuralNetwork_train_fix_zeroMean_answer_fix。修改后的運行結果是loss基本上都會收斂,所以基本上不會出現“loss可能會逐漸增大”的情況,所以就不需要“減小學習率,增加輪數;”)
總結
- 請回答所有主問題?
- 如何根據梯度下降算法實現訓練代碼?
- 會出現什么問題?如何解決?
浙公網安備 33010602011771號