第二周:神经网络基础
- 2.1 二分分类
- 2.2 Logistic Regression
- 2.2 Logistic Regression cost function
- 2.4 Gradient Descent
- 2.7/2.8 Computation Graph 计算图及其导数计算
- 2.9 Logistic Regression Gradient Descent
- 2.10 Logistic regression on m m m examples
- 2.11 向量化
- 2.12 More Vectorization Examples
- 2.13 / 2.14 Vectorizing Logistic Regression
- 2.15 Broadcasting in Python
- 2.16 A note on python / numpy vectors
- 2.17 Explanation of logistic regression cost function
- 测验中要点:
本文是神经网络和深度学习课程的笔记。
2.1 二分分类
- Logistic Regression
- 目的:属于A,还是不属于A
- 记号:
- 输入一个三通道的彩色图片:
n
x
=
3
∗
64
∗
64
n_x=3*64*64
nx=3∗64∗64输入单个样本向量的维度
[ x 1 ⋮ x n x ] \begin{bmatrix} x_{1} \\ \vdots \\ x_{n_x} \end{bmatrix} ⎣⎢⎡x1⋮xnx⎦⎥⎤ - m t r a i n m_{train} mtrain训练样本个数,有时候简记为m。每个样本(向量)为 x i x^i xi。
- m t e s t m_{test} mtest测试集样本个数
- 记 X ∈ R n x × m = [ x 1 … x m t r a i n ] X \in \mathbb{R}^{n_x\times m}= \begin{bmatrix} x^1 & \dots & x^{m_{train}} \end{bmatrix} X∈Rnx×m=[x1…xmtrain]
- 记 Y ∈ R 1 × m t r a i n = [ y 1 … y m t r a i n ] Y \in \mathbb{R}^{1\times m_{train}}=\begin{bmatrix} y^1 & \dots & y^{m_{train}} \end{bmatrix} Y∈R1×mtrain=[y1…ymtrain]
- 输入一个三通道的彩色图片:
n
x
=
3
∗
64
∗
64
n_x=3*64*64
nx=3∗64∗64输入单个样本向量的维度
2.2 Logistic Regression
- 目的:
- 给定x,期望输出 y ^ = P ( y = 1 ∣ x ) , x ∈ R n x \hat{y}=\mathbb{P}(y=1|x),x\in \mathbb{R}^{n_x} y^=P(y=1∣x),x∈Rnx
- 参数: w ∈ R n x , b ∈ R w\in \mathbb{R}^{n_x},b\in \mathbb{R} w∈Rnx,b∈R,这里是把常数项分开,这样方便编写代码。
- 一个简单的想法:
- y ^ = w T x + b \hat{y}=w^Tx+b y^=wTx+b
- 这个不行,因为我们希望 y ^ \hat{y} y^是一个0到1中的概率
- 因此,我们加了一个sigmoid函数,将值域映射到0到1中。
- y ^ = σ ( w T x + b ) \hat{y}=\sigma(w^Tx+b) y^=σ(wTx+b)其中 σ ( z ) = 1 1 + e − z \sigma(z)=\frac{1}{1+e^{-z}} σ(z)=1+e−z1
2.2 Logistic Regression cost function
- 目的:
- m i n ( y ^ , y ) min(\hat{y},y) min(y^,y)
- y ^ ( i ) = σ ( w T x ( i ) + b ) \hat{y}^{(i)}=\sigma(w^Tx^{(i)}+b) y^(i)=σ(wTx(i)+b)其中 σ ( z ( i ) ) = 1 1 + e − z ( i ) \sigma(z^{(i)})=\frac{1}{1+e^{-z^{(i)}}} σ(z(i))=1+e−z(i)1
- i表示第i个样本
损失函数(Loss function): L
- 对于逻辑回归,为了将最终的问题变成一个凸的问题,以方便进行梯度下降,我们不再使用传统的MSE损失,而选择交叉熵损失函数:⚠️ 损失函数是对于一个样本而言的。
L ( y ^ , y ) = − ( y × l o g ( y ^ ) + ( 1 − y ) × l o g ( 1 − y ^ ) ) L(\hat{y},y)=-(y\times log(\hat{y})+(1-y)\times log(1-\hat{y})) L(y^,y)=−(y×log(y^)+(1−y)×log(1−y^))- 一个简单的分析: (为什么最小化L可以实现 m i n ( y ^ , y ) min(\hat{y},y) min(y^,y))
- y=1: L ( y ^ , y ) = − l o g ( y ^ ) L(\hat{y},y)=-log(\hat{y}) L(y^,y)=−log(y^),我们希望损失函数越小越好,所以 y ^ \hat{y} y^越大越好。鉴于sigmoid函数的值域为[0,1] 。所以 y ^ \hat{y} y^为1。
- y=0: L ( y ^ , y ) = − l o g ( 1 − y ^ ) L(\hat{y},y)=-log(1-\hat{y}) L(y^,y)=−log(1−y^),我们希望损失函数越小越好,所以 y ^ \hat{y} y^越小越好。鉴于sigmoid函数的值域为[0,1] 。所以 y ^ \hat{y} y^为0。
成本函数(Cost function): J
J
(
w
,
b
)
=
1
m
t
r
a
i
n
∑
i
=
1
m
t
r
a
i
n
L
(
y
^
(
i
)
,
y
(
i
)
)
=
−
1
m
t
r
a
i
n
∑
i
=
1
m
t
r
a
i
n
[
y
(
i
)
l
o
g
(
y
^
(
i
)
)
+
(
1
−
y
(
i
)
)
l
o
g
(
1
−
y
^
(
i
)
)
]
J(w,b)=\frac{1}{m_{train}}\sum_{i=1}^{m_{train}} L(\hat{y}^{(i)},y^{(i)})=-\frac{1}{m_{train}}\sum_{i=1}^{m_{train}}[y^{(i)}log(\hat{y}^{(i)})+(1-y^{(i)})log(1-\hat{y}^{(i)})]
J(w,b)=mtrain1i=1∑mtrainL(y^(i),y(i))=−mtrain1i=1∑mtrain[y(i)log(y^(i))+(1−y(i))log(1−y^(i))]
它是作用在整个数据集上的,我们的目的是最小化J。
2.4 Gradient Descent
- Recap
- J ( w , b ) = − 1 m ∑ i = 1 m [ y ( i ) l o g ( y ^ ( i ) ) + ( 1 − y ( i ) ) l o g ( 1 − y ^ ( i ) ) ] J(w,b)=-\frac{1}{m}\sum_{i=1}^{m}[y^{(i)}log(\hat{y}^{(i)})+(1-y^{(i)})log(1-\hat{y}^{(i)})] J(w,b)=−m1∑i=1m[y(i)log(y^(i))+(1−y(i))log(1−y^(i))]
- y ^ = σ ( w T x + b ) , σ ( z ) = 1 1 + e − z \hat{y}=\sigma(w^Tx+b),\sigma(z)=\frac{1}{1+e^{-z}} y^=σ(wTx+b),σ(z)=1+e−z1
- 因为J是Convex,所以无论初始化在哪都可以找到最小值。
- 参数更新:
- w = w − α × d w w = w-\alpha \times dw w=w−α×dw其中 d w = ∂ J ( w , b ) ∂ w dw = \frac{\partial J(w,b)}{\partial w} dw=∂w∂J(w,b)
- b = b − α × d b b = b-\alpha \times db b=b−α×db其中 d b = ∂ J ( w , b ) ∂ b db = \frac{\partial J(w,b)}{\partial b} db=∂b∂J(w,b)
2.7/2.8 Computation Graph 计算图及其导数计算
- 例子: J ( a , b , c ) = 3 × ( a + b c ) J(a,b,c) = 3\times(a+bc) J(a,b,c)=3×(a+bc)
- d J d v = 3 \frac{dJ}{dv}=3 dvdJ=3
- d J d a = 3 \frac{dJ}{da}=3 dadJ=3
- 感觉是⚠️ ⚠️ 上 一 层 梯 度 × ∂ 上 一 层 变 量 ∂ 当 前 层 变 量 上一层梯度 \times \frac{\partial 上一层变量}{\partial 当前层变量} 上一层梯度×∂当前层变量∂上一层变量
-
d
F
i
n
a
l
O
u
t
p
u
t
V
a
r
d
v
a
r
\frac{d FinalOutputVar}{d var}
dvardFinalOutputVar在程序里,我们用"dvar"表示
2.9 Logistic Regression Gradient Descent
- Recap:
z = w T x + b z = w^Tx+b z=wTx+b
y ^ = a = σ ( z ) \hat{y}=a=\sigma(z) y^=a=σ(z)
L ( a , y ) = − ( y l o g ( a ) + ( 1 − y ) l o g ( 1 − a ) ) L(a,y)=-(ylog(a)+(1-y)log(1-a)) L(a,y)=−(ylog(a)+(1−y)log(1−a))
对于一个参数的更新,看Loss Function L L L,其实有上标(i)。
2.10 Logistic regression on m m m examples
这里我们给出一种用for循环的,比较低效的方法。
对于m个样本权重的更新,我们需要考虑Cost Function J J J。
-
Recap:
J ( w , b ) = 1 m ∑ i = 1 m L ( a ( i ) , y ( i ) ) J(w,b) = \frac{1}{m} \sum_{i=1}^{m}L(a^{(i)},y^{(i)}) J(w,b)=m1∑i=1mL(a(i),y(i)),其中 a = y ^ a=\hat{y} a=y^ -
依旧使用梯度下降:
∂ J ( w , b ) ∂ w 1 = 1 m ∑ i = 1 m ∂ L ( a ( i ) , y ( i ) ) ∂ w 1 ( i ) \frac{\partial J(\bold{w},b)}{\partial w_1}=\frac{1}{m} \sum_{i=1}^{m}\frac{\partial L(a^{(i)},y^{(i)})}{\partial w_1^{(i)}} ∂w1∂J(w,b)=m1∑i=1m∂w1(i)∂L(a(i),y(i)),注意到求和里面的每一项就是我们前面的 d w 1 = ( y ^ ( i ) − y ( i ) ) × x 1 ( i ) dw1=(\hat{y}^{(i)}-y^{(i)})\times x_1^{(i)} dw1=(y^(i)−y(i))×x1(i),所以可以用上面的公式依次求出来。 -
⚠️具体的算法:
-
Rq:
- 这里成本比较麻烦,因为如果我们有n个特征,需要手动输入
d
w
1
,
.
.
.
,
d
w
n
dw_1,...,dw_n
dw1,...,dwn。
Sol:向量化计算,用来摆脱for循环。
2.11 向量化
我们可以证明,如果使用向量乘法,要比普通的用for循环的速度更加快。
import numpy as np
import time
a = np.random.rand(10000000)
b = np.random.rand(10000000)
t0 = time.time()
c = np.dot(a,b);
t1 = time.time()
print(c)
print(f"Vectorization Version:{1000*(t1-t0)} ms")
t0 = time.time()
c=0
for i in range(len(a)):
c+=a[i]*b[i]
t1 = time.time()
print(c)
print(f"For Loop Version:{1000*(t1-t0)} ms")
输出:
2499542.3991724537
Vectorization Version:9.550094604492188 ms
2499542.3991726325
For Loop Version:8469.129085540771 ms
- jupyter notebook上只用CPU
- GPU和CPU都有并行化指令(parallelization instructions),SIMD(Single Instruction Multiple Data,单指令流多数据流)。
2.12 More Vectorization Examples
- u = A v \bold{u}=\bold{A}\bold{v} u=Av
np.exp()
,np.abs()
,np.maximum()
,v**2
【对于逐个元素计算】- 想法:numpy中的函数都有优化,能用numpy中的函数就不要用for loop。
对于Logistic Regression的初步Vectorization,见ipad,可以直接改上面那幅图。
2.13 / 2.14 Vectorizing Logistic Regression
正向传播向量化
- Recap:
z ( 1 ) = w T x ( 1 ) + b , z ( 2 ) = w T x ( 2 ) + b , z ( 3 ) = w T x ( 3 ) + b z^{(1)}=w^Tx^{(1)}+b,z^{(2)}=w^Tx^{(2)}+b,z^{(3)}=w^Tx^{(3)}+b z(1)=wTx(1)+b,z(2)=wTx(2)+b,z(3)=wTx(3)+b
a ( 1 ) = σ ( z ( 1 ) ) , a ( 2 ) = σ ( z ( 2 ) ) , a ( 3 ) = σ ( z ( 3 ) ) a^{(1)}=\sigma(z^{(1)}),a^{(2)}=\sigma(z^{(2)}),a^{(3)}=\sigma(z^{(3)}) a(1)=σ(z(1)),a(2)=σ(z(2)),a(3)=σ(z(3)) - 向量化:
- 引入 X = [ x ( 1 ) , … , x ( m ) ] ∈ R n x × m \bold{X}=[x^{(1)},\dots,x^{(m)}] \in\mathbb{R}^{n_x\times m} X=[x(1),…,x(m)]∈Rnx×m其中有m个样本,每个样本有 n x n_x nx个特征。
- w ∈ R n x × 1 w\in \mathbb{R}^{n_x\times 1} w∈Rnx×1
- Z = [ z ( 1 ) , … , z ( m ) ] \bold{Z}=[z^{(1)},\dots,z^{(m)}] Z=[z(1),…,z(m)], Z = w T X + b \bold{Z}=w^T\bold{X}+b Z=wTX+b
- A = [ a ( 1 ) , … , a ( m ) ] = σ ( Z ) \bold{A}=[a^{(1)},\dots,a^{(m)}]=\sigma(\bold{Z}) A=[a(1),…,a(m)]=σ(Z)
- 具体实现:(利用了python里面的broadcasting)
z = np.dot(w.T,x)+b // Brodcasting,因为b是一个实数
反向传播向量化
- Recap:
- d z ( 1 ) = a ( 1 ) − y ( 1 ) , … , d z ( m ) = a ( m ) − y ( m ) dz^{(1)}=a^{(1)}-y^{(1)},\dots,dz^{(m)}=a^{(m)}-y^{(m)} dz(1)=a(1)−y(1),…,dz(m)=a(m)−y(m)
-
d
w
∈
R
n
x
×
1
dw \in \mathbb{R}^{n_x\times1}
dw∈Rnx×1:
- d w + = x ( 1 ) d z ( 1 ) , . . . , d w + = x ( m ) d z ( m ) dw+=x^{(1)}dz^{(1)},...,dw+=x^{(m)}dz^{(m)} dw+=x(1)dz(1),...,dw+=x(m)dz(m)
- d w / = m dw/=m dw/=m
-
d
b
db
db:
- d b + = d z ( 1 ) , . . . , d b + = d z ( m ) db+=dz^{(1)},...,db+=dz^{(m)} db+=dz(1),...,db+=dz(m)
- d b / = m db/=m db/=m
- 向量化:
- 在正向传播中,我们已经计算了 A = [ a ( 1 ) , … , a ( m ) ] = σ ( Z ) \bold{A}=[a^{(1)},\dots,a^{(m)}]=\sigma(\bold{Z}) A=[a(1),…,a(m)]=σ(Z)
- 我们又已知 Y = [ y ( 1 ) , . . . , y ( m ) ] \bold{Y}=[y^{(1)},...,y^{(m)}] Y=[y(1),...,y(m)]是m个样本对应的目的的标签
- 所以,通过引入⚠️ d z = [ d z ( 1 ) , … , d z ( m ) ] = A − Y ∈ R m × 1 dz=[dz^{(1)},\dots,dz^{(m)}]=\bold{A}-\bold{Y}\in \mathbb{R}^{m\times 1} dz=[dz(1),…,dz(m)]=A−Y∈Rm×1
- 因此 ⚠️ d b = n p . s u m ( d z ) / m db=np.sum(dz)/m db=np.sum(dz)/m
- ⚠️ d w = 1 m X d z T dw=\frac{1}{m}\bold{X}dz^T dw=m1XdzT
- d w = 1 m [ x ( 1 ) … x ( m ) ] [ d z ( 1 ) ⋮ d z ( m ) ] = 1 m [ x ( 1 ) d z ( 1 ) + ⋯ + x ( m ) d z ( m ) ] ∈ R n x × 1 dw=\frac{1}{m} \begin{bmatrix} x^{(1)} & \dots & x^{(m)} \end{bmatrix} \begin{bmatrix} dz^{(1)} \\ \vdots \\ dz^{(m)} \end{bmatrix}= \frac{1}{m} [x^{(1)}dz^{(1)}+\dots+x^{(m)}dz^{(m)}] \in \mathbb{R}^{n_x\times 1} dw=m1[x(1)…x(m)]⎣⎢⎡dz(1)⋮dz(m)⎦⎥⎤=m1[x(1)dz(1)+⋯+x(m)dz(m)]∈Rnx×1
具体实现:
- 对于n次梯度下降还是得外部加一个循环。
#参数
eta=0.1 #学习率
# 对于np.array可以直接运行的sigmoid函数
def sigmoid(t):
return 1/1+np.exp(-t)
#对于m个样本
Z = np.dot(w.T,X)+b
A = sigmoid(Z)
dz = A-Y
dw = np.dot(X,dz.T)/m
db = np.sum(dz)/m
w = w - dw*eta
b = b - db*eta
2.15 Broadcasting in Python
- 例子:
tmp1 =
[[1 2 3]
[4 5 6]]
tmp2 =
[[100 200 300]]
tmp1 + tmp2 =
[[101 202 303]
[104 205 306]]
tmp1 =
[[1 2 3]
[4 5 6]]
tmp2 =
[[100]
[200]]
tmp1 + tmp2 =
[[101 102 103]
[204 205 206]]
- 规则:
(m,n) + (1,n): 水平复制m次 -> 得到(m,n)
(m,n) + (m,1): 竖直复制n次 -> 得到(m,n)
2.16 A note on python / numpy vectors
- 不要用
(5,)
矩阵,因为它们在做外积的时候有可能会得到奇怪的结果 - 解决方案:
.reshape()
assert(a.shape==(5,1))
: 运行速度比较快,如果shape不对会报错AssertionError
。
- 例子:
a = np.random.randn(5)
print(a)
# (5,)是秩为1的矩阵,它既不是行向量,也不是列向量
print(a.shape)
assert(a.shape==(5,1)) #这里会报错
print(a.T) #这里只有一个括号
print(np.dot(a,a.T)) #是一个数字!!
# 解决方案 (或者reshape)
a = np.random.randn(5,1)
print(a.shape)
print(a.T) #这里有2个括号
print(np.dot(a,a.T)) #不是一个数字!!
2.17 Explanation of logistic regression cost function
Loss Function的由来
实际上我们有一定取巧的成分,因为是二分类问题,所以我们令两个类别对应的值为0和1。
-如果 y=1:
p
(
y
∣
x
)
=
y
^
p(y|x) = \hat{y}
p(y∣x)=y^
-如果 y=0:
p
(
y
∣
x
)
=
1
−
y
^
p(y|x) = 1 - \hat{y}
p(y∣x)=1−y^
换句话说我们估计的参数就是
y
^
\hat{y}
y^。如果在指定样本下,我们计算出
y
^
=
0.75
\hat{y}=0.75
y^=0.75,则y=1的概率越高。
- 因此,在样本x,预计标签y的前提下, p ( y ∣ x ) = y ^ y × ( 1 − y ^ ) ( 1 − y ) p(y|x)=\hat{y}^y\times (1-\hat{y})^{(1-y)} p(y∣x)=y^y×(1−y^)(1−y)即当y=1,预测成功概率为 p ( y = 1 ∣ x ) = y ^ p(y=1|x)=\hat{y} p(y=1∣x)=y^。所以上式给出了预测正确的概率。我们希望它越大越好。
- 为此,我们考虑 L ( y ^ , y ) = − l o g ( p ( y ∣ x ) ) = − ( y l o g ( y ^ ) + ( 1 − y ) l o g ( 1 − y ^ ) ) L(\hat{y},y)=-log(p(y | x))=-(ylog(\hat{y})+(1-y)log(1-\hat{y})) L(y^,y)=−log(p(y∣x))=−(ylog(y^)+(1−y)log(1−y^))也就是我们常见的交叉熵损失函数。
Cost Function的由来
如果考虑m个样本,则m个样本都预测正确的概率
P
=
Π
i
=
1
m
p
(
y
(
i
)
∣
x
(
i
)
)
\mathbb{P}=\Pi_{i=1}^m p(y^{(i)}|x^{(i)})
P=Πi=1mp(y(i)∣x(i))
同样,引入对数似然之后,我们得到了Cost Function
J
(
w
,
b
)
=
1
m
∑
i
=
1
m
L
(
y
^
(
i
)
,
y
(
i
)
)
J(w,b)=\frac{1}{m}\sum_{i=1}^mL(\hat{y}^{(i)},y^{(i)})
J(w,b)=m1i=1∑mL(y^(i),y(i))
正如我们希望损失函数越小越好,我们的目的是最小化Cost Function。
测验中要点:
- 区别
np.dot
和*
。
a = np.random.randn(12288, 150) # a.shape = (12288, 150)
b = np.random.randn(150, 45) # b.shape = (150, 45)
c = np.dot(a, b)
d = a*b #会报错