前言
相对于
L
2
L_2
L2? 正则化的计算量较大,dropout正则化减少了计算量,不足的是不能直观体现出
?
(
w
,
b
)
\jmath(w,b)
?(w,b) 随着迭代次数的变化情况。但这也不妨碍其在计算机视觉中的广泛使用。
dropout 正则化
原理
对神经网络中每一层的每个节点取一定概率丢弃,进而使得神经网络一定程度上简化
例如上图中,橙色的节点是丢弃的节点。橙色节点丢弃后,该神经网络就一定程度上简化了
常见方法:反向随机失活
反向随机失活在计算机视觉上用的多。使用反向随机失活时,神经网络最少取3层
d3 = np.random.rand(a3.shape[0],a3.shape[1])<keep.prob
a3 = np.multply(a3,d3)
a3 /= keep.prob
假设我们有 50 个神经元,且概率为 0.8,则 50 个神经元中有 10 个 将会被丢弃。
那么,
z
[
4
]
=
w
[
4
]
?
a
[
3
]
+
b
[
4
]
z^{[4]} = w^{[4]}*a^{[3]} + b^{[4]}
z[4]=w[4]?a[3]+b[4] 中,
a
[
3
]
a^{[3]}
a[3] 就被减少了
20
20%
20,为了不减少这个期望值,就需要 a3 /= keep.prob 来防止对
a
[
3
]
a^{[3]}
a[3] 期望值的改变。
但是,在测试阶段不可以使用反向随机失活,不然期望输出也会是随机的。
而且,反向随机失活会使代价函数不明确,故,在神经网络的训练过程中,要先确定
?
(
w
,
b
)
\jmath(w,b)
?(w,b) 随梯度下降的迭代次数增加而减小后再使用反向随机失活。
数据集扩增
图像
等一系列的图像操作可以使得数据量翻倍从而扩大训练集
字符
早终止法
早终止法的优点也是减少了计算量。但是却把两个问题结合在了一起增加了复杂度
如图,我们画出随着迭代次数增加的情况下,开发集 (dev) 误差与训练误差 (train) (或者
?
\jmath
? 代价函数也可) 的曲线。我们会发现随着迭代次数的增加,开发集 (dev) 误差会先减后增,训练误差 (train) (或者
?
\jmath
? 代价函数也可) 的曲线会一直递减。
我们找到两个曲线均小的点,这个点就是早终止的点。在这个点可以取得较好的性能,从而降低高方差
然而,这也是有缺点的。
这使得最优化的
?
\jmath
? 函数(或者梯度下降的最优解)与正则化减少方差的两个问题结合在了一起。使得不能单一解决其中一个问题,增加了复杂性。
提早中断了梯度下降,打断了
?
\jmath
? 的优化过程,没法用同一个工具解决两个问题。
但是这避免了正则化的缺点,大量的对
λ
\lambda
λ 的计算,减少了计算量。
归一化输入
零均值化
μ
=
1
m
∑
i
=
1
m
x
(
i
)
x
=
x
?
μ
\mu = \frac{1}{m}\sum_{i=1}^mx_{(i)}\\ x = x - \mu
μ=m1?i=1∑m?x(i)?x=x?μ
归一化方差
σ
2
=
1
m
∑
i
=
1
m
x
(
i
)
2
x
/
=
σ
\sigma^2 = \frac{1}{m}\sum_{i=1}^{m}x_{(i)}^2\\ x /= \sigma
σ2=m1?i=1∑m?x(i)2?x/=σ
为什么要归一化输入呢?我们看看归一化前后的结果
我们可以发现,归一化后的数据在梯度下降时候会更容易找到最优解,如果不进行归一化,会加大计算量,同时损失函数也会较复杂。即消除了数据特征之间的量纲影响,使得不同指标之间具有可比性,数据的更新速度将会变得一致,从而更容易更快通过梯度下降找到最优解,进而得到更精确的结果,便于分析。
梯度消失与梯度爆炸
梯度消失与梯度爆炸常常出现在较深的神经网络中,梯度消失与梯度爆炸的含义是,在训练时,损失函数的导数或者斜率有时候会变得特小或者特大
例如上图的神经网络,我们可以知道,输出
y
y
y 的值为:
y
=
w
[
l
]
?
w
[
l
?
1
]
?
?
w
[
1
]
x
y = w^{[l]}* w^{[l-1]}\cdots* w^{[1]}x
y=w[l]?w[l?1]??w[1]x 假设:
w
=
[
1.5
0
0
1.5
]
w = \begin{bmatrix} 1.5 & 0 \\ 0 & 1.5 \end{bmatrix}
w=[1.50?01.5?] 则
y
^
=
w
[
l
]
?
[
1.5
0
0
1.5
]
l
?
1
x
\hat y = w^{[l]}*\begin{bmatrix} 1.5 & 0 \\ 0 & 1.5 \end{bmatrix}^{l-1}x
y^?=w[l]?[1.50?01.5?]l?1x 在这样的情况下,
y
^
\hat y
y^? 的值会指数增长。损失函数的导数会特大。
同理,在
w
=
[
0.5
0
0
0.5
]
w = \begin{bmatrix} 0.5 & 0 \\ 0 & 0.5 \end{bmatrix}
w=[0.50?00.5?] 的情况下,损失函数的导数会特小。
那么如何解决这个问题?
我们需要使用更细致的随机初始化神经网络(初始化权重)
例如:
w[l] = np.random.randn(shape)*np.sqrt(1/n[l-1])
其中,
1
n
[
l
?
1
]
\frac{1}{n^{[l-1]}}
n[l?1]1? 中的
n
[
l
?
1
]
n^{[l-1]}
n[l?1] 为输入的每个神经元的特征数。因为每层神经网络的每个单元有
n
[
l
?
1
]
n^{[l-1]}
n[l?1] 个输入,而在这个例子中,有
n
n
n 个输入特征
需要注意的是,当使用
R
e
L
U
ReLU
ReLU 作为激活函数时,我们应该使用 np.sqrt(2/n[l-1])
当使用
t
a
n
h
tanh
tanh 时,有两种方案,任选一种即可:
梯度检验
梯度检验用于检验梯度反向传播的正确性
梯度的近似计算:
f
(
θ
+
ε
)
?
f
(
θ
?
ε
)
2
ε
≈
g
(
θ
)
\frac{f(\theta + \varepsilon)-f(\theta - \varepsilon)}{2\varepsilon}\approx g(\theta)
2εf(θ+ε)?f(θ?ε)?≈g(θ) 用双侧的差值计算更精确。
梯度检验具体来讲就是:
将
w
[
1
]
,
b
[
1
]
?
?
w
[
l
]
,
b
[
l
]
w^{[1]},b^{[1]} \cdots \cdots w^{[l]},b^{[l]}
w[1],b[1]??w[l],b[l] 连成一个向量
θ
\theta
θ
那么:
?
(
[
w
[
1
]
,
b
[
1
]
?
?
w
[
l
]
,
b
[
l
]
]
)
=
?
(
θ
)
\jmath([w^{[1]},b^{[1]} \cdots \cdots w^{[l]},b^{[l]}]) = \jmath(\theta)
?([w[1],b[1]??w[l],b[l]])=?(θ) 同理,将
d
w
[
1
]
,
d
b
[
1
]
?
?
d
w
[
l
]
,
d
b
[
l
]
dw^{[1]},db^{[1]} \cdots \cdots dw^{[l]},db^{[l]}
dw[1],db[1]??dw[l],db[l] 连成一个向量
d
θ
d \theta
dθ
d
θ
=
[
d
w
[
1
]
,
d
b
[
1
]
?
?
d
w
[
l
]
,
d
b
[
l
]
]
d \theta = [dw^{[1]},db^{[1]} \cdots \cdots dw^{[l]},db^{[l]}]
dθ=[dw[1],db[1]??dw[l],db[l]] 我们需要计算的是,
d
θ
d\theta
dθ 是
?
(
θ
)
\jmath(\theta)
?(θ) 的梯度或者斜率嘛?
由于
?
(
θ
)
=
?
(
θ
1
,
?
?
,
θ
l
)
\jmath(\theta) =\jmath(\theta_1 ,\cdots ,\theta_l)
?(θ)=?(θ1?,?,θl?) ,故我们要对每个
θ
\theta
θ 循环一次
对于每个
θ
i
\theta_{i}
θi?,我们有
d
θ
a
p
p
o
r
(
i
)
=
?
(
θ
1
,
?
θ
i
+
ε
,
?
?
)
?
?
(
θ
1
,
?
θ
i
?
ε
,
?
?
)
2
ε
d \theta_{appor(i)} = \frac{\jmath(\theta_1,\cdots \theta_i+\varepsilon,\cdots) - \jmath(\theta_1,\cdots \theta_i-\varepsilon,\cdots)}{2\varepsilon}
dθappor(i)?=2ε?(θ1?,?θi?+ε,?)??(θ1?,?θi??ε,?)? 而:
d
θ
(
i
)
=
?
?
?
θ
(
i
)
d\theta_{(i)} = \frac{\partial \jmath}{\partial \theta_{(i)}}
dθ(i)?=?θ(i)???? 接下来检查
d
θ
a
p
p
o
r
(
i
)
≈
d
θ
d \theta_{appor(i)} \approx d\theta
dθappor(i)?≈dθ 是否成立
我们计算它们的欧几里得距离,即两个向量的每个分量差的平方和再开方,看看结果是否大概为
1
0
?
7
10^{-7}
10?7。
∣
∣
d
θ
a
p
p
o
r
?
d
θ
∣
∣
2
∣
∣
d
θ
a
p
p
o
r
∣
∣
2
+
∣
∣
d
θ
∣
∣
2
≈
1
0
?
7
\frac{\lvert \lvert d\theta_appor - d\theta \lvert \lvert_2}{\lvert \lvert d\theta_{appor} \lvert\lvert_2+\lvert \lvert d\theta\lvert \lvert_2} \approx 10^{-7}
∣∣dθappor?∣∣2?+∣∣dθ∣∣2?∣∣dθa?ppor?dθ∣∣2??≈10?7 如果为
1
0
?
7
10^{-7}
10?7 那么梯度检验就通过了。
如果为
1
0
?
5
10^{-5}
10?5,那么需要好好检查一下,可能正确也有可能错误,检查每个分量。如果其中某个分量很大,就有可能出错了
如果为
1
0
?
3
10^{-3}
10?3,那么一定有错误,需要仔细检查
梯度检验的实用技巧
- 不要在训练中使用梯度检查,仅仅只在调试时使用,否则会严重影响训练速度,调试过后记得关掉
- 如果检验失败,仔细检查每一项去找出漏洞,仔细检查,差值大的可能有错误
- 如果使用了正则化,那么检验也需要正则化
- 梯度检验不要与 dropout 一起使用,可以设 dropout 的 keep.prob 为 1,即关掉 dropout 再检验
|