Logistic Regression as a Neural Network

Binary Classification

一開始,我們想將一張 64x64 的圖片餵進 nn 中,來辨識是否是貓

1 代表是,0 代表不是

怎麼餵呢,我們將圖片中 RGB 三種 channel 的各 64x64 個 pixel 存到一個非常長的向量 x

共有 64×64×3=1228864 \times 64 \times 3 = 12288 個 features

x=[255231255134255134]x = \begin{bmatrix} 255\\231\\\vdots\\255\\134\\\vdots\\255\\134\\\vdots \end{bmatrix}

我們會使用 nxn_x 來表達 feature x 的維度,所以 n=nx=12288n = n_x = 12288

Notation

我們的 training sets 為 (x,y)(x, y) 分別表示為

xRnx,y{0,1}x \in \mathbb{R}^{n_x}, y \in \begin{Bmatrix}0,1\end{Bmatrix}

共有 m 個 training sets

{(x(1),y(1)),(x(2),y(2)),,(x(m),y(m))}\begin{Bmatrix}(x^{(1)}, y^{(1)}), (x^{(2)}, y^{(2)}),\cdots, (x^{(m)}, y^{(m)})\end{Bmatrix}

並且我們會壓縮所有的 training sets 和 y 成為一個大矩陣

這邊跟 machine learning 學的有點不一樣

XX 矩陣中

  • 每個 columns i 為不同個 training set x(i)x^{(i)}

  • 每個 rows j 表示所有 xx 的第 j 個 feature

yy 矩陣中

  • 每個 columns i 為不同個 result label y(i)y^{(i)}

Logistic Regression

定義好 xxy^\hat{y}

Given xRnx, want y^=P(y=1x),0y^1\text{Given } x \in \mathbb{R}^{n_x},\text{ want } \hat{y} = P(y=1\mid x), 0 \le \hat{y} \le 1

以及 parameter wRnxw \in \mathbb{R}^{n_x}bRb \in \mathbb{R}

這個 ww 其實就是之前的 θ\theta 是一個 vector

bb 就是 bias 的 θ0\theta_0 是一個實數

然後我們要求 output y^\hat{y} 就是之前的 hθ(x)h_\theta(x)

其中的 σ\sigma 就是之前的 sigmoid gg function

y^=σ(wTx+b)\hat{y} = \sigma(w^Tx + b)

Loss Function

我們會定義一個 Loss function 來當作 single training set 的誤差

L(y^,y)=(ylogy^+(1y)log(1y^))\mathcal{L}(\hat{y}, y) = -(y\log \hat{y} + (1-y)\log (1-\hat{y}))

以下是一個 intuition 為什麼這個 loss function 可以這樣定義

If y=1:L(y^,y)=logy^If y=0:L(y^,y)=log(1y^)\begin{aligned} &\text{If } y = 1 : && \mathcal{L}(\hat{y}, y) = -\log \hat{y} \\ &\text{If } y = 0 : && \mathcal{L}(\hat{y}, y) = -\log(1 - \hat{y}) \end{aligned}

就是說當 y=1y = 1 時,我的 y^\hat{y} 也要越大越好

我的 y^\hat{y} 越大,代表越接近 yy,我的 loss 就越小,所以 logy^0-\log \hat{y} \approx 0

y=0y = 0y^\hat{y} 要越小越好

所以 log(1y^)-\log(1 - \hat{y}) 就會接近 0

Cost Function

於是我們可以將作用在每一筆 training sets 的 loss function 集合形成 cost function J(w,b)J(w,b)

cost function is the average of the loss functions of the entire training set

J(w,b)=1mi=1mL(y^(i),y(i))=1mi=1m[y(i)logy^(i)+(1y(i))log(1y^(i))]\begin{aligned} J(w,b) &= \frac{1}{m}\sum_{i=1}^m\mathcal{L}(\hat{y}^{(i)}, y^{(i)}) \\ &= -\frac{1}{m}\sum_{i=1}^{m}\begin{bmatrix}y^{(i)}\log\hat{y}^{(i)} + (1- y^{(i)}) \log(1-\hat{y}^{(i)})\end{bmatrix} \end{aligned}

