9。9 從資料中學習
神經網路的特徵之一,就是從資料樣本中學習。
也就是說,可以由訓練資料來自動確定網路權值引數的值。
這是非常了不起的,要知道,如果所有工作全部都由手工確定,那工作量就會達到難以承受之重。
那該如何自動確定呢?其抓手是什麼呢?
抓手就是前面提取的損失函式。如果某些網路引數,使得損失函式達到最小值,它們就是我們要找的引數。
我們知道,求某個函式的極值,難免就要用到“導數”等概念。對於某個連續函式
,令其一階導數
,透過求解該微分方程,便可直接獲得極值點。
然而,顯而易見的方案,並不能顯而易見獲得。
一方面,
的顯式解,並不容易求得,當輸入變數很多時或者函式很複雜時,就更不容易求解微分方程。
另一方面,求解微分方程並不是計算機所長。計算機所擅長的是,
憑藉強大的計算能力
,透過插值等方法(如牛頓下山法、弦截法等),
海量嘗試,一步一步的去把函式的極值點“試”出來
。
當然,這個海量嘗試,也不能像無頭的蒼蠅一樣,毫無方向感。怎樣做,才算是有方向感呢?這就要依賴最佳化演算法了。
如果某個問題的解確定存在,而幫助我們快速找到這個解的演算法,我們都可以稱之為“最佳化演算法”。BP演算法、Adam演算法等都輸入最佳化演算法之列,而delta法則是最早使用的最佳化演算法之一。
9。10 delta法則
為了克服多層感知機調參存在的問題,人們設計了一種名為delta(
)法則(delta rule)的啟發式方法,該方法可以讓目標收斂到最佳解的近似值。
delta法則的核心思想在於,
使用梯度下降(gradient descent)的方法找極值。
具體說來,就是在假設空間中搜索可能的權值向量,並以“最佳”的姿態,來擬合訓練集合中的樣本。那麼,何謂最佳擬合呢?當然就是讓前文提到的
讓損失函式達到最小值!
我們知道,求某個函式的極值,難免就要用到“導數”等概念。既然我們把這個系列文章定位為入門層次,那不妨就再講細緻一點。
什麼是導數呢?
所謂導數,就是用來分析函式“變化率”的一種度量。針對函式中的某個特定點x0,該點的導數就是x0點的“瞬間斜率”,也即切線斜率。
見公式(9-1)。
(9-1)
如果這個斜率越大,就表明其上升趨勢越強勁。當這個斜率為0時,就達到了這個函式的“強弩之末”,即達到了極值點。在單變數的實值函式中,梯度可簡單理解為只是導數,或者說對於一個線性函式而言,梯度就是曲線在某點的斜率。
9。11 導數的Python實現
下面我們就用一個簡單Python程式來說明導數的概念。假設目前的函式為:
,然後我們求得
處的導數。程式碼如下所示。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import
numpy
as
np
import
matplotlib。pylab
as
plt
def
numerical_diff
(
func
,
x
):
h
=
1e-4
# 另delta=0。0001
#為避免計算的舍入誤差,使用中心差分法計算導數
return
(
func
(
x
+
h
)
-
func
(
x
-
h
))
/
(
2
*
h
)
def
function_1
(
x
):
return
x
**
2
+
x
#切線函式
def
tangent_line
(
func
,
x
):
k
=
numerical_diff
(
func
,
x
)
(
“x = ”
,
x
,
“時,導數為:”
,
k
)
b
=
func
(
x
)
-
k
*
x
return
lambda
t
:
k
*
t
+
b
#返回一個有終點和起點的固定步長(0。1)的數列
x
=
np
。
arange
(
0。0
,
20。0
,
0。1
)
y
=
function_1
(
x
)
#設定繪圖的x和y標籤
plt
。
xlabel
(
“x”
)
plt
。
ylabel
(
“f(x)”
)
tf
=
tangent_line
(
function_1
,
8
)
y2
=
tf
(
x
)
#繪製曲線
plt
。
plot
(
x
,
y
)
#繪製切線
plt
。
plot
(
x
,
y2
)
plt
。
show
()
執行結果:
x = 8 時,導數為: 16。999999999924853
聰慧如你,上述程式碼壓根不是讓你理解導數這個概念的,而是讓你溫習一下Python是如何玩的(比如說,如何用Python畫圖)。
9。12 多維變數的“區域性導數”
但對於多維變數的函式,梯度概念就不那麼容易理解了,它就要涉及到標量場概念。
在向量微積分中,標量場的梯度,其實是一個向量場(vector field)。假設一個標量函式f的梯度記為:
或
grad f
,這裡表示向量微分運算元。那麼,在一個三維直角座標系,該函式的梯度就可以表示為公式(9-2):
(9-2)
為求得這個梯度值,難免要用到“偏導”的概念。說到“偏導”,這裡順便“輕拍”一下國內的翻譯。“偏導”的英文字意是“partial derivatives(區域性導數)”,書本上常將其翻譯為“偏導”,可能會把讀者的思路引導“偏”了。
那什麼是“區域性導數”呢?對於多維變數函式而言,當求某個變數的導數時,就是把其它變數視為常量,然後整個函式求其導數(相比於全部變數,這裡只求一個變數,即為“區域性”)。之後,這個過程對每個變數都“臨幸”一遍,放在向量場中,就得到了這個函式的梯度了。舉例來說,對於3變數函式
,它的梯度可以這樣求得:
(1)把
y
,
z
視為常量,得
x
的“區域性導數”:
(2) 然後把
x
,
z
視為常量,得
y
的“區域性導數”:
(3) 最後把
x
,
y
視為常量,得
z
的“區域性導數”:
於是,函式
f
的梯度可表示為:
針對某個特定點,如點A(1, 2, 3),帶入對應的值即可得到該點的梯度:
圖9-4 梯度概念的示意圖
對於函式的某個特定點,它的梯度就表示從該點出發,函式值增長最為迅猛的方向(direction of greatest increase of a function)。
對於圖9-4所示的案例,梯度可理解為,站在向量點A(1, 2, 3),如果想讓函式
f
的值增長得最快,那麼它的下一個前進的方向,就是朝著向量點B(8,7,27)方向進發。
本文部分節選自《深度學習之美:AI時代的資料處理與最佳實踐》(張玉宏著,電子工業出版社,2018年7月出版)。更多理論推導及實戰環節,請參閱該書。
(連載待續)