在本节中,我们学习如何计算偏导数来实现Logistic回归的梯度下降法。
我们将使用导数流程图来计算梯度。
首先回顾一下Logistic回归的公式
z = w T x + b z = w^Tx+b z=wTx+b
y ^ = a = σ ( z ) = 1 1 + e − z \widehat{y}=a = \sigma(z) = \frac 1 {1+e^{-z}} y =a=σ(z)=1+e−z1
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))
现在只考虑单个样本的情况
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)),为Logistic的损失函数,a是Logistic回归的输出,y是样本的基本真值标签值。
现在写出该样本的偏导数流程图
假设样本只有两个,特征x1和x2,为了计算z,我们需要输出参数w1,w2和b,还有样本特征x1,x2,因此用来计算z的偏导数公式,
z
=
w
1
∗
x
1
+
w
2
∗
x
2
+
b
z=w1*x1+w2*x2+b
z=w1∗x1+w2∗x2+b,
y
^
=
a
=
σ
(
z
)
\hat y = a = \sigma(z)
y^=a=σ(z)是偏导数流程图的下一步,最后计算L(a,y).
因此,在逻辑回归中,我们需要做的是变换参数w和b的值,来最小化损失函数。
接下来我们讨论怎样向后计算偏导数,想要计算损失函数 L ( a , y ) L(a,y) L(a,y)的导数,首先我们要向前一步,先计算损失函数的导数 d L ( a , y ) d a \frac {dL(a,y)} {d a} dadL(a,y),即L关于变量a的导数,在代码中,我们用da来表示这个变量。如果你熟悉微积分的话,这个da的结果为 d L ( a , y ) d a = d a = − y a + 1 − y 1 − a \frac { dL(a,y)} {da} = d a = \frac {-y} a+\frac {1-y} {1-a} dadL(a,y)=da=a−y+1−a1−y,损失函数的导数计算公式就是这样,计算关于变量a的导数,就是这个式子。
现在计算出da,最终结果关于变量a的导数,现在可以在向后一步,计算dz,dz是代码中的变量名,dz是损失函数关于z的导数,
d
z
=
d
L
d
z
=
d
L
(
a
,
y
)
d
z
=
a
−
y
dz = \frac {dL} {dz} = \frac {dL(a,y)} {dz} = a-y
dz=dzdL=dzdL(a,y)=a−y;其中
d
L
d
z
=
d
L
(
a
,
y
)
d
a
∗
d
a
d
z
\frac {dL} {dz} = \frac {dL(a,y)} {da}* \frac {da} {dz}
dzdL=dadL(a,y)∗dzda,其中
d
a
d
z
=
a
∗
(
1
−
a
)
\frac {da} {dz} = a*(1-a)
dzda=a∗(1−a),这个推导的过程,即“链式法则”。
现在后向传播的最后一步,计算看看w和b需要如何变化,特别的关于w1的导数 d L d w 1 = d w 1 = x 1 ∗ d z \frac {dL} {dw1} = dw1 = x1 *dz dw1dL=dw1=x1∗dz,同样的 d L d w 2 = d w 2 = x 2 ∗ d z \frac {dL} {dw2} = dw2 = x2 *dz dw2dL=dw2=x2∗dz, d L d b = d b = d z \frac {dL} {db} = db = dz dbdL=db=dz。
因此关于单个样本的梯度下降法,你说需要做的就是这些事情。使用上面的公式计算dz、dw1、dw2、db。
更新
w
1
=
w
1
−
α
∗
d
w
1
;
w
2
=
w
1
−
α
∗
d
w
2
;
b
=
b
−
α
∗
d
b
w1= w1 - α*dw1;w2= w1 - α*dw2;b = b - α*db
w1=w1−α∗dw1;w2=w1−α∗dw2;b=b−α∗db。这是单个样本实例的一次梯度更新的步骤。
详细的推导过程
z = w T x + b z = w^Tx+b z=wTx+b
y ^ = a = σ ( z ) = 1 1 + e − z \widehat{y}=a = \sigma(z) = \frac 1 {1+e^{-z}} y =a=σ(z)=1+e−z1
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))
∂ L ( a , y ) d a = − y a + ( 1 − y 1 − a ) \frac {\partial L(a,y)} {da} = -\frac y a + (\frac {1-y} {1-a}) da∂L(a,y)=−ay+(1−a1−y)
= a − y a ( 1 − a ) =\frac {a-y} {a(1-a)} =a(1−a)a−y,其中 ∂ L ( a , y ) d a \frac {\partial L(a,y)} {da} da∂L(a,y)就是L(a,y)关于a的偏导数。
∂ L ( a , y ) d z = ∂ L ( a , y ) d a d a d z \frac {\partial L(a,y)} {dz} = \frac {\partial L(a,y)} {da} \frac {da} {dz} dz∂L(a,y)=da∂L(a,y)dzda,其中
d a d z = e − z ( 1 + e − z ) 2 \frac {da} {dz} =\frac {e^{-z}} {(1+e^{-z})^2} dzda=(1+e−z)2e−z
= 1 + e − z − 1 ( 1 + e − z ) 2 =\frac {1+e^{-z} - 1} {(1+e^{-z})^2} =(1+e−z)21+e−z−1
= 1 1 + e − z − 1 ( 1 + e − z ) 2 =\frac 1 {1+e^{-z}} - \frac 1 {(1+e^{-z})^2} =1+e−z1−(1+e−z)21
= a − a 2 = a ( 1 − a ) =a - a^2 = a(1-a) =a−a2=a(1−a)
因此,推导出, ∂ L ( a , y ) d z = a − y \frac {\partial L(a,y)} {dz} = a - y dz∂L(a,y)=a−y,代码中用dz表示。
∂ L ( a , y ) d w 1 = ∂ L ( a , y ) d a ∗ d a d z ∗ d z d w 1 = d w 1 = x 1 ∗ d z \frac {\partial L(a,y)} {dw1} = \frac {\partial L(a,y)} {da} *\frac {da} {dz}* \frac {dz} {dw1} = dw1 = x1*dz dw1∂L(a,y)=da∂L(a,y)∗dzda∗dw1dz=dw1=x1∗dz,代码中,用dw1表示
∂ L ( a , y ) d w 2 = ∂ L ( a , y ) d a ∗ d a d z ∗ d z d w 2 = d w 2 = x 2 ∗ d z \frac {\partial L(a,y)} {dw2} = \frac {\partial L(a,y)} {da} *\frac {da} {dz}* \frac {dz} {dw2} = dw2 = x2*dz dw2∂L(a,y)=da∂L(a,y)∗dzda∗dw2dz=dw2=x2∗dz,代码中,用dw2表示
∂ L ( a , y ) d b = ∂ L ( a , y ) d a ∗ d a d z ∗ d z d b = d b = d z \frac {\partial L(a,y)} {db} = \frac {\partial L(a,y)} {da} *\frac {da} {dz}* \frac {dz} {db} = db = dz db∂L(a,y)=da∂L(a,y)∗dzda∗dbdz=db=dz,代码中,用db表示
对参数w和b进行更新,其中α是学习率
w
1
=
w
1
−
α
∗
d
w
1
w1= w1 - α*dw1
w1=w1−α∗dw1
w
2
=
w
1
−
α
∗
d
w
2
w2= w1 - α*dw2
w2=w1−α∗dw2
b
=
b
−
α
∗
d
b
b = b - α*db
b=b−α∗db
首先,我们需要记住关于成本函数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)=m1∑i=1mL(a(i),y(i))
a
(
i
)
=
y
^
(
i
)
=
σ
(
z
(
i
)
)
=
σ
(
w
T
x
(
i
)
+
b
)
a^{(i)} = \hat{y}^{(i)} = \sigma(z^{(i)}) = \sigma{(w^Tx^{(i)}+b)}
a(i)=y^(i)=σ(z(i))=σ(wTx(i)+b)
全局成本函数是一个求和,实际上是1到m项,损失函数和的平均。
它表明全局成本函数对w1的导数,也同样是各项损失函数对w1导数的平均。
∂
∂
w
1
J
(
w
,
b
)
=
1
m
∑
i
=
1
m
∂
∂
w
1
L
(
a
(
i
)
,
y
(
i
)
)
\frac {\partial} {\partial w1} J(w,b) = \frac 1 m \sum_{i = 1}^m\frac {\partial} {\partial w1} L(a^{(i)},y^{(i)})
∂w1∂J(w,b)=m1∑i=1m∂w1∂L(a(i),y(i)),其中
∂
∂
w
1
L
(
a
(
i
)
,
y
(
i
)
)
=
d
w
1
(
i
)
=
(
x
(
i
)
,
y
(
i
)
)
\frac {\partial} {\partial w1} L(a^{(i)},y^{(i)}) = dw1^{(i)} = (x^{(i)},y^{(i)})
∂w1∂L(a(i),y(i))=dw1(i)=(x(i),y(i)),即对单个训练样本进行计算,所以真正需要做的是计算这些导数,如我们之前的训练样本上做的,并且求平均,会得到全局梯度值,你可以将它直接应用到梯度下降算法中。
让我们将其使用到一个具体的算法中。
J = 0;dw1 = 0;dw2 = 0;db = 0
For i = 1 to m
z
(
i
)
=
w
T
x
(
i
)
+
b
z^{(i)} = w^Tx^{(i)} + b
z(i)=wTx(i)+b
a
(
i
)
=
σ
(
z
(
i
)
)
a^{(i)} = \sigma(z^{(i)})
a(i)=σ(z(i))
J
+
=
−
[
y
(
i
)
l
o
g
a
(
i
)
+
(
1
−
y
(
i
)
)
l
o
g
(
1
−
a
(
i
)
)
]
J+=-[y^{(i)}loga^{(i)}+(1-y^{(i)})log(1-a^{(i)})]
J+=−[y(i)loga(i)+(1−y(i))log(1−a(i))]
d
z
(
i
)
=
a
(
i
)
−
y
(
i
)
dz^{(i)} = a^{(i)} - y^{(i)}
dz(i)=a(i)−y(i)
d
w
1
+
=
x
1
(
i
)
d
z
(
i
)
dw1+=x1^{(i)}dz^{(i)}
dw1+=x1(i)dz(i) 目前特征2个,n=2
d
w
2
+
=
x
2
(
i
)
d
z
(
i
)
dw2+=x2^{(i)}dz^{(i)}
dw2+=x2(i)dz(i)
d
b
+
=
d
z
(
i
)
db +=dz^{(i)}
db+=dz(i)
J/=m
dw1/=m
dw2/=m
db/=m
其中,
d
w
1
=
∂
J
∂
w
1
dw1 = \frac {\partial J} {\partial w1}
dw1=∂w1∂J
w
1
:
=
w
1
−
α
d
w
1
w1:= w1 - \alpha dw1
w1:=w1−αdw1
w
2
:
=
w
2
−
α
d
w
2
w2:= w2 - \alpha dw2
w2:=w2−αdw2
b
:
=
b
−
α
d
b
b:= b - \alpha db
b:=b−αdb
上述代码只应用了一次梯度下降法,因此,你需要重复上述内容很多次,以应用多次梯度下降。
上述计算中有两个缺点,即我们需要编写两个for循环,第一个for循环是遍历m个训练样本的小循环,第二个for循环是遍历所有特征的for循环,这个例子中,我们有两个特征,所以n等于2,n_x等于2,但是如果你有更多特征,你就需要一个for循环,来遍历所有的n个特征,当你应用深度学习算法,你会发现,在代码中显式的使用for循环,会使算法效率很低。同时在深度学习领域,会有越来越大的数据集,所以能够应用你的算法,完全不用显式for循环的话,会是重要的,会帮助你处理更大的数据集,有一门向量化技术,帮助你的代码,摆脱这些显式的for循环。在深度学习的早期,向量化技术有时候用来加速运算是非常棒的,在深度学习时代,用向量化来摆脱for循环已经变得相当重要。