本文来自于网易云课堂
二分类问题
logistic回归中的梯度下降法
本节主要用到三个核心公式:
z=wTx+b
y^=a=σ(z)=11+e(−z)
L(a,y)=−(ylog(a)+(1−y)log(1−a))
本文用到的符号说明:
dz=∂L∂z,一般记为dLdz
da=∂L∂a,一般记为dLda
dw=∂L∂w,一般记为dLdw
db=∂L∂b,一般记为dLdb
从下图中可以清晰的看出前向传播过程,现在开始计算导数。
公式的推导如下:
dLda=−ya+1−y1−a
dadz=a(1−a)
dz=dLdz=dLda∗dadz=a−y
dw=dLdw=dLdz∗dzdw=(a−y)∗x=dz∗x
db=dLdb=dLdz∗dzdb=a−y=dz
m个样本的梯度下降
核心公式:
J(w,b)=1m∑mi=1L(a(i),y)
a(i)=y^(i)=σ(z(i))=σ(wTx(i)+b)
∂∂w1J(w,b)=1m∑mi=1∂∂w1L(a(i),y)=1m∑mi=1dw(i)1
全局成本函数实际上是各项损失函数的平均,相应的,全局成本函数对
w1
的导数同样是各项损失函数对
w1
的平均。所以,我们实际要做的就是计算全局梯度导数
∂∂w1J(w,b)
,于是我们可以这样来表示算法。
但是,这种计算方式并不完美,我们可以从编程上对其进行改进。首先,这种算法需要写2个for循环,一个遍历m个样本,一个遍历每个样本中的n个特征(上图中只有2个特征)。当使用深度学习算法时会发现,使用for循环会使得算法很低效。同样,在深度学习领域会有越来越大的数据集,所以能够应用你的算法完全不使用显示for循环是很有帮助的。而向量化技术的出现能够帮助你的代码摆脱这些显示的for循环。
向量化
import numpy as np
import time
a = np.random.rand(1000000)
b = np.random.rand(1000000)
tic = time.time()
c = np.dot(a, b)
toc = time.time()
print c
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"
250134.41753492085
Vectorized version:3.00002098083ms
250134.4175349188
for loop:524.999856949ms
从时间对比上我们看到向量化相比for循环可以节省将近200倍的时间。对于深度学习算法,利用向量化后效率可以大大提升。一个经验法则就是,在计算回归时尽量避免使用for循环。
python中的numpy模块可以实现向量化的运算。
import numpy as np
a = np.zeros((1, 10))
b = np.exp(a)
b
array([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]])
m个样本的logistic回归
首先我们通过向量化消除第一个循环,过程如下图:
对于m个样本,我们可以得到这样一个公式:
Z=WTX+b,Z∈R1×m,W∈Rn×1,X∈Rn×m,
其中,
Z
表示m个输出,
其次我们通过向量化消除第二个循环,过程如下图:
我们可以将算法进一步修改为如下图所示,这样就实现了一次迭代。当然如果想要使用多次迭代,恐怕还是得使用for循环。
A=σ(z)
dZ=A−Y
dW=1mXdZT
db=1mnp.sum(dZ)
W=W−αdW
b=b−αdb