裡面的 superscript i 代表第 i 個 training set

Gradient Descent

這邊的 gradient descent 和 machine learning 時學的大同小異

只是現在我們連 b 也要一起進行更新

Repeat :w:=wαJ(w,b)wb:=bαJ(w,b)b\begin{aligned} &\text{Repeat :} && \\ &&w := w - \alpha \frac{\partial J(w, b)}{\partial w}\\ &&b := b - \alpha \frac{\partial J(w, b)}{\partial b}\\ \end{aligned}

Derivatives intuition

這邊講一下 gradient descent 需要用到的微分技巧

其實就只是要求出 x 在對應的 cost function 當下的 slope 而已

slope 的算法就是 heightwidth\frac{\text{height}}{\text{width}}

所以一個 f(a)=3af(a) = 3a 的 linear function 中

做任何的移動都可以算出 slope = 3

a=2f(a)=6a=2.001f(a)=6.003Slope of f(a) at a=2 is 0.0030.001=3=f(a)a\begin{aligned} &a = 2 && f(a) = 6\\ &a = 2.001 && f(a) = 6.003\\ &\text{Slope of } f(a) \text{ at } a = 2 \text{ is } \frac{0.003}{0.001} = 3 = \frac{\partial f(a)}{\partial a} \end{aligned}

Changing Derivatives

在不同的 function 上可以有不斷變動的 slope

例如在 f(a)=a2f(a) = a^2 的圖形中

當 a = 2 時

a=2f(a)4a=2.001f(a)4.004Slope df(a)da=4 when a=2\begin{aligned} &a = 2 && f(a) \approx 4\\ &a = 2.001 && f(a) \approx 4.004\\ &\text{Slope } \frac{df(a)}{da} = 4 \text{ when } a = 2 \end{aligned}

當 a = 5 時

a=5f(a)25a=5.001f(a)25.010Slope df(a)da=10 when a=5\begin{aligned} &a = 5 && f(a) \approx 25\\ &a = 5.001 && f(a) \approx 25.010\\ &\text{Slope } \frac{df(a)}{da} = 10 \text{ when } a = 5 \end{aligned}

可以看到不同地方的三角形所產生的斜率都不同

這其實就是一次微分的意義

常見的有 :

f(a)=a2df(a)da=2af(a)=a3df(a)da=3a2f(a)=ln(a)df(a)da=1a\begin{aligned} &f(a) = a^2 && \frac{d f(a)}{da} = 2a\\ &f(a) = a^3 && \frac{d f(a)}{da} = 3a^2\\ &f(a) = \ln(a) && \frac{d f(a)}{da} = \frac{1}{a}\\ \end{aligned}

Computation Graph

在講解 backpropogation 前,我們用一個簡單方法來解釋一下流程

假設我們想要最小化 J(a,b,c)=3(a+bc)J(a,b,c) = 3(a+bc)

這個函式需要用到三個計算

u=bcv=a+uJ=3v\begin{aligned} u &= bc\\ v &= a+u\\ J &= 3v \end{aligned}

可以畫成像這樣的 computation graph

而 backpropogation 就像是由右往左取每一個數對 J 的導數一樣

求完就可以對每個數做 gradient descent

為什麼要由右往左取呢,是因為需要用到 chain rule 的關係

以下會將 dJdvar\frac{dJ}{dvar} 標示為 dvardvar

其中 var 是任何一個變數

例如 dJda=da\frac{dJ}{da} = da, dJdb=db\frac{dJ}{db} = db

這是 python 在定義這些變數時的常見寫法

現在我們就可以往前求得 dv=3dv = 3

因為當 v 進行微調的時候,J 就會改變三倍

v=1J=3v=1.001J=3.003Slope =0.0030.001=3\begin{aligned} &v = 1 && J = 3\\ &v = 1.001 && J = 3.003 \\ &\text{Slope } = \frac{0.003}{0.001} = 3 \end{aligned}

