逻辑回归中的梯度下降
梯度下降法的作用是:在测试集上,通过最小化代价函数
J
(
w
,
b
)
J(w,b)
J(w,b)来训练的参数
w
w
w和
b
b
b。
w
:
=
w
?
a
?
J
(
w
,
b
)
?
w
w:=w-a\frac{\partial J(w,b)}{\partial w}
w:=w?a?w?J(w,b)?
b
:
=
w
?
a
?
J
(
w
,
b
)
?
b
b:=w-a\frac{\partial J(w,b)}{\partial b}
b:=w?a?b?J(w,b)?
:
=
:=
:=表示更新参数
a
a
a 表示学习率(learning rate),用来控制步长(step)
?
\partial
? 表示求偏导符号
?
J
(
w
,
b
)
?
w
\frac{\partial J(w,b)}{\partial w}
?w?J(w,b)? 是
J
(
w
,
b
)
J(w,b)
J(w,b) 对
w
w
w 求偏导,代码使用
d
w
dw
dw 表示
?
J
(
w
,
b
)
?
b
\frac{\partial J(w,b)}{\partial b}
?b?J(w,b)? 是
J
(
w
,
b
)
J(w,b)
J(w,b)对
b
b
b 求偏导,代码使用
d
b
db
db 表示
单样本梯度下降
回想逻辑回归的公式定义:
z
=
w
T
x
+
b
z={{w}^{T}}x+b
z=wTx+b
y
^
=
a
=
σ
(
z
)
=
1
1
+
e
?
z
\hat{y}=a=\sigma (z)=\frac{1}{1+{{e}^{-z}}}
y^?=a=σ(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)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?∑im?L(y^?(i),y(i)) 假设样本只有两个特征
x
1
{{x}_{1}}
x1?和
x
2
{{x}_{2}}
x2?,只考虑一个样本,为了计算
z
z
z,我们需要输入参数
w
1
{{w}_{1}}
w1?、
w
2
{{w}_{2}}
w2? 和
b
b
b,还有特征值
x
1
{{x}_{1}}
x1?和
x
2
{{x}_{2}}
x2?。
z
=
w
1
x
1
+
w
2
x
2
+
b
z={{w}_{1}}{{x}_{1}}+{{w}_{2}}{{x}_{2}}+b
z=w1?x1?+w2?x2?+b
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是样本的标签值。 根据导数链式法则进行反向传播
d
a
=
d
L
(
a
,
y
)
d
a
=
?
y
/
a
+
(
1
?
y
)
/
(
1
?
a
)
da=\frac{dL(a,y)}{da}=-y/a+(1-y)/(1-a)
da=dadL(a,y)?=?y/a+(1?y)/(1?a)
d
a
d
z
=
a
?
(
1
?
a
)
\frac{da}{dz}=a\cdot (1-a)
dzda?=a?(1?a) 所以:
d
z
=
d
L
(
a
,
y
)
d
z
=
(
d
L
d
a
)
?
(
d
a
d
z
)
=
a
?
y
dz=\frac{dL(a,y)}{dz}=(\frac{dL}{da})\cdot (\frac{da}{dz})=a-y
dz=dzdL(a,y)?=(dadL?)?(dzda?)=a?y
d
w
1
=
?
L
?
w
1
=
x
1
?
d
z
d{{w}_{1}}=\frac{\partial L}{\partial {{w}_{1}}}={{x}_{1}}\cdot dz
dw1?=?w1??L?=x1??dz
d
w
2
=
?
L
?
w
2
=
x
2
?
d
z
d{{w}_{2}}=\frac{\partial L}{\partial {{w}_{2}}}={{x}_{2}}\cdot dz
dw2?=?w2??L?=x2??dz
d
b
=
d
z
db=dz
db=dz 更新
w
1
=
w
1
?
a
d
w
1
{{w}_{1}}={{w}_{1}}-a d{{w}_{1}}
w1?=w1??adw1?, 更新
w
2
=
w
2
?
a
d
w
2
{{w}_{2}}={{w}_{2}}-a d{{w}_{2}}
w2?=w2??adw2?, 更新
b
=
b
?
α
d
b
b=b-\alpha db
b=b?αdb。 这就是关于单个样本实例的梯度下降算法中参数更新一次的步骤。
向量化
向量化是非常基础的去除代码中for循环的艺术,在深度学习安全领域、深度学习实践中是提高代码运行速度非常关键的技巧。
python中向量化使用的常用指令
import numpy as np
w= np.array(n(x), 1)
u=np.zeros(n(x), 1)
c= np.dot(a,b)
u=np.log
u=np.abs()
u=np.maximum(v, 0)
矩阵乘法的定义就是:
u
i
=
∑
j
A
ij
v
i
u_{i} =\sum_{j}^{}{A_{\text{ij}}v_{i}}
ui?=∑j?Aij?vi?,这取决于你怎么定义
u
i
u_{i}
ui?值。同样使用非向量化实现,
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] 。现在就有了
i
i
i 和
j
j
j 的两层循环,这就是非向量化。向量化方式就可以用
u
=
n
p
.
d
o
t
(
A
,
v
)
u=np.dot(A,v)
u=np.dot(A,v),右边这种向量化实现方式,消除了两层循环使得代码运行速度更快。
多样本梯度下降
z
=
w
T
x
+
b
z={{w}^{T}}x+b
z=wTx+b,
w
w
w、
x
x
x都是列向量
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 利用前五个公式完成了前向和后向传播,实现了对所有训练样本进行预测和求导,利用后两个公式,梯度下降更新参数。不使用for循环,通过一次迭代实现一次梯度下降,但如果你希望多次迭代进行梯度下降,那么仍然需要for循环,放在最外层。
|