人工智慧實踐:Tensorflow2.0 新手筆記(2)
本節目標:學會神經網路的優化過程,使用正則化減少過擬合,使用優化器更新網路引數。
1. 預備知識
(1) tf.where(條件語句, 真返回A, 假返回B)
- 條件語句,如果條件為真返回A,否則返回B
a = tf.constant([1, 2, 3, 4, 4])
b = tf.constant([0, 1, 3, 4, 5])
c = tf.where(tf.greater(a, b), a, b) # 對應元素比較
c
執行結果:
<tf.Tensor: shape=(5,), dtype=int32, numpy=array([1, 2, 3, 4, 5])>
(2) np.random.RandomState().rand()
- 返回一個[0,1)之間的隨機數
np.random.RandomState().rand(維度)
rdm = np.random.RandomState(seed = 11) # seed 可以保障每次執行的結果一致
aa = rdm.rand()
bb = rdm.rand()
cc = rdm.rand(2,3)
print(aa)
print(bb)
print(cc)
0.1802696888767692
0.019475241487624584
[[0.46321853 0.72493393 0.4202036 ]
[0.4854271 0.01278081 0.48737161]]
(3) np.vstack()
- 將兩個陣列按橫向合併
np.vstack(陣列1, 陣列2)
rdm = np.random.RandomState(seed = 11)
aa = rdm.rand(2, 3)
bb = rdm.rand(2, 3)
cc = np.vstack((aa, bb))
print(aa)
print(bb)
print(cc)
執行結果:
[[0.18026969 0.01947524 0.46321853]
[0.72493393 0.4202036 0.4854271 ]]
[[0.01278081 0.48737161 0.94180665]
[0.85079509 0.72996447 0.10873607]]
[[0.18026969 0.01947524 0.46321853]
[0.72493393 0.4202036 0.4854271 ]
[0.01278081 0.48737161 0.94180665]
[0.85079509 0.72996447 0.10873607]]
(4) np.mgrid[] .ravel() np.c_[]
- np.mgrid[] 返回若干組維度相同的等差陣列網格
np.mgrid[起始值 : 結束值 : 步長, 起始值 : 結束值 : 步長, … ]
[起始值,結束值) 前閉後開 - x.ravel() 將x變為以為陣列
- np.mgrid[陣列1, 陣列2, …] 使返回值的間隔數值點配對
x, y = np.mgrid[1:3:1, 2:4:0.5] # 維度一致 所以將x擴充了
print("x = \n", x)
print("y = \n", y)
grid = np.c_[x.ravel(), y.ravel()]
grid
執行結果:
x =
[[1. 1. 1. 1.]
[2. 2. 2. 2.]]
y =
[[2. 2.5 3. 3.5]
[2. 2.5 3. 3.5]]
array([[1. , 2. ],
[1. , 2.5],
[1. , 3. ],
[1. , 3.5],
[2. , 2. ],
[2. , 2.5],
[2. , 3. ],
[2. , 3.5]])
2. 神經網路複雜度
- 神經網路(NN)複雜度:多用NN層數和NN引數的個數表示
- 空間複雜度:
層數 = 隱藏的層數 + 1個輸出層 (輸入層只是將資料傳輸進來,所以不計入)
總引數 = 總w個數 + 總b個數 - 時間複雜度:
乘加運算次數(有多少權重線)
- 空間複雜度:
3. 指數衰減學習率
- 學習率:
w t + 1 = w t − l r ∂ l o s s ∂ w t w_{t+1}=w_{t}-lr\frac{\partial loss}{\partial w_{t}} wt+1=wt−lr∂wt∂loss
w t + 1 w_{t+1} wt+1 | w t w_{t} wt | l r lr lr | ∂ l o s s ∂ w t \frac{\partial loss}{\partial w_{t}} ∂wt∂loss |
---|---|---|---|
更新後的引數 | 當前引數 | 學習率 | 損失函式的梯度(偏導數) |
- 指數衰減學習率:可以先採用較大的學習率,快速得到較優解,然後逐步減小學習率,使模型在訓練後期穩定。
指 數 衰 減 學 習 率 = 初 始 學 習 率 ∗ 學 習 率 衰 減 率 ( 當 前 次 數 / 多 少 次 衰 減 一 次 ) 指數衰減學習率 = 初始學習率*學習率衰減率^{(當前次數/多少次衰減一次)} 指數衰減學習率=初始學習率∗學習率衰減率(當前次數/多少次衰減一次)
epoch = 40
LR_BASE = 0.2
LR_DECAY = 0.99
LR_STEP = 1
for epoch in range(epoch):
lr = LR_BASE * LR_DECAY ** (epoch / LR_STEP)
with tf.GradientTape() as tape:
loss = tf.square(w + 1)
grads = tape.gradient(loss, w)
w.assign_sub =(lr * grads)
print("after %s epoch, w is %f,loss is %f,lr is %f"
% (epoch, w.numpy(), loss, lr))
學習率衰減詳細參考: TENSORFLOW2.0學習率衰減詳細彙總
4. 啟用函式
- 啟用函式(Activation Function):就是在人工神經網路的神經元上執行的函式,負責將神經元的輸入對映到輸出端。
(1) sigmoid函式:
f
(
x
)
=
1
1
+
e
−
x
f(x) = \frac{1}{1+ e^{-x}}
f(x)=1+e−x1
- 優點:
(1)輸出對映在(0,1)之間,單調連續,輸出範圍有限,優化穩定,可用作輸出層;
(2)求導容易 - 缺點:
(1)易造成梯度消失;
(2)輸出非0均值,收斂慢
(3)冪運算複雜,訓練時間長 - sigmoid函式可應用在訓練過程中。然而,當處理分類問題作出輸出時,sigmoid卻無能為力。簡單地說,sigmoid函式只能處理兩個類,不適用於多分類問題。而softmax可以有效解決這個問題,並且softmax函式大都運用在神經網路中的最後一層網路中,使得值得區間在(0,1)之間,而不是二分類的。
(2) tanh函式:
f
(
x
)
=
1
−
e
−
2
x
1
+
e
−
2
x
f(x) = \frac{1- e^{-2x}}{1+ e^{-2x}}
f(x)=1+e−2x1−e−2x
- 優點:
(1)比sigmoid收斂更快
(2)輸出是0均值 - 缺點:
(1)易造成梯度消失;
(2)冪運算複雜,訓練時間長
(3) relu函式:
f
(
x
)
=
m
a
x
(
x
,
0
)
{
0
x
<
0
x
x
>
=
0
f(x) = max(x,0) \begin{cases} 0 & x<0\\ x & x>=0 \end{cases}
f(x)=max(x,0){0xx<0x>=0
tf.nn.relu(x)
- 優點:
(1)解決了梯度消失問題(在正區間)
(2)只需判斷輸入是否大於0,速度快
(3)收斂速度遠快於sigmoid和tanh - 缺點:
(1)輸出非0均值,又會使收斂慢
(2)Dead RelU問題,某些神經元可能永遠不會被啟用,導致相應的引數永遠不能更新,神經元死亡。 - 啟用函式的輸入特徵為負數時,啟用函式的輸出為0,反向傳播得到的梯度是0,導致引數無法更新,造成神經元死亡。其原因是經過relu函式的負數特徵過多導致的,可以改進隨機初始化,避免過多的負數特徵送入relu函式;可以減小學習率,減少引數分佈的巨大變化,避免訓練中
產生過多負數特徵進入relu函式。
(4) Leak Relu函式:
f
(
x
)
=
m
a
x
(
α
x
,
x
)
{
α
x
,
x
<
0
x
x
>
=
0
f(x) = max(\alpha{x},x) \begin{cases} \alpha{x}, & x<0\\ x & x>=0 \end{cases}
f(x)=max(αx,x){αx,xx<0x>=0
tf.nn.leaky_relu(x)
- 理論上講,Leaky Relu有 Relu 的所有優點,外加不會有Dead RelU問題,但是在實際操作中,並沒有完全證明Leaky Relu總是浩宇 Relu,所以使用Relu的更多。
(5) 建議:
- 首選ReLU啟用函式;
- 學習率設定較小值;
- 輸入特徵標準化,即讓輸入特徵滿足以0為均值,1為標準差的正態分佈;
- 初始化問題:初始引數中心化,即讓隨機生成的引數滿足以0為均值, 2 當 前 層 輸 入 特 徵 個 數 \sqrt{\frac{2}{當前層輸入特徵個數} } 當前層輸入特徵個數2
5. 損失函式
- 啟用函式:損失函式用來評價模型的預測值和真實值不一樣的程度,損失函式越好,通常模型的效能越好。不同的模型用的損失函式一般也不一樣。神經網路模型的效果及優化的目標是通過損失函式來定義的。迴歸和分類是監督學習中的兩個大類。
(1) 均方誤差損失函式:
- 均方誤差Mean Square Error):是迴歸問題最常用的損失函式。迴歸問題解決的是對具體數值的預測,比如房價預測、銷量預測等。這些問題需要預測的不是一個事先定義好的類別,而是一個任意實數。
M S E ( y i , y i ^ ) = ∑ i = 1 n ( y i − y i ^ ) 2 n MSE(y_i,\hat{y_i}) =\frac{ \sum_{i=1}^n{(y_i-\hat{y_i})}^2}{n} MSE(yi,yi^)=n∑i=1n(yi−yi^)2
其中 y i y_i yi為一個batch中第i個資料的真實值,而 y i ^ \hat{y_i} yi^為神經網路的預測值。
loss_mes = tf.reduce_mean(tf.square(y_-y))
(2) 交叉熵損失函式:
- 交叉熵Cross Entropy):表徵兩個概率分佈之間的距離,交叉熵越小說明二者分佈越接近,是分類問題中使用較廣泛的損失函式。
H ( y , y ^ ) = − ∑ ( y ^ ∗ l n y ) H(y,\hat{y}) ={ -\sum({\hat{y}}}*{lny} ) H(y,y^)=−∑(y^∗lny)
例:
二分類已知答案y_(1,0), 預測
y
1
=
(
0.6
,
0.4
)
y_1 = (0.6,0.4)
y1=(0.6,0.4)
y
2
=
(
0.8
,
0.2
)
y_2 = (0.8,0.2)
y2=(0.8,0.2),哪一個更接近標準答案?
H
1
(
(
1
,
0
)
,
(
0.6
,
0.4
)
)
=
−
(
1
∗
l
n
0.6
+
0
∗
l
n
0.4
)
=
0.511
H_1((1,0),(0.6,0.4)) = -(1*ln0.6+0*ln0.4) = 0.511
H1((1,0),(0.6,0.4))=−(1∗ln0.6+0∗ln0.4)=0.511
H
1
(
(
1
,
0
)
,
(
0.6
,
0.4
)
)
=
−
(
1
∗
l
n
0.8
+
0
∗
l
n
0.2
)
=
0.233
H_1((1,0),(0.6,0.4)) = -(1*ln0.8+0*ln0.2) = 0.233
H1((1,0),(0.6,0.4))=−(1∗ln0.8+0∗ln0.2)=0.233
loss_ce1 = tf.losses.categorical_crossentropy([1,0],[0.6,0.4])
loss_ce2 = tf.losses.categorical_crossentropy([1,0],[0.8,0.2])
print(loss_ce1)
print(loss_ce2)
執行結果:
tf.Tensor(0.5108256, shape=(), dtype=float32)
tf.Tensor(0.22314353, shape=(), dtype=float32)
- softmax函式與交叉熵函式結合:
正常流程輸出先過softmax函式,使結果符合概率分佈,再計算y和y_的交叉熵損失函式,Tensorflow給出了可以同時計算softmax概率分佈結果和交叉熵的函式:
tf.nn.softmax_cross_entropy_with_logits(y_,y)
6. 欠擬合與過擬合
-
欠擬合:模型不能有效擬合資料集,對現有資料集學習的不夠徹底;
-
過擬合:對當前資料集擬合的太強,但對未見過的新資料不能正確預測,缺乏泛化能力。
-
欠擬合解決方案:
增加輸入特徵項
增加網格引數
減少正則化引數 -
過擬合解決方案:
資料清洗,減少噪聲
增大訓練集
採用正則化
增大正則化引數
7. 正則化減少過擬合
《直觀理解,什麼是正則化》
我們總會在各種地方遇到正則化這個看起來很難理解的名詞,其實它並沒有那麼高冷,是很好理解的…
8. 優化器更新網路引數
神經網路是基於連線的人工智慧,當網路結構固定後,不同引數的選取對模型的表達力影響很大,更新模型引數的過程彷彿教一個孩子理解世界,適齡的孩子都具備了學習的條件,但是不同的引導方法會是孩子具備不同的能力。
- 優化器,就是引導神經網路更新引數的工具。
待優化引數
w
w
w,損失函式
l
o
s
s
loss
loss,學習率
l
r
lr
lr,每次迭代的一個
b
a
t
c
h
batch
batch,
t
t
t 表示當前
b
a
t
c
h
batch
batch 迭代的總次數,更新引數分為4步完成:
1.計算
t
t
t時刻損失函式關於當前引數的梯度
g
t
=
∇
l
o
s
s
=
∂
l
o
s
s
∂
w
t
g_t=\nabla{loss}=\frac{\partial{loss}}{\partial{w_t}}
gt=∇loss=∂wt∂loss
2.計算
t
t
t時刻一階動量
m
t
m_t
mt和二階動量
V
t
V_t
Vt
3.計算
t
t
t時刻下降梯度:
η
t
=
l
r
⋅
m
t
/
V
t
\eta_t = {lr}\cdot{{m_t}}/{\sqrt{V_t}}
ηt=lr⋅mt/Vt
4.計算
t
+
1
t+1
t+1時刻引數:
w
t
+
1
=
w
t
−
η
t
=
w
t
−
l
r
⋅
m
t
/
V
t
w_{t+1} = w_{t}-{\eta_t }=w_{t}- {lr}\cdot{{m_t}}/{\sqrt{V_t}}
wt+1=wt−ηt=wt−lr⋅mt/Vt
- 一階動量:與梯度相關的函式
- 二階動量:與梯度平方相關的函式
- 不同的優化器,實質上只是定義了不同的一階動量和二階動量公式
(1) SGD:
- SGD(無momentum),最常用的梯度下降法:
m t = g t m_t = g_t mt=gt V t = 1 V_t = 1 Vt=1
η t = l r ⋅ m t / V t = l r ⋅ g t \eta_t = {lr}\cdot{{m_t}}/{\sqrt{V_t}} = lr\cdot{g_t} ηt=lr⋅mt/Vt=lr⋅gt
w t + 1 = w t − η t = w t − l r ⋅ m t / V t = w t − l r ⋅ g t w_{t+1} = w_{t}-{\eta_t }=w_{t}- {lr}\cdot{{m_t}}/{\sqrt{V_t}}=w_{t}- lr\cdot{g_t} wt+1=wt−ηt=wt−lr⋅mt/Vt=wt−lr⋅gt
最終得到
w
t
+
1
=
w
t
−
l
r
∂
l
o
s
s
∂
w
t
w_{t+1}=w_{t}-lr\frac{\partial loss}{\partial w_{t}}
wt+1=wt−lr∂wt∂loss
(2) SGDM:
- SGDM(含momentum的SGD),在SGD基礎上增加一階動量。
m t = β ⋅ m t − 1 + ( 1 − β ) g t m_t = \beta {\cdot}{m_{t-1}}+(1-\beta)g_t mt=β⋅mt−1+(1−β)gt V t = 1 V_t = 1 Vt=1
η t = l r ⋅ m t / V t = l r ⋅ m t = l r ⋅ ( β ⋅ m t − 1 + ( 1 − β ) g t ) \eta_t = {lr}\cdot{{m_t}}/{\sqrt{V_t}} = lr\cdot{m_t}={lr}{\cdot}{(\beta {\cdot}{m_{t-1}}+(1-\beta)g_t)} ηt=lr⋅mt/Vt=lr⋅mt=lr⋅(β⋅mt−1+(1−β)gt)
w t + 1 = w t − η t = w t − l r ⋅ m t = w t − l r ⋅ ( β ⋅ m t − 1 + ( 1 − β ) g t ) w_{t+1} = w_{t}-{\eta_t }=w_{t}- lr\cdot{m_t}=w_{t}- {lr}{\cdot}{(\beta {\cdot}{m_{t-1}}+(1-\beta)g_t)} wt+1=wt−ηt=wt−lr⋅mt=wt−lr⋅(β⋅mt−1+(1−β)gt)
m
t
m_t
mt表示各時刻梯度方向的指數滑動平均,和SGD相比一階動量的公式多了
m
t
−
1
{m_{t-1}}
mt−1項(上一時刻的一階動量),且該項在公式中佔比更大,因為
β
\beta
β是一個超引數,接近1(經驗值為0.9)。
(3) Adagrad:
- Adagrad,在SGD基礎上增加二階動量
m t = g t m_t = g_t mt=gt V t = ∑ τ = 1 t g τ 2 V_t = \sum_{{\tau}=1}^t{g_{\tau}^2} Vt=∑τ=1tgτ2
η t = l r ⋅ m t / V t = l r ⋅ g t / ∑ τ = 1 t g τ 2 \eta_t = {lr}\cdot{{m_t}}/{\sqrt{V_t}} = {lr}\cdot{{ g_t}}/{\sqrt{\sum_{{\tau}=1}^t{g_{\tau}^2}}} ηt=lr⋅mt/Vt=lr⋅gt/∑τ=1tgτ2
w t + 1 = w t − η t = w t − l r ⋅ g t / ∑ τ = 1 t g τ 2 w_{t+1} = w_{t}-{\eta_t }=w_{t}- {lr}\cdot{{ g_t}}/{\sqrt{\sum_{{\tau}=1}^t{g_{\tau}^2}}} wt+1=wt−ηt=wt−lr⋅gt/∑τ=1tgτ2
Adagrad是在SGD的基礎上引入二階動量,可以對模型中的每一個引數分配自適應學習率。
(4) RMSProp,SGD基礎上增加二階動量
m t = g t m_t = g_t mt=gt V t = β ⋅ V t − 1 + ( 1 − β ) g t 2 V_t =\beta {\cdot}{V_{t-1}}+(1-\beta)g_t^2 Vt=β⋅Vt−1+(1−β)gt2
η t = l r ⋅ m t / V t = l r ⋅ g t / β ⋅ V t − 1 + ( 1 − β ) g t 2 \eta_t = {lr}\cdot{{m_t}}/{\sqrt{V_t}} = {lr}\cdot{{ g_t}}/{\sqrt{\beta {\cdot}{V_{t-1}}+(1-\beta)g_t^2}} ηt=lr⋅mt/Vt=lr⋅gt/β⋅Vt−1+(1−β)gt2
w t + 1 = w t − η t = w t − l r ⋅ g t / ( β ⋅ V t − 1 + ( 1 − β ) g t 2 ) w_{t+1} = w_{t}-{\eta_t }=w_{t}- {lr}\cdot{{ g_t}}/{({\sqrt{\beta {\cdot}{V_{t-1}}+(1-\beta)g_t^2}})} wt+1=wt−ηt=wt−lr⋅gt/(β⋅Vt−1+(1−β)gt2)
二階動量 V V V使用指數滑動平均值計算,同樣,表徵過去一段時間的平均值
(5) Adam,同時結合SGDM一階動量和RMSProp二階動量
m t = β ⋅ m t − 1 + ( 1 − β ) g t m_t = \beta {\cdot}{m_{t-1}}+(1-\beta)g_t mt=β⋅mt−1+(1−β)gt
修正一階動量偏差: m t ^ = m t 1 − β 1 t \hat{m_t}=\frac{m_t}{1-{\beta_1^t}} mt^=1−β1tmt
V t = β 2 ⋅ V s t e p − 1 + ( 1 − β 2 ) ⋅ g t 2 V_t =\beta_2 {\cdot}{V_{step-1}}+(1-\beta_2){\cdot}g_t^2 Vt=β2⋅Vstep−1+(1−β2)⋅gt2
修正二階動量偏差: v t ^ = v t 1 − β 2 t \hat{v_t}=\frac{v_t}{1-{\beta_2^t}} vt^=1−β2tvt
η t = l r ⋅ m t ^ / v t ^ = l r ⋅ m t 1 − β 1 t / v t 1 − β 2 t \eta_t = {lr}\cdot{{\hat{m_t}}}/{\sqrt{\hat{v_t}}}=lr{\cdot}{\frac{m_t}{1-{\beta_1^t}}}/{\frac{v_t}{1-{\beta_2^t}}} ηt=lr⋅mt^/vt^=lr⋅1−β1tmt/1−β2tvt
相關文章
- 人工智慧實踐:Tensorflow筆記:程式碼總結(2)人工智慧筆記
- 【北京大學】人工智慧實踐:Tensorflow筆記(一)人工智慧筆記
- [筆記]最佳實踐筆記
- 人工智慧學習筆記(2)人工智慧筆記
- 新手學 GO 筆記Go筆記
- ThreadLoop實踐學習筆記threadOOP筆記
- Latex排版學習筆記(2)——Latex新手入門教程筆記
- 【tensorflow2.0】例項2
- 嵌入式狗的 JAVA 入門筆記·2 程式碼實踐Java筆記
- mysql新手入門隨筆2MySql
- 【docker】Docker入門到實踐 筆記Docker筆記
- 「輕算賬」小程式實踐筆記筆記
- 學習筆記專案實踐(python)筆記Python
- 《Golang學習筆記》error最佳實踐Golang筆記Error
- Cozmo人工智慧機器人SDK使用筆記(X)-總結- |人工智慧基礎(中小學版)實踐平臺|人工智慧機器人筆記
- 社群使用筆記 - 新手搬運工筆記
- 《Kafka入門與實踐》讀書筆記Kafka筆記
- docker 筆記3 dockerfile語法及最佳實踐Docker筆記
- 0.去O過程實踐筆記-前言筆記
- 讀小程式效能優優化實踐-筆記優化筆記
- .NET Core學習筆記(7)——Exception最佳實踐筆記Exception
- Docker筆記(十三):容器日誌採集實踐Docker筆記
- JavaScript設計模式與開發實踐筆記JavaScript設計模式筆記
- 《Python開發簡單爬蟲》實踐筆記Python爬蟲筆記
- 《CMake實踐》筆記二:INSTALL/CMAKE_INSTALL_PREFIX筆記
- docker 筆記2Docker筆記
- Day 2 筆記筆記
- HTML筆記(2)HTML筆記
- sqlserver筆記2SQLServer筆記
- linux筆記2Linux筆記
- pandas+pyechars 實踐筆記:比特幣價格分析筆記比特幣
- pandas+pyecharts 實踐筆記:比特幣價格分析Echarts筆記比特幣
- 產研指南針的量化指標實踐筆記指標筆記
- Cozmo人工智慧機器人SDK使用筆記(2)-顯示部分face人工智慧機器人筆記
- PySimpleGUI 學習筆記(純新手記錄,大神請忽視)GUI筆記
- LightGCN實踐2——GPU記憶體爆炸終結篇GCGPU記憶體
- 【計算機系統設計】實踐筆記(2)資料通路構建:第一類R型指令分析(2)計算機筆記
- 《Hbase原理與實踐》讀書筆記——2.基礎資料結構與演算法筆記資料結構演算法