再來我們再往前求得 da=3da = 3

因為當 a 進行微調時,J 一樣也改變三倍

但我們要從 a 改變 v 而 v 改變 J 這樣算

dJda=dJdvdvda=3dvda\frac{dJ}{da} = \frac{dJ}{dv} \frac{dv}{da} = 3 \cdot \frac{dv}{da}

我們已經知道 dJdv\frac{dJ}{dv}

基於這點,我們再找出 a 進行微調時 v 會維持一倍

a=5v=11a=5.001J=11.001Slope =0.0010.001=1\begin{aligned} &a = 5 && v = 11\\ &a = 5.001 && J = 11.001 \\ &\text{Slope } = \frac{0.001}{0.001} = 1 \end{aligned}

所以 da=dJda=3dvda=31=3da = \frac{dJ}{da} = 3 \cdot \frac{dv}{da} = 3 \cdot 1 = 3

我們用這個 chain rule 方法計算出 u 然後再計算出 b, c

就可以得到所有數字對 J 的 slope 是多少

Logisitic Regression Gradient Descent as NN

我們將 logistic regression 計算 cost function 轉換成 computation graph

  1. 計算 a 的導數為 da=dL(a,y)da=ya+1y1ada = \frac{d\mathcal{L}(a, y)}{da} = -\frac{y}{a} + \frac{1-y}{1-a}

  2. 計算 z 的導數為 dz=dL(a,y)dz=dLdadadz=aydz = \frac{d\mathcal{L}(a, y)}{dz} = \frac{d\mathcal{L}}{da} \cdot \frac{da}{dz}= a - y

    • 其中已知 dLda=ya+1y1a\frac{d\mathcal{L}}{da} = -\frac{y}{a} + \frac{1-y}{1-a}

    • 而新的 dadz=a(1a)\frac{da}{dz} = a(1-a)

  3. 接著就可以算出 w1,w2,bw_1, w_2, bJJ 的導數

    • dw1=dLdw1=x1dzdw_1 = \frac{d\mathcal{L}}{dw_1} = x_1 \cdot dz

    • dw2=dLdw2=x2dzdw_2 = \frac{d\mathcal{L}}{dw_2} = x_2 \cdot dz

    • db=dLdb=dzdb = \frac{d\mathcal{L}}{db} = dz

  4. 然後對這三個數做 gradient descent

    • w1:=w1αdw1w_1 := w_1 - \alpha dw_1

    • w2:=w2αdw2w_2 := w_2 - \alpha dw_2

    • b:=bαdbb := b - \alpha db

Gradient Decsent on m Examples

接著我們把上面所有東西統整一起,對 m 筆 training sets 做一次 gradient descent

pseudo code 如下 :

J = dw1 = dw2 = db = 0

For i = 1 to m:
    % 首先是 forward propogation
    z(i) = w'x(i) + b  % 每個 training set 的 z
    a(i) = sigmoid(z(i))  % 每個 training set 的 a
    J += -[y(i) * log(a(i)) + (1 - y(i)) * log(1 - a(i))]  % 加總所有 training sets 的 cost

    % 接著是 backward propogation
    dz(i) = a(i) - y(i)  % 每個 training set 的 dz

    % feature 很多時,這裡會是一個 loop
    dw1 += x1(i) * dz(i)  % 每個 training set 的 dw1 加到一個 dw1 總合去
    dw2 += x2(i) * dz(i)  % 每個 training set 的 dw2 加到一個 dw2 總合去
    db  += dz(i)  % 每個 training set 的 db 加到一個 db 總合去

% 結束迴圈後對以下幾個東西,都求平均數
J /= m
dw1 /= m
dw2 /= m
db /= m

這個做法可能會用到兩個迴圈,一個是對 m 筆資料,一個是對 n 個 input features (dw1, dw2, ..., dwn)

所以我們需要學習 vectorization 的精神來解決問題

Last updated