1.2.2 第一位代表第一门课,第二位代表第几周,第三位代表第几次视频。编号和视频顺序对应,有些章节视频内容较少进行了省略。对内容进行简单的总结,而不是全面的记录视频的每一个细节,详细可见[1]。
1.神经网络和深度学习
1.2 Basics of Neural Network programming
1.2.1 Binary classification
符号定义 :
-
x x x:表示一个 n x n_x nx维数据,维度为 ( n x , 1 ) (n_x,1) (nx,1), n x n_x nx为特征数;
-
y y y:表示输出结果,取值为 ( 0 , 1 ) (0,1) (0,1);
-
( x ( i ) , y ( i ) ) (x^{(i)},y^{(i)}) (x(i),y(i)):表示第 i i i组数据,可能是训练数据,也可能是测试数据,此处默认为训练数据;
-
X = [ x ( 1 ) , x ( 2 ) , . . . , x ( m ) ] X=[x^{(1)},x^{(2)},...,x^{(m)}] X=[x(1),x(2),...,x(m)]:表示所有的训练数据集的输入值,放在一个 n x × m n_x×m nx×m的矩阵中,其中 m m m表示样本数目;
-
Y = [ y ( 1 ) , y ( 2 ) , . . . , y ( m ) ] Y=[y^{(1)},y^{(2)},...,y^{(m)}] Y=[y(1),y(2),...,y(m)]:对应表示所有训练数据集的输出值,维度为 1 × m 1×m 1×m
1.2.2 Logistic regression
- 算法用于二分类
- 回归公式: y ^ = σ ( w T x + b ) \hat{y}=\sigma({{w}^{T}}x+b) y^=σ(wTx+b)
- 激活函数simoid: σ ( z ) = 1 1 + e − z \sigma \left( z \right)=\frac{1}{1+{{e}^{-z}}} σ(z)=1+e−z1
- 参数: w w w 权重; b b b 偏置
- 二分类 y y y必须是0或1;
1.2.3 Logistic regression cost function
为什么需要代价函数:
为了训练得到
w
,
b
w,b
w,b
代价函数:
- RMSE: L ( y ^ , y ) = ( y − y ′ ) 2 2 L\left( \hat{y},y \right) = \frac{(y-y')^2}{2} L(y^,y)=2(y−y′)2
- logloss: L ( y ^ , y ) = − y log ( y ^ ) − ( 1 − y ) log ( 1 − y ^ ) L\left( \hat{y},y \right)=-y\log(\hat{y})-(1-y)\log (1-\hat{y}) L(y^,y)=−ylog(y^)−(1−y)log(1−y^)
为什么选择logloss:
-
当 y = 1 y=1 y=1 ==> L = − log ( y ^ ) L=-\log (\hat{y}) L=−log(y^),损失函数 L L L尽可能得小 ==> y ^ \hat{y} y^就要尽可能大 ==> y ^ \hat{y} y^无限接近于1
-
当 y = 0 y=0 y=0 ==> L = − log ( 1 − y ^ ) L=-\log (1-\hat{y}) L=−log(1−y^),损失函数 L L L尽可能得小 ==> y ^ \hat{y} y^就要尽可能小 ==> y ^ \hat{y} y^会无限接近于0
m个样本的损失函数: *
J
(
w
,
b
)
=
1
m
∑
i
=
1
m
L
(
y
^
(
i
)
,
y
(
i
)
)
=
1
m
∑
i
=
1
m
(
−
y
(
i
)
log
y
^
(
i
)
−
(
1
−
y
(
i
)
)
log
(
1
−
y
^
(
i
)
)
)
J\left( w,b \right) =\frac{1}{m}\sum\limits_{i=1}^{m}{L\left( {{{\hat{y}}}^{(i)}},{{y}^{(i)}} \right)}= \frac{1}{m}\sum\limits_{i=1}^{m}{\left( -{{y}^{(i)}}\log {{{\hat{y}}}^{(i)}}-(1-{{y}^{(i)}})\log (1-{{{\hat{y}}}^{(i)}}) \right)}
J(w,b)=m1i=1∑mL(y^(i),y(i))=m1i=1∑m(−y(i)logy^(i)−(1−y(i))log(1−y^(i)))
1.2.4 Gradient Descent
1.梯度下降法的形象化说明:
- 代价函数 J ( w , b ) J(w,b) J(w,b)是一个凸函数(convex function)
- 非凸函数会存在很多极小值
2. 朝最陡的下坡方向走一步,不断地迭代
w
:
=
w
−
α
∂
J
(
w
,
b
)
∂
w
w := w - \alpha\frac{\partial J(w,b)}{\partial w}
w:=w−α∂w∂J(w,b)
b : = w − α ∂ J ( w , b ) ∂ b b := w - \alpha\frac{\partial J(w,b)}{\partial b} b:=w−α∂b∂J(w,b)
1.2.8 Derivatives with a Computation Graph
上述计算图的的导数关系是:
d
J
d
u
=
d
J
d
v
d
v
d
u
\frac{dJ}{du}=\frac{dJ}{dv}\frac{dv}{du}
dudJ=dvdJdudv ,
d
J
d
b
=
d
J
d
u
d
u
d
b
\frac{dJ}{db}=\frac{dJ}{du}\frac{du}{db}
dbdJ=dudJdbdu ,
d
J
d
a
=
d
J
d
u
d
u
d
a
\frac{dJ}{da}=\frac{dJ}{du}\frac{du}{da}
dadJ=dudJdadu
其实利用计算图求导即链式法则。
1.2.9 逻辑回归中的梯度下降(Logistic Regression Gradient Descent)
假设样本只有两个特征
x
1
{{x}_{1}}
x1和
x
2
{{x}_{2}}
x2,参数为
w
1
{{w}_{1}}
w1、
w
2
{{w}_{2}}
w2 和
b
b
b。
z
z
z的计算公式为:
y
^
=
a
=
σ
(
z
)
\hat{y}=a=\sigma (z)
y^=a=σ(z)
σ
(
z
)
=
1
1
+
e
−
z
\sigma \left( z \right)=\frac{1}{1+{{e}^{-z}}}
σ(z)=1+e−z1
z = w T x + b = w 1 x 1 + w 2 x 2 + b z={{w}^{T}}x+b = {{w}_{1}}{{x}_{1}}+{{w}_{2}}{{x}_{2}}+b z=wTx+b=w1x1+w2x2+b
损失函数:
L
(
y
^
(
i
)
,
y
(
i
)
)
=
−
y
(
i
)
log
y
^
(
i
)
−
(
1
−
y
(
i
)
)
log
(
1
−
y
^
(
i
)
)
L( {{{\hat{y}}}^{(i)}},{{y}^{(i)}})=-{{y}^{(i)}}\log {{\hat{y}}^{(i)}}-(1-{{y}^{(i)}})\log (1-{{\hat{y}}^{(i)}})
L(y^(i),y(i))=−y(i)logy^(i)−(1−y(i))log(1−y^(i))
代价函数:
J
(
w
,
b
)
=
1
m
∑
i
m
L
(
y
^
(
i
)
,
y
(
i
)
)
J\left( w,b \right)=\frac{1}{m}\sum\nolimits_{i}^{m}{L( {{{\hat{y}}}^{(i)}},{{y}^{(i)}})}
J(w,b)=m1∑imL(y^(i),y(i))
单个样本的代价函数:
L
(
a
,
y
)
=
−
(
y
log
(
a
)
+
(
1
−
y
)
log
(
1
−
a
)
)
L(a,y)=-(y\log (a)+(1-y)\log (1-a))
L(a,y)=−(ylog(a)+(1−y)log(1−a))
a a a:逻辑回归的输出, y y y:样本的标签值
梯度下降法,
w
w
w和
b
b
b的更新公式:
w
:
=
w
−
a
∂
J
(
w
,
b
)
∂
w
,
b
:
=
b
−
a
∂
J
(
w
,
b
)
∂
b
w:=w-a \frac{\partial J(w,b)}{\partial w},b:=b-a\frac{\partial J(w,b)}{\partial b}
w:=w−a∂w∂J(w,b),b:=b−a∂b∂J(w,b)
链式法则:
∂
L
∂
w
1
=
(
d
L
d
a
)
⋅
(
d
a
d
z
)
(
∂
z
∂
w
1
)
=
[
(
−
y
a
+
(
1
−
y
)
(
1
−
a
)
)
]
⋅
[
a
(
1
−
a
)
]
[
x
1
]
=
(
a
−
y
)
x
1
\frac{\partial L}{\partial {{w}_{1}}}=(\frac{dL}{da})\cdot (\frac{da}{dz}) (\frac{\partial z}{\partial {{w}_{1}}})=[( - \frac{y}{a} + \frac{(1 - y)}{(1 - a)})]\cdot [a(1 - a)][x_1]=(a-y)x1
∂w1∂L=(dadL)⋅(dzda)(∂w1∂z)=[(−ay+(1−a)(1−y))]⋅[a(1−a)][x1]=(a−y)x1
∂ L ∂ w 2 = ( d L d a ) ⋅ ( d a d z ) ( ∂ z ∂ w 2 ) = [ ( − y a + ( 1 − y ) ( 1 − a ) ) ] ⋅ [ a ( 1 − a ) ] [ x 2 ] = ( a − y ) x 2 \frac{\partial L}{\partial {{w}_{2}}}=(\frac{dL}{da})\cdot (\frac{da}{dz}) (\frac{\partial z}{\partial {{w}_{2}}})=[( - \frac{y}{a} + \frac{(1 - y)}{(1 - a)})]\cdot [a(1 - a)][x_2]=(a-y)x2 ∂w2∂L=(dadL)⋅(dzda)(∂w2∂z)=[(−ay+(1−a)(1−y))]⋅[a(1−a)][x2]=(a−y)x2
∂ L ∂ b = ( d L d a ) ⋅ ( d a d z ) ( ∂ z ∂ b ) = [ ( − y a + ( 1 − y ) ( 1 − a ) ) ] ⋅ [ a ( 1 − a ) ] = ( a − y ) \frac{\partial L}{\partial {b}}=(\frac{dL}{da})\cdot (\frac{da}{dz}) (\frac{\partial z}{\partial {b}})=[( - \frac{y}{a} + \frac{(1 - y)}{(1 - a)})]\cdot [a(1 - a)]=(a-y) ∂b∂L=(dadL)⋅(dzda)(∂b∂z)=[(−ay+(1−a)(1−y))]⋅[a(1−a)]=(a−y)
参数更新:
w
1
=
w
1
−
α
d
w
1
,
w
2
=
w
2
−
α
d
w
2
,
b
=
b
−
α
d
b
{{w}_{1}}={{w}_{1}}-\alpha d{{w}_{1}},{{w}_{2}}={{w}_{2}} - \alpha d{{w}_{2}},b=b-\alpha db
w1=w1−αdw1,w2=w2−αdw2,b=b−αdb
1.2.10 m 个样本的梯度下降(Gradient Descent on m Examples)
m 个样本的梯度下降也就是对m个样本求损失函数,然后对损失函数求梯度,对参数的更新公式是不变的。此处直接给出伪代码,这里通过循环来实现求和以及参数的更新。
J=0;dw1=0;dw2=0;db=0;
for i = 1 to m
z(i) = wx(i)+b;
a(i) = sigmoid(z(i));
J += -[y(i)log(a(i))+(1-y(i))log(1-a(i));
dz(i) = a(i)-y(i);
dw1 += x1(i)dz(i);
dw2 += x2(i)dz(i);
db += dz(i);
J /= m;
dw1 /= m;
dw2 /= m;
db /= m;
w = w-alpha*dw
b = b-alpha*db
代码缺陷:两个for循环
- 循环遍历m个训练样本
- 循环遍历所有特征,对特征进行更新
1.2.11 向量化
针对上一节的两个问题,通过向量化代替循环来解决问题。
以下为两个数组相乘的向量化版本
import time #导入时间库
a = np.random.rand(1000000)
b = np.random.rand(1000000) #通过round随机得到两个一百万维度的数组
tic = time.time() #现在测量一下当前时间
#向量化的版本
c = np.dot(a,b)
toc = time.time()
print(“Vectorized version:” + str(1000*(toc-tic)) +”ms”) #打印一下向量化的版本的时间
#继续增加非向量化的版本
c = 0
tic = time.time()
for i in range(1000000):
c += a[i]*b[i]
toc = time.time()
print(c)
print(“For loop:” + str(1000*(toc-tic)) + “ms”)#打印for循环的版本的时间
计算向量 u = A v u=Av u=Av:
- 矩阵乘法的定义就是: u i = ∑ j A ij v j u_{i} =\sum_{j}^{}{A_{\text{ij}}v_{j}} ui=∑jAijvj
- 非向量化实现: u = n p . z e r o s ( n , 1 ) u=np.zeros(n,1) u=np.zeros(n,1), 并且通过两层循环 f o r ( i ) : f o r ( j ) : for(i):for(j): for(i):for(j):,得到 u [ i ] = u [ i ] + A [ i ] [ j ] ∗ v [ j ] u[i]=u[i]+A[i][j]*v[j] u[i]=u[i]+A[i][j]∗v[j]
- 向量化方式: u = n p . d o t ( A , v ) u=np.dot(A,v) u=np.dot(A,v)
Numpy内置的向量函数:
u=np.log()
:是计算对数函数()u=np.exp()
:是计算指数函数()np.abs()
是:计算数据的绝对值np.maximum()
:计算元素中的最大值v**2
:计算每个元素的平方1/v
:获取元素 的倒数
参数更新向量化方式:
d
w
dw
dw 定义 为一个向量,np.zeros(n(x),1)
,向量化操作
d
w
=
d
w
+
x
(
i
)
d
z
(
i
)
dw=dw+x^{(i)}dz^{(i)}
dw=dw+x(i)dz(i)
1.2.13 向量化逻辑回归(Vectorizing Logistic Regression)
对m个样本进行预测:
a
(
1
)
=
σ
(
z
(
1
)
)
,
z
(
1
)
=
w
T
x
(
1
)
+
b
a^{(1)}=\sigma (z^{(1)}),z^{(1)}=w^{T}x^{(1)}+b
a(1)=σ(z(1)),z(1)=wTx(1)+b
a ( 2 ) = σ ( z ( 2 ) ) , z ( 2 ) = w T x ( 2 ) + b a^{(2)}=\sigma (z^{(2)}),z^{(2)}=w^{T}x^{(2)}+b a(2)=σ(z(2)),z(2)=wTx(2)+b
. . . ... ...
a ( m ) = σ ( z ( m ) ) , z ( m ) = w T x ( m ) + b a^{(m)}=\sigma (z^{(m)}),z^{(m)}=w^{T}x^{(m)}+b a(m)=σ(z(m)),z(m)=wTx(m)+b
向量化操作:
X
:
R
n
x
×
m
,
w
:
R
1
×
m
X:R^{n_x \times m},w:R^{1 \times m}
X:Rnx×m,w:R1×m
[
z
(
1
)
,
z
(
2
)
,
.
.
.
z
(
m
)
]
=
w
T
X
+
[
b
,
b
,
.
.
.
b
]
=
[
w
T
x
(
1
)
+
b
,
w
T
x
(
2
)
+
b
,
.
.
.
w
T
x
(
m
)
+
b
]
[z^{(1)},z^{(2)},...z^{(m)}]=w^{T}X+[b,b,...b]=[w^{T}x^{(1)}+b,w^{T}x^{(2)}+b,...w^{T}x^{(m)}+b]
[z(1),z(2),...z(m)]=wTX+[b,b,...b]=[wTx(1)+b,wTx(2)+b,...wTx(m)+b]
numpy实现:
Z = np.dot(W.T,X) + b # Vectorization, then broadcasting, Z shape is (1, m)
A = 1 / 1 + np.exp(-Z) # Vectorization, A shape is (1, m)
向量化梯度下降
Z = w T X + b = n p . d o t ( w . T , X ) + b Z = w^{T}X + b = np.dot( w.T,X)+b Z=wTX+b=np.dot(w.T,X)+b
A = σ ( Z ) A = \sigma( Z ) A=σ(Z)
d Z = A − Y dZ = A - Y dZ=A−Y
d w = 1 m ∗ X ∗ d z T {{dw} = \frac{1}{m}*X*dz^{T}\ } dw=m1∗X∗dzT
d b = 1 m ∗ n p . s u m ( d Z ) db= \frac{1}{m}*np.sum( dZ) db=m1∗np.sum(dZ)
w : = w − a ∗ d w w: = w - a*dw w:=w−a∗dw
b : = b − a ∗ d b b: = b - a*db b:=b−a∗db
1.2.15 Python-Numpy简单教程
一图总结Numpy的广播机制:
Numpy:axis,指明将要进行的运算是沿着哪个轴执行,0轴是垂直的(列),而1轴是水平的(行)
注意:
- 不建议使用类似
a=np.random.randn(5)
这种数据结构,a.shape=(5, )
操作起来不可控; - 建议使用
a=np.random.randn(5,1)
这种操作,乘积的维度是可控的; assert(a.shape==(5,1))
来辅助判断数据的维度
1.2.18 logistic 损失函数的解释(Explanation of logistic regression cost function)
为什么采用logloss,以及logloss是如何得到的。
型预测结果:
y
^
=
σ
(
w
T
x
+
b
)
\hat{y}=\sigma(w^{T}x+b)
y^=σ(wTx+b),
σ
(
z
)
=
σ
(
w
T
x
+
b
)
=
1
1
+
e
−
z
\sigma(z)=\sigma(w^{T}x+b)=\frac{1}{1+e^{-z}}
σ(z)=σ(wTx+b)=1+e−z1
算法模型的输出
y
^
\hat{y}
y^ 是给定训练样本
x
x
x 条件下
y
y
y 等于1的概率,
y
^
=
p
(
y
=
1
∣
x
)
\hat{y}=p(y=1|x)
y^=p(y=1∣x)
分两种情况讨论:
if
y
=
1
y=1
y=1,⇒
p
(
y
∣
x
)
=
y
^
p(y|x)=\hat{y}
p(y∣x)=y^
if
y
=
0
y=0
y=0,⇒
p
(
y
∣
x
)
=
1
−
y
^
p(y|x)=1-\hat{y}
p(y∣x)=1−y^
上述的两个条件概率公式合并成一个: p ( y ∣ x ) = y ^ y ( 1 − y ^ ) ( 1 − y ) p(y|x)={\hat{y}}^{y}{(1-\hat{y})}^{(1-y)} p(y∣x)=y^y(1−y^)(1−y)
log 函数是严格单调递增函数,最大化 l o g ( p ( y ∣ x ) ) log(p(y|x)) log(p(y∣x)) 等价于最大化 p ( y ∣ x ) p(y|x) p(y∣x),就是计算 l o g ( y ^ ( y ) ( 1 − y ^ ) ( 1 − y ) ) log({\hat{y}}^{(y)}{(1-\hat{y})}^{(1-y)}) log(y^(y)(1−y^)(1−y)),化简后 y l o g y ^ + ( 1 − y ) l o g ( 1 − y ^ ) ylog\hat{y}+(1-y)log(1-\hat{y}) ylogy^+(1−y)log(1−y^)。后面便可以得到逻辑回归的损失函数。
[1] 深度学习笔记目录