逻辑回归中的梯度下降 Logistic Regression Gradient Descent
本节我们讨论怎样通过计算偏导数来实现逻辑回归中的梯度下降算法。
1.细节推导
假设样本只有两个特征 x 1 x1 x1和 x 2 x2 x2,为了计算 z z z,我们需要输入参数 w 1 、 w 2 w1、w2 w1、w2和 b b b,除此之外还有特征值 x 1 x1 x1和 x 2 x2 x2。因此 z z z的计算公式为 z = w 1 x 1 + w 2 x 2 + b z = w_1 x_1 + w_2 x_2 + b z=w1x1+w2x2+b。
我们回顾一下逻辑回归的公式定义如下:
y
^
=
a
=
σ
(
z
)
其
中
z
=
w
T
x
+
b
,
σ
(
z
)
=
1
1
+
e
−
z
\hat{y} = a = \sigma(z) \ 其中 z = w^T x + b,\sigma(z) = \frac{1}{1 + e^{-z}}
y^=a=σ(z) 其中z=wTx+b,σ(z)=1+e−z1
损失函数:
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)log(y^(i))−(1−y(i))log(1−y^(i))
代价函数: J ( w , b ) = 1 m ∑ i m L ( y ^ ( i ) , y ( i ) ) J(w, b) = \frac{1}{m}\sum_i^m L(\hat{y}^{(i)}, y^{(i)}) J(w,b)=m1∑imL(y^(i),y(i))
假设现在只考虑单个样本的情况,单个样本的代价函数定义如下:
L
(
a
,
y
)
=
−
(
y
l
o
g
(
a
)
+
(
1
−
y
)
log
(
1
−
a
)
)
L(a, y) = -(y \ log(a) + (1 - y)\log (1 - a))
L(a,y)=−(y log(a)+(1−y)log(1−a))
其中a是逻辑回归的输出,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 ( a , y ) L(a, y) L(a,y)关于 a a a的导数,在代码中我们以 d a da da表示 d L ( a , y ) d a \frac{\mathrm{d}L(a, y)}{\mathrm{d}a} dadL(a,y)。
通过微积分的知识,我们可以求得 d L ( a , y ) d a = − y / a + ( 1 − y ) / ( 1 − a ) \frac{\mathrm{d}L(a, y)}{\mathrm{d}a} = -y/a + (1 - y)/(1 - a) dadL(a,y)=−y/a+(1−y)/(1−a)
接下来,我们继续反向传播,
d
L
(
a
,
y
)
d
z
=
d
L
d
z
=
(
d
L
d
a
)
(
d
a
d
z
)
\frac{\mathrm{d}L(a, y)}{\mathrm{d}z} = \frac{\mathrm{d}L}{\mathrm{d}z} = ({\frac{\mathrm{d}L}{\mathrm{d}a}})({\frac{\mathrm{d}a}{\mathrm{d}z}})
dzdL(a,y)=dzdL=(dadL)(dzda),其中
d
L
d
a
\frac{\mathrm{d}L}{\mathrm{d}a}
dadL我们已经求得,下面计算
d
a
d
z
\frac{\mathrm{d}a}{\mathrm{d}z}
dzda。
a
=
σ
(
z
)
,
σ
(
z
)
=
1
1
+
e
−
x
,
d
a
d
z
=
σ
(
z
)
′
=
σ
(
z
)
(
1
−
σ
(
z
)
)
a = \sigma(z),\sigma(z) = \frac{1}{1 + e^{-x}}, \frac{\mathrm{d}a}{\mathrm{d}z} = \sigma(z)^{'} = \sigma(z)(1 - \sigma(z))
a=σ(z),σ(z)=1+e−x1,dzda=σ(z)′=σ(z)(1−σ(z))
因此将两项相乘,得到:
d
z
=
d
L
(
a
,
y
)
d
z
=
d
L
d
z
=
(
d
L
d
a
)
(
d
a
d
z
)
=
(
−
y
a
+
(
1
−
y
)
(
1
−
a
)
)
×
a
(
1
−
a
)
=
a
−
y
\mathrm{d}z = \frac{\mathrm{d}L(a, y)}{\mathrm{d}z} = \frac{\mathrm{d}L}{\mathrm{d}z} = ({\frac{\mathrm{d}L}{\mathrm{d}a}})({\frac{\mathrm{d}a}{\mathrm{d}z}}) = (-\frac{y}{a} + \frac{(1 - y)}{(1 - a)}) \times a(1 - a) = a - y
dz=dzdL(a,y)=dzdL=(dadL)(dzda)=(−ay+(1−a)(1−y))×a(1−a)=a−y
如果不熟悉微积分也没关系,你只需要知道
d
z
=
a
−
y
\mathrm{d}z = a- y
dz=a−y已经计算好了。
现进行最后一步反向推导,也就是计算代价函数
J
J
J关于参数
w
w
w和
b
b
b的导数。
d
w
1
=
1
m
∑
i
m
x
1
(
i
)
(
a
(
i
)
−
y
(
i
)
)
d
w
2
=
1
m
∑
i
m
x
2
(
i
)
(
a
(
i
)
−
y
(
i
)
)
d
b
=
1
m
∑
i
m
(
a
(
i
)
−
y
(
i
)
)
\mathrm{d}w_1 = \frac{1}{m}\sum_i^m x_1^{(i)}(a^{(i)} - y^{(i)}) \\ \mathrm{d}w_2 = \frac{1}{m}\sum_i^m x_2^{(i)}(a^{(i)} - y^{(i)}) \\ \mathrm{d}b = \frac{1}{m}\sum_i^m (a^{(i)} - y^{(i)})
dw1=m1i∑mx1(i)(a(i)−y(i))dw2=m1i∑mx2(i)(a(i)−y(i))db=m1i∑m(a(i)−y(i))
经过上述推导,逻辑回归的梯度下降算法所需要做的就是如下事情:
- 使用公式 d z = ( a − y ) \mathrm{d}z = (a - y) dz=(a−y)计算 d z \mathrm{d}z dz
- 使用 d w 1 = x 1 ⋅ d z \mathrm{d}w_1 = x_1 \cdot \mathrm{d}z dw1=x1⋅dz计算 d w 1 \mathrm{d}w_1 dw1,使用 d w 2 = x 2 ⋅ d z \mathrm{d}w_2 = x_2 \cdot \mathrm{d}z dw2=x2⋅dz计算 d w 2 \mathrm{d}w_2 dw2, d b = d z \mathrm{d}b = \mathrm{d}z db=dz来计算 d b \mathrm{d}b db
- 然后更新 w 1 = w 1 − α ⋅ d w 1 w1 = w1 - \alpha \cdot \mathrm{d}w_1 w1=w1−α⋅dw1, w 2 = w 2 − α ⋅ d w 2 w2 = w2 - \alpha \cdot \mathrm{d}w_2 w2=w2−α⋅dw2, b = b − α ⋅ d b b = b - \alpha \cdot \mathrm{d}b b=b−α⋅db
2.如何应用在多个样本
以上,你已经看到了如何计算导数,如何将梯度下降应用在逻辑回归的一个训练样本上。接下来,我们要介绍如何将其应用在m个训练样本上。
首先,让我们回顾一下损失函数
J
(
w
,
b
)
J(w, b)
J(w,b)的定义。
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)=m1i=1∑mL(a(i),y(i))
这是带有求和的全局代价函数,实际上是1到m项损失函数的均值。故我们想要将之前的单个样本应用拓展到m个样本之上,其实我们就是在对各个项进行计算并求其均值。因此,我们可以使用一个for循环来将其实现,伪代码如下。
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
这便是在m个样本上进行一次梯度下降迭代的伪代码,但这种计算存在两个缺点。在实际应用时,你需要编写两个for循环,内层for循环遍历m个训练样本,外层for循环遍历所有特征。
当你应用深度学习算法,你会发现在代码中显示地使用for循环会使你的算法很低小,并在深度学习领域中的特大数据集上表现较差。所以,我们将在下一节介绍一种向量化技术,帮助你摆脱这些显式的for循环。
现在,我们已经介绍完了怎样计算导数,并且实现针对单个及多个训练样本的逻辑回归的梯度下降算法。下一节,我们将介绍向量化技术,来帮助你间接、高效你的代码。