3.1.2 linear regression
xiaoyao 《動手學深度學習》tensorflow2.1.0實現
3.1 線性迴歸
線性迴歸輸出是一個連續值,因此適用於迴歸問題。迴歸問題在實際中很常見,如預測房屋價格、氣溫、銷售額等連續值的問題。與迴歸問題不同,分類問題中模型的最終輸出是一個離散值。我們所說的圖像分類、垃圾郵件識別、疾病檢測等輸出爲離散值的問題都屬於分類問題的範疇。softmax迴歸則適用於分類問題。
由於線性迴歸和softmax迴歸都是單層神經網絡,它們涉及的概念和技術同樣適用於大多數的深度學習模型。我們首先以線性迴歸爲例,介紹大多數深度學習模型的基本要素和表示方法。
3.1.1 線性迴歸的基本要素
我們以一個簡單的房屋價格預測作爲例子來解釋線性迴歸的基本要素。這個應用的目標是預測一棟房子的售出價格(元)。我們知道這個價格取決於很多因素,如房屋狀況、地段、市場行情等。爲了簡單起見,這裏我們假設價格只取決於房屋狀況的兩個因素,即面積(平方米)和房齡(年)。接下來我們希望探索價格與這兩個因素的具體關係。
3.1.1.1 模型定義
設房屋的面積爲 x 1 x_1 x 1 ,房齡爲 x 2 x_2 x 2 ,售出價格爲 y y y 。我們需要建立基於輸入 x 1 x_1 x 1 和 x 2 x_2 x 2 來計算輸出 y y y 的表達式,也就是模型(model)。顧名思義,線性迴歸假設輸出與各個輸入之間是線性關係:
y ^ = x 1 w 1 + x 2 w 2 + b (式1)
\hat{y} = x_1 w_1 + x_2 w_2 + b\tag{式1}
y ^ = x 1 w 1 + x 2 w 2 + b ( 式 1 )
其中 w 1 w_1 w 1 和 w 2 w_2 w 2 是權重(weight),b b b 是偏差(bias),且均爲標量。它們是線性迴歸模型的參數(parameter)。模型輸出 y ^ \hat{y} y ^ 是線性迴歸對真實價格 y y y 的預測或估計。我們通常允許它們之間有一定誤差。
3.1.1.2 模型訓練
接下來我們需要通過數據來尋找特定的模型參數值,使模型在數據上的誤差儘可能小。這個過程叫作模型訓練(model training)。下面我們介紹模型訓練所涉及的3個要素。
(1) 訓練數據
我們通常收集一系列的真實數據,例如多棟房屋的真實售出價格和它們對應的面積和房齡。我們希望在這個數據上面尋找模型參數來使模型的預測價格與真實價格的誤差最小。在機器學習術語裏,該數據集被稱爲訓練數據集(training data set)或訓練集(training set),一棟房屋被稱爲一個樣本(sample),其真實售出價格叫作標籤(label),用來預測標籤的兩個因素叫作特徵(feature)。特徵用來表徵樣本的特點。
假設我們採集的樣本數爲 n n n ,索引爲 i i i 的樣本的特徵爲 x 1 ( i ) x_1^{(i)} x 1 ( i ) 和 x 2 ( i ) x_2^{(i)} x 2 ( i ) ,標籤爲 y ( i ) y^{(i)} y ( i ) 。對於索引爲 i i i 的房屋,線性迴歸模型的房屋價格預測表達式爲
y ^ ( i ) = x 1 ( i ) w 1 + x 2 ( i ) w 2 + b (式2)
\hat{y}^{(i)} = x_1^{(i)} w_1 + x_2^{(i)} w_2 + b\tag{式2}
y ^ ( i ) = x 1 ( i ) w 1 + x 2 ( i ) w 2 + b ( 式 2 )
(2) 損失函數
在模型訓練中,我們需要衡量價格預測值與真實值之間的誤差。通常我們會選取一個非負數作爲誤差,且數值越小表示誤差越小。一個常用的選擇是平方函數。它在評估索引爲 i i i 的樣本誤差的表達式爲
ℓ ( i ) ( w 1 , w 2 , b ) = 1 2 ( y ^ ( i ) − y ( i ) ) 2 (式3)
\ell^{(i)}(w_1, w_2, b) = \frac{1}{2} \left(\hat{y}^{(i)} - y^{(i)}\right)^2\tag{式3}
ℓ ( i ) ( w 1 , w 2 , b ) = 2 1 ( y ^ ( i ) − y ( i ) ) 2 ( 式 3 )
其中常數 1 2 \frac 1 2 2 1 使對平方項求導後的常數係數爲1,這樣在形式上稍微簡單一些。顯然,誤差越小表示預測價格與真實價格越相近,且當二者相等時誤差爲0。給定訓練數據集,這個誤差只與模型參數相關,因此我們將它記爲以模型參數爲參數的函數。在機器學習裏,將衡量誤差的函數稱爲損失函數(loss function)。這裏使用的平方誤差函數也稱爲平方損失(square loss)。
通常,我們用訓練數據集中所有樣本誤差的平均來衡量模型預測的質量,即
ℓ ( w 1 , w 2 , b ) = 1 n ∑ i = 1 n ℓ ( i ) ( w 1 , w 2 , b ) = 1 n ∑ i = 1 n 1 2 ( x 1 ( i ) w 1 + x 2 ( i ) w 2 + b − y ( i ) ) 2 (式4)
\ell(w_1, w_2, b) =\frac{1}{n} \sum_{i=1}^n \ell^{(i)}(w_1, w_2, b) =\frac{1}{n} \sum_{i=1}^n \frac{1}{2}\left(x_1^{(i)} w_1 + x_2^{(i)} w_2 + b - y^{(i)}\right)^2\tag{式4}
ℓ ( w 1 , w 2 , b ) = n 1 i = 1 ∑ n ℓ ( i ) ( w 1 , w 2 , b ) = n 1 i = 1 ∑ n 2 1 ( x 1 ( i ) w 1 + x 2 ( i ) w 2 + b − y ( i ) ) 2 ( 式 4 )
在模型訓練中,我們希望找出一組模型參數,記爲 w 1 ∗ , w 2 ∗ , b ∗ w_1^*, w_2^*, b^* w 1 ∗ , w 2 ∗ , b ∗ ,來使訓練樣本平均損失最小:
w 1 ∗ , w 2 ∗ , b ∗ = arg min w 1 , w 2 , b ℓ ( w 1 , w 2 , b ) (式5)
w_1^*, w_2^*, b^* = \underset{w_1, w_2, b}{\arg\min} \ell(w_1, w_2, b)\tag{式5}
w 1 ∗ , w 2 ∗ , b ∗ = w 1 , w 2 , b arg min ℓ ( w 1 , w 2 , b ) ( 式 5 )
(3) 優化算法
當模型和損失函數形式較爲簡單時,上面的誤差最小化問題的解可以直接用公式表達出來。這類解叫作解析解(analytical solution)。本節使用的線性迴歸和平方誤差剛好屬於這個範疇。然而,大多數深度學習模型並沒有解析解,只能通過優化算法有限次迭代模型參數來儘可能降低損失函數的值。這類解叫作數值解(numerical solution)。
在求數值解的優化算法中,小批量隨機梯度下降(mini-batch stochastic gradient descent)在深度學習中被廣泛使用。它的算法很簡單:先選取一組模型參數的初始值,如隨機選取;接下來對參數進行多次迭代,使每次迭代都可能降低損失函數的值。在每次迭代中,先隨機均勻採樣一個由固定數目訓練數據樣本所組成的小批量(mini-batch)B \mathcal{B} B ,然後求小批量中數據樣本的平均損失有關模型參數的導數(梯度),最後用此結果與預先設定的一個正數的乘積作爲模型參數在本次迭代的減小量。
在訓練本節討論的線性迴歸模型的過程中,模型的每個參數將作如下迭代:
w 1 ← w 1 − η ∣ B ∣ ∑ i ∈ B ∂ ℓ ( i ) ( w 1 , w 2 , b ) ∂ w 1 = w 1 − η ∣ B ∣ ∑ i ∈ B x 1 ( i ) ( x 1 ( i ) w 1 + x 2 ( i ) w 2 + b − y ( i ) ) , w 2 ← w 2 − η ∣ B ∣ ∑ i ∈ B ∂ ℓ ( i ) ( w 1 , w 2 , b ) ∂ w 2 = w 2 − η ∣ B ∣ ∑ i ∈ B x 2 ( i ) ( x 1 ( i ) w 1 + x 2 ( i ) w 2 + b − y ( i ) ) , b ← b − η ∣ B ∣ ∑ i ∈ B ∂ ℓ ( i ) ( w 1 , w 2 , b ) ∂ b = b − η ∣ B ∣ ∑ i ∈ B ( x 1 ( i ) w 1 + x 2 ( i ) w 2 + b − y ( i ) ) . (式6)
\begin{aligned}
w_1 &\leftarrow w_1 - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \frac{ \partial \ell^{(i)}(w_1, w_2, b) }{\partial w_1} = w_1 - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}}x_1^{(i)} \left(x_1^{(i)} w_1 + x_2^{(i)} w_2 + b - y^{(i)}\right),\\
w_2 &\leftarrow w_2 - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \frac{ \partial \ell^{(i)}(w_1, w_2, b) }{\partial w_2} = w_2 - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}}x_2^{(i)} \left(x_1^{(i)} w_1 + x_2^{(i)} w_2 + b - y^{(i)}\right),\\
b &\leftarrow b - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \frac{ \partial \ell^{(i)}(w_1, w_2, b) }{\partial b} = b - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}}\left(x_1^{(i)} w_1 + x_2^{(i)} w_2 + b - y^{(i)}\right).
\end{aligned}\tag{式6}
w 1 w 2 b ← w 1 − ∣ B ∣ η i ∈ B ∑ ∂ w 1 ∂ ℓ ( i ) ( w 1 , w 2 , b ) = w 1 − ∣ B ∣ η i ∈ B ∑ x 1 ( i ) ( x 1 ( i ) w 1 + x 2 ( i ) w 2 + b − y ( i ) ) , ← w 2 − ∣ B ∣ η i ∈ B ∑ ∂ w 2 ∂ ℓ ( i ) ( w 1 , w 2 , b ) = w 2 − ∣ B ∣ η i ∈ B ∑ x 2 ( i ) ( x 1 ( i ) w 1 + x 2 ( i ) w 2 + b − y ( i ) ) , ← b − ∣ B ∣ η i ∈ B ∑ ∂ b ∂ ℓ ( i ) ( w 1 , w 2 , b ) = b − ∣ B ∣ η i ∈ B ∑ ( x 1 ( i ) w 1 + x 2 ( i ) w 2 + b − y ( i ) ) . ( 式 6 )
在上式中,∣ B ∣ |\mathcal{B}| ∣ B ∣ 代表每個小批量中的樣本個數(批量大小,batch size),η \eta η 稱作學習率(learning rate)並取正數。需要強調的是,這裏的批量大小和學習率的值是人爲設定的,並不是通過模型訓練學出的,因此叫作超參數(hyperparameter)。我們通常所說的“調參”指的正是調節超參數,例如通過反覆試錯來找到超參數合適的值。在少數情況下,超參數也可以通過模型訓練學出。本書對此類情況不做討論。
3.1.1.3 模型預測
模型訓練完成後,我們將模型參數 w 1 , w 2 , b w_1, w_2, b w 1 , w 2 , b 在優化算法停止時的值分別記作 w ^ 1 , w ^ 2 , b ^ \hat{w}_1, \hat{w}_2, \hat{b} w ^ 1 , w ^ 2 , b ^ 。注意,這裏我們得到的並不一定是最小化損失函數的最優解 w 1 ∗ , w 2 ∗ , b ∗ w_1^*, w_2^*, b^* w 1 ∗ , w 2 ∗ , b ∗ ,而是對最優解的一個近似。然後,我們就可以使用學出的線性迴歸模型 x 1 w ^ 1 + x 2 w ^ 2 + b ^ x_1 \hat{w}_1 + x_2 \hat{w}_2 + \hat{b} x 1 w ^ 1 + x 2 w ^ 2 + b ^ 來估算訓練數據集以外任意一棟面積(平方米)爲x 1 x_1 x 1 、房齡(年)爲x 2 x_2 x 2 的房屋的價格了。這裏的估算也叫作模型預測、模型推斷或模型測試。
3.1.2 線性迴歸的表示方法
我們已經闡述了線性迴歸的模型表達式、訓練和預測。下面我們解釋線性迴歸與神經網絡的聯繫,以及線性迴歸的矢量計算表達式。
3.1.2.1 神經網絡圖
在深度學習中,我們可以使用神經網絡圖直觀地表現模型結構。爲了更清晰地展示線性迴歸作爲神經網絡的結構,圖3.1使用神經網絡圖表示本節中介紹的線性迴歸模型。神經網絡圖隱去了模型參數權重和偏差。
在圖3.1所示的神經網絡中,輸入分別爲 x 1 x_1 x 1 和 x 2 x_2 x 2 ,因此輸入層的輸入個數爲2。輸入個數也叫特徵數或特徵向量維度。圖3.1中網絡的輸出爲 o o o ,輸出層的輸出個數爲1。需要注意的是,我們直接將圖3.1中神經網絡的輸出 o o o 作爲線性迴歸的輸出,即 y ^ = o \hat{y} = o y ^ = o 。由於輸入層並不涉及計算,按照慣例,圖3.1所示的神經網絡的層數爲1。所以,線性迴歸是一個單層神經網絡。輸出層中負責計算 o o o 的單元又叫神經元。在線性迴歸中,o o o 的計算依賴於 x 1 x_1 x 1 和 x 2 x_2 x 2 。也就是說,輸出層中的神經元和輸入層中各個輸入完全連接。因此,這裏的輸出層又叫全連接層(fully-connected layer)或稠密層(dense layer)。
代碼部分
import tensorflow as tf
print ( tf. __version__)
2.1.0
from time import time
a = tf. ones( ( 1000 , ) )
b = tf. ones( ( 1000 , ) )
print ( type ( a) , type ( b) )
<class 'tensorflow.python.framework.ops.EagerTensor'> <class 'tensorflow.python.framework.ops.EagerTensor'>
start = time( )
c = tf. Variable( tf. zeros( ( 1000 , ) ) )
for i in range ( 1000 ) :
c[ i] . assign( a[ i] + b[ i] )
time( ) - start
0.2967078685760498
start = time( )
c. assign( a + b)
time( ) - start
0.0009565353393554688
start = time( )
c. assign_add( a+ b)
time( ) - start
0.012198925018310547
這裏顯示出,進行矢量計算將更加省時,所以應該儘可能採用矢量計算
如果我們對訓練數據集裏的3個房屋樣本(索引分別爲1、2和3)逐一預測價格,將得到
y ^ ( 1 ) = x 1 ( 1 ) w 1 + x 2 ( 1 ) w 2 + b , y ^ ( 2 ) = x 1 ( 2 ) w 1 + x 2 ( 2 ) w 2 + b , y ^ ( 3 ) = x 1 ( 3 ) w 1 + x 2 ( 3 ) w 2 + b . (式7)
\begin{aligned}
\hat{y}^{(1)} &= x_1^{(1)} w_1 + x_2^{(1)} w_2 + b,\\
\hat{y}^{(2)} &= x_1^{(2)} w_1 + x_2^{(2)} w_2 + b,\\
\hat{y}^{(3)} &= x_1^{(3)} w_1 + x_2^{(3)} w_2 + b.
\end{aligned}\tag{式7}
y ^ ( 1 ) y ^ ( 2 ) y ^ ( 3 ) = x 1 ( 1 ) w 1 + x 2 ( 1 ) w 2 + b , = x 1 ( 2 ) w 1 + x 2 ( 2 ) w 2 + b , = x 1 ( 3 ) w 1 + x 2 ( 3 ) w 2 + b . ( 式 7 )
現在,我們將上面3個等式轉化成矢量計算。設
y ^ = [ y ^ ( 1 ) y ^ ( 2 ) y ^ ( 3 ) ] , X = [ x 1 ( 1 ) x 2 ( 1 ) x 1 ( 2 ) x 2 ( 2 ) x 1 ( 3 ) x 2 ( 3 ) ] , w = [ w 1 w 2 ] (式8)
\boldsymbol{\hat{y}} =
\begin{bmatrix}
\hat{y}^{(1)} \\
\hat{y}^{(2)} \\
\hat{y}^{(3)}
\end{bmatrix},\quad
\boldsymbol{X} =
\begin{bmatrix}
x_1^{(1)} & x_2^{(1)} \\
x_1^{(2)} & x_2^{(2)} \\
x_1^{(3)} & x_2^{(3)}
\end{bmatrix},\quad
\boldsymbol{w} =
\begin{bmatrix}
w_1 \\
w_2
\end{bmatrix}\tag{式8}
y ^ = ⎣ ⎡ y ^ ( 1 ) y ^ ( 2 ) y ^ ( 3 ) ⎦ ⎤ , X = ⎣ ⎢ ⎡ x 1 ( 1 ) x 1 ( 2 ) x 1 ( 3 ) x 2 ( 1 ) x 2 ( 2 ) x 2 ( 3 ) ⎦ ⎥ ⎤ , w = [ w 1 w 2 ] ( 式 8 )
對3個房屋樣本預測價格的矢量計算表達式爲y ^ = X w + b , \boldsymbol{\hat{y}} = \boldsymbol{X} \boldsymbol{w} + b, y ^ = X w + b , 其中的加法運算使用了廣播機制.
廣義上講,當數據樣本數爲 n n n ,特徵數爲 d d d 時,線性迴歸的矢量計算表達式爲
y ^ = X w + b (式9)
\boldsymbol{\hat{y}} = \boldsymbol{X} \boldsymbol{w} + b\tag{式9}
y ^ = X w + b ( 式 9 )
其中模型輸出 y ^ ∈ R n × 1 \boldsymbol{\hat{y}} \in \mathbb{R}^{n \times 1} y ^ ∈ R n × 1 批量數據樣本特徵 X ∈ R n × d \boldsymbol{X} \in \mathbb{R}^{n \times d} X ∈ R n × d ,權重 w ∈ R d × 1 \boldsymbol{w} \in \mathbb{R}^{d \times 1} w ∈ R d × 1 , 偏差 b ∈ R b \in \mathbb{R} b ∈ R 。相應地,批量數據樣本標籤 y ∈ R n × 1 \boldsymbol{y} \in \mathbb{R}^{n \times 1} y ∈ R n × 1 。設模型參數 θ = [ w 1 , w 2 , b ] ⊤ \boldsymbol{\theta} = [w_1, w_2, b]^\top θ = [ w 1 , w 2 , b ] ⊤ ,我們可以重寫損失函數爲
ℓ ( θ ) = 1 2 n ( y ^ − y ) ⊤ ( y ^ − y ) (式10)
\ell(\boldsymbol{\theta})=\frac{1}{2n}(\boldsymbol{\hat{y}}-\boldsymbol{y})^\top(\boldsymbol{\hat{y}}-\boldsymbol{y})\tag{式10}
ℓ ( θ ) = 2 n 1 ( y ^ − y ) ⊤ ( y ^ − y ) ( 式 1 0 )
小批量隨機梯度下降的迭代步驟將相應地改寫爲
θ ← θ − η ∣ B ∣ ∑ i ∈ B ∇ θ ℓ ( i ) ( θ ) , (式11)
\boldsymbol{\theta} \leftarrow \boldsymbol{\theta} - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \nabla_{\boldsymbol{\theta}} \ell^{(i)}(\boldsymbol{\theta}),\tag{式11}
θ ← θ − ∣ B ∣ η i ∈ B ∑ ∇ θ ℓ ( i ) ( θ ) , ( 式 1 1 )
其中梯度是損失有關3個爲標量的模型參數的偏導數組成的向量:
∇ θ ℓ ( i ) ( θ ) = [ ∂ ℓ ( i ) ( w 1 , w 2 , b ) ∂ w 1 ∂ ℓ ( i ) ( w 1 , w 2 , b ) ∂ w 2 ∂ ℓ ( i ) ( w 1 , w 2 , b ) ∂ b ] = [ x 1 ( i ) ( x 1 ( i ) w 1 + x 2 ( i ) w 2 + b − y ( i ) ) x 2 ( i ) ( x 1 ( i ) w 1 + x 2 ( i ) w 2 + b − y ( i ) ) x 1 ( i ) w 1 + x 2 ( i ) w 2 + b − y ( i ) ] = [ x 1 ( i ) x 2 ( i ) 1 ] ( y ^ ( i ) − y ( i ) ) (式12)
\nabla_{\boldsymbol{\theta}} \ell^{(i)}(\boldsymbol{\theta})=
\begin{bmatrix}
\frac{ \partial \ell^{(i)}(w_1, w_2, b) }{\partial w_1} \\
\frac{ \partial \ell^{(i)}(w_1, w_2, b) }{\partial w_2} \\
\frac{ \partial \ell^{(i)}(w_1, w_2, b) }{\partial b}
\end{bmatrix} =
\begin{bmatrix}
x_1^{(i)} (x_1^{(i)} w_1 + x_2^{(i)} w_2 + b - y^{(i)}) \\
x_2^{(i)} (x_1^{(i)} w_1 + x_2^{(i)} w_2 + b - y^{(i)}) \\
x_1^{(i)} w_1 + x_2^{(i)} w_2 + b - y^{(i)}
\end{bmatrix}=
\begin{bmatrix}
x_1^{(i)} \\
x_2^{(i)} \\
1
\end{bmatrix}
(\hat{y}^{(i)} - y^{(i)})\tag{式12}
∇ θ ℓ ( i ) ( θ ) = ⎣ ⎢ ⎢ ⎡ ∂ w 1 ∂ ℓ ( i ) ( w 1 , w 2 , b ) ∂ w 2 ∂ ℓ ( i ) ( w 1 , w 2 , b ) ∂ b ∂ ℓ ( i ) ( w 1 , w 2 , b ) ⎦ ⎥ ⎥ ⎤ = ⎣ ⎢ ⎡ x 1 ( i ) ( x 1 ( i ) w 1 + x 2 ( i ) w 2 + b − y ( i ) ) x 2 ( i ) ( x 1 ( i ) w 1 + x 2 ( i ) w 2 + b − y ( i ) ) x 1 ( i ) w 1 + x 2 ( i ) w 2 + b − y ( i ) ⎦ ⎥ ⎤ = ⎣ ⎢ ⎡ x 1 ( i ) x 2 ( i ) 1 ⎦ ⎥ ⎤ ( y ^ ( i ) − y ( i ) ) ( 式 1 2 )
小結
和大多數深度學習模型一樣,對於線性迴歸這樣一種單層神經網絡,它的基本要素包括模型、訓練數據、損失函數和優化算法。
既可以用神經網絡圖表示線性迴歸,又可以用矢量計算表示該模型。
應該儘可能採用矢量計算,以提升計算效率。
a = tf. ones( ( 3 , ) )
print ( a)
b = 10
a+ b
tf.Tensor([1. 1. 1.], shape=(3,), dtype=float32)
<tf.Tensor: shape=(3,), dtype=float32, numpy=array([11., 11., 11.], dtype=float32)>