赞
踩
1 先要解决偏差问题,当偏差解决以后再考虑方差问题。
2 当进行方差操作以后,一定要再次测试新的策略的会不会再次导致偏差问题, 也就是当解决了过拟合操作以后,一定要再次测试一下会不会欠拟合
减小偏差
减小方差
先设计逻辑回归,然后一点点增加隐藏层的数量。
在深度学习中,模型的核心组成可以包括以下几个方面:
层数(Layers):深度神经网络由多层神经元组成,包括输入层、隐藏层和输出层,但是在计算层数的时候不包括输入层。
在计算的时候,一般使用 L L L 或者 l l l 来所在表示层的位置。
神经元数(Neurons):每一层中的神经元数,也决定了该层的复杂度。
用 n n n来表示神经元的数量,第 l l l 层的神经元表示为 n [ l ] n^{[l]} n[l]
线性函数(Linear Functions):提供基本的线性函数计算。
公式为 z = W x + b z=Wx+b z=Wx+b,第 l l l 层的线性函数为 z [ l ] = W [ l ] a [ l − 1 ] + b [ l ] z^{[l]}=W^{[l]}a^{[l-1]}+b^{[l]} z[l]=W[l]a[l−1]+b[l], a [ l − 1 ] a^{[l-1]} a[l−1]为前一层的激活值,对于第一层来说 a [ l − 1 ] a^{[l-1]} a[l−1]是输入层。
a i [ l ] a^{[l]}_i ai[l]表示第 l l l 层的第 i i i 个神经元的激活值
激活函数(Activation Functions) 转换线性函数到非线性,如ReLU、sigmoid、tanh等,用于引入非线性,使模型能够学习复杂的模式。
公式为 a [ l ] = g ( z [ l ] ) a^{[l]}=g(z^{[l]}) a[l]=g(z[l]),激活函数统一用 g g g 表示,激活值为 a a a,但是具体的算法则不一样。
σ
(
x
)
=
1
1
+
e
−
x
\sigma(x) = \frac{1}{1 + e^{-x}}
σ(x)=1+e−x1
导数公式:
d
σ
(
z
[
l
]
)
d
z
[
l
]
=
a
[
l
]
(
1
−
a
[
l
]
)
\frac{d \sigma(z^{[l]})}{dz^{[l]}} = a^{[l]} (1 - a^{[l]})
dz[l]dσ(z[l])=a[l](1−a[l])
ReLU
(
x
)
=
max
(
0
,
x
)
\text{ReLU}(x) = \max(0, x)
ReLU(x)=max(0,x)
导数公式:
d
ReLU
(
z
[
l
]
)
d
z
[
l
]
=
{
1
if
z
[
l
]
>
0
0
if
z
[
l
]
≤
0
\frac{d \text{ReLU}(z^{[l]})}{dz^{[l]}} =
tanh
(
x
)
=
e
x
−
e
−
x
e
x
+
e
−
x
\tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}
tanh(x)=ex+e−xex−e−x
导数公式:
d
tanh
(
z
[
l
]
)
d
z
[
l
]
=
1
−
(
a
[
l
]
)
2
\frac{d \tanh(z^{[l]})}{dz^{[l]}} = 1 - (a^{[l]})^2
dz[l]dtanh(z[l])=1−(a[l])2
tanh
′
(
x
)
=
1
−
tanh
2
(
x
)
\tanh'(x) = 1 - \tanh^2(x)
tanh′(x)=1−tanh2(x)
训练集的作用是为了学习数据的特征和模式,使模型能够对输入数据进行准确的预测。
主要的任务是获得学习到的 “模型”,也就是
W
W
W 和
b
b
b 的值。
在使用训练集获得了模型,即确定了 W W W 和 b b b 的值以后使用开发集来测试==超参数==调优,例如学习率、正则化系数等。
检测最终的模型的性能,用于最终评估模型性能的数据集。
偏差是指模型预测值与真实值之间的差异。
高偏差表示模型在训练数据和测试数据上的预测都较差,即模型欠拟合(underfitting)。偏差高的模型通常过于简单,无法捕捉数据中的复杂模式。
特征:
方差是指模型对训练数据中随机噪声的敏感程度。
高方差表示模型在训练数据上表现很好,但在测试数据上表现较差,即模型过拟合(overfitting)。方差高的模型通常过于复杂,只记住训练数据中的噪声,但无法泛化到新的数据。
特征:
偏差和方差之间存在权衡关系,即在降低偏差的同时可能会增加方差,反之亦然。理想情况下,模型应当在偏差和方差之间找到一个平衡点,以确保其在训练数据和测试数据上都能有较好的表现。
高偏差、低方差:
低偏差、高方差:
适中偏差、适中方差:
先要解决偏差问题,当偏差解决以后再考虑方差问题。
当进行方差操作以后,一定要再次测试新的策略的会不会再次导致偏差问题
减小偏差
减小方差
正则化就是利用一些手段,在模型训练解决解决模型过拟合、提高范化能力等问题。
不同的方法作用的阶段不同。
不过这之前需要明白一个概念:重要特征和最高权重
PS:以下全为个人抽象理解,未来有极大概率修改这段话,切勿照本宣科。
在深度学习中,重要特征指的是“对预测影响较大”的特征值。
假设样本X有俩个特征:x1为0.9,x2为0.1
如果此时标签Y是1,那么x1就是重要特征,如果标签为0,那么x2就是重要特征。
虽然最后的关于特征的表示,是特征*权重,但是权重的值一般都比较小,类似0.01
即使一开始给非重要特征设置了高权重,在一次次优化中(类似梯度下降)非重要特征的权重也会变低,重要特征的权重会变高。
所以,从结果导向来看:重要特征就是权重高的特征,非重要特征就是权重低的特征
J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ i , y i ) + λ m ∑ ℓ = 1 L ∥ ω [ ℓ ] ∥ J(w, b) = \frac{1}{m} \sum_{i=1}^m L(\hat y^{i},y^{i})+ \frac{\lambda}{m} \sum_{\ell=1}^L \|\omega^{[\ell]}\| J(w,b)=m1i=1∑mL(y^i,yi)+mλℓ=1∑L∥ω[ℓ]∥
d ω [ ℓ ] = d J d ω [ ℓ ] + λ m sign ( ω [ ℓ ] ) \text{d}\omega^{[\ell]} = \frac{d J}{d \omega^{[\ell]}} + \frac{\lambda}{m} \text{sign}(\omega^{[\ell]}) dω[ℓ]=dω[ℓ]dJ+mλsign(ω[ℓ])
解析:简单来说Lasso正则化就是在原有的损失函数上增加了一个 λ \lambda λ 倍的权重的方差,这样会导致如下的结果:
1:由于增加的内容基于权重的值,对于大权重的特征来说,损失会增大,所以下一次更新的时候权重会被减少很多。
2:对于小权重的特征来说,损失也会增大,但也没有那么大,所以下一次更新的时候权重会减少但是没有很多。
抽象举例,假设:大权重为100,小权重为1
这样操作以后,下一次更新也许大权重会变为 1 , 减少了99,也许小权重会变为 0.1,减少了 0.9。
虽然大权重变少了很多,但是还是比小权重高,所以对于模型来说,大权重的特征的重要性还是比小权重的特征的重要性要高。
为什么降低特征的权重可以减少过拟合呢?
因为可以减少对个别特征的过度依赖。泛化能力不足往往与模型对个别特征的过度依赖有关
此外,降低权重还有另外作用,减小非重要特征的影响力–权重被趋近于0。减小网络复杂度
对第一层来说,减小的是输入的特征的权重,优化的是输入样本的特征。
但是对于深度网络的其它层来说,减小是上一层的输出的权重,优化的则是上一层神经网络
L1正则化前:
L1正则化后:
J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ i , y i ) + λ 2 m ∑ j = 1 n w j 2 J(w, b) = \frac{1}{m} \sum_{i=1}^m L(\hat y^{i},y^{i})+ \frac{\lambda}{2m}\sum_{j=1}^n w_j^2 J(w,b)=m1i=1∑mL(y^i,yi)+2mλj=1∑nwj2
d ω [ ℓ ] = d J d ω [ ℓ ] + λ m ω [ ℓ ] \text{d}\omega^{[\ell]} = \frac{d J}{d \omega^{[\ell]}} + \frac{\lambda}{m} \omega^{[\ell]} dω[ℓ]=dω[ℓ]dJ+mλω[ℓ]
原理于L1类似,差异如下:
区别
对异常值的敏感度
解的唯一性
应用场景
选择L1还是L2正则化通常取决于具体问题的需求和数据的特性。
例如,如果你需要一个简化的模型来解释模型是如何做出决策的(特征选择),L1可能是更好的选择。
如果你需要确保模型的所有参数都小一些,从而增强模型的泛化能力,那么L2可能是更合适的选择。同时L2也是最常用的正则化手段。
在实践中,也可以同时使用L1和L2正则化,这种组合被称为弹性网(Elastic Net)正则化。
Dropout正则化不能用于测试阶段!!Dropout正则化不能用于测试阶段!!
相较于L1和L2利用损失函数来间接的弱化一些不重要的神经元。
Dropout 的核心思想更直接,就是在每次训练迭代中,随机将一些神经元的激活值 a a a 设置为零,每次训练设置的神经元都不同。
Dropout 丢弃的不是神经元,丢弃的是当前个别神经元对于样本的预测,
或者说丢弃的是当前层某一个神经元对于原始输入样本的预测,每次训练迭代中丢的都不一样。
这个过程涉及到公式不明朗(在我看来是这样…)所以在此直接记录完成的代码。
# A的维度(当前神经元个数,样本的个数) # A3:存放第三层的5个神经元对于最开始输入的10个样本的预测 A3 = np.random.randn(5, 10) # 开始 # 1.设置 keep_prob 为 0.8 (即有 0.2 的概率舍弃) keep_prob = 0.8 #概率为1-keep_prob # 2.设计一个和A3形状一样的随机数矩阵 D3 = np.random.rand(a3.shape[0], a3.shape[1]) # 这里用的是rand,在[0,1) 之间取值 D3 = D3 < keep_prob #用True 和 False 随机填充 D3 # 3.利用随机矩阵的True 和 False随机丢弃 A3中的值 A3 = A3 * D3 #True == 1 / False == 0 # 4.扩大A3的值 A3 = A3/keep_prob #因为有(1-keep_prob)也就是20%,的值被舍弃了,所以扩大20%。 # A3= A3 /(8/10) # A3= A3 *(10/8)
其实我还是有点不理解第4步,不过先这样记着吧。
此外, Dropout正则化的设置比较灵活,对于重要的层,比如最后的输出层,我们也可以不用 Dropout,把 keep_prob 设置为1。
简单来说就是修改当前有的数据集为新数据。
举例数据集数据为图片,那么就可以水平反转图片、裁切图片、图片轻微扭曲。
简单来说,就是在测试寻找超参数(迭代次数、学习率等)的时候,找一个对于验证集来说损失最低的
W
W
W和
b
b
b, 即使这个
W
W
W和
b
b
b不是对于训练集的损失最低。
除了正则化以外,一些对于设置的优化方式,也可以帮助建立更好的模型,主要有以下几点。
目的:可以将数据聚合到以0为原点,的方差标准化为 1。
公式:
第一步,获得输入的均值:
μ
=
1
m
∑
i
=
1
m
x
(
i
)
\mu = \frac{1}{m} \sum_{i=1}^{m} x^{(i)}
μ=m1i=1∑mx(i)
第二步,计算方差:
σ
2
=
1
m
∑
i
=
1
m
(
x
(
i
)
−
μ
)
2
\sigma^2 = \frac{1}{m} \sum_{i=1}^{m} (x^{(i)} - \mu)^2
σ2=m1i=1∑m(x(i)−μ)2
于是标准差:
σ
=
1
m
∑
i
=
1
m
(
x
(
i
)
−
μ
)
2
\sigma = \sqrt{\frac{1}{m} \sum_{i=1}^{m} (x^{(i)} - \mu)^2}
σ=m1i=1∑m(x(i)−μ)2
第三步,最终的标准化数据:
x
′
=
x
−
μ
σ
x' = \frac{x - \mu}{\sigma}
x′=σx−μ
通过输入Normalizing化,可以让特征分布的更均匀,损失函数图形更像一个碗,更容易梯度下降。
防止梯度爆炸/梯度消失,主要是因为对于深层的神经网络,如果用统一的方式初始化 W 矩阵,W的初始值都相同。
在后续涉及到 W 乘法操作中可能会导致 W 过大或者过小,继而导致 Z 过大或者过小。
所以我们需要优化W的初始化,即对不同的层用不同的W初始化函数
对于不同的激活函数,初始化的方法也不一样
WL=np.random.rand(shape) * np.sqrt( 2.0 / 前一层的神经元个数) # np.sqrt( 2 / n[l-1])
# W的形状为(n[l], n[l-1]),n[l]为当前神经元个数; n[l-1]为前一层的神经元个数
WL=np.random.rand(shape) * np.sqrt( 1.0 / 前一层的神经元个数) # np.sqrt( 2 / n[l-1])
# W的形状为(n[l], n[l-1]),n[l]为当前神经元个数; n[l-1]为前一层的神经元个数
也有第二个版本
WL=np.random.rand(shape) * np.sqrt( 2.0 / (前一层的神经元个数)+(当前层的神经元个数)) # np.sqrt( 2 / n[l-1])
# W的形状为(n[l], n[l-1]),n[l]为当前神经元个数; n[l-1]为前一层的神经元个数
当模型出现一些问题的时候,我们需要逐一排查,其中一个很重要的部分是对 “梯度下降算法”和“反向传播”的检查,要进行梯度检查,必须要考虑下面这三点:
梯度检查的核心来源于中心差分公式:
f
′
(
x
)
≈
f
(
x
+
h
)
−
f
(
x
−
h
)
2
h
f'(x) \approx \frac{f(x + h) - f(x - h)}{2h}
f′(x)≈2hf(x+h)−f(x−h)
函数
f
(
x
)在
x
的点导数
≈
f
(
x
+
一个微小的偏量
)
−
f
(
x
−
一个微小的偏量
)
2
∗
一个微小的偏量
函数f(x)在x的点导数\approx \frac{f(x + 一个微小的偏量) - f(x -一个微小的偏量)}{2 * 一个微小的偏量}
函数f(x)在x的点导数≈2∗一个微小的偏量f(x+一个微小的偏量)−f(x−一个微小的偏量)
不过,这个方法有一个必要的前提条件,
那就是 h h h, 这个移动的标量必须是一个极小值,类似 1 0 − 7 . 所得到的误差一般为 h 2 10^{-7}. 所得到的误差一般为h^2 10−7.所得到的误差一般为h2
# θ ={w1,b1,w2,b2....wl,bl}
theta=np.concatenate([w1.flatten(),b1 , w2.flatten(),b2 , w3.flatten(),b3 , .....)}
for i = L:
dθ = (J(θ1,θ2,θ3.....θi+h,...,θL)-J(θ1,θ2,θ3.....θi-h,...,θL)) / 2h
relative error = ∥ d θ − grad analytic ∥ ∥ d θ ∥ + ∥ grad analytic ∥ \text{relative error} = \frac{\left\| dθ - \text{grad}_{\text{analytic}} \right\|}{\left\| dθ \right\| + \left\| \text{grad}_{\text{analytic}} \right\|} relative error=∥dθ∥+ gradanalytic dθ−gradanalytic
这个移动的标量必须是一个极小值,类似 1 0 − 7 10^{-7} 10−7
如果 h h h 是 1 0 − 7 10^{-7} 10−7 ,那么relative error的值应该在 1 0 − 5 10^{-5} 10−5 到 1 0 − 9 10^{-9} 10−9 之间,否则为异常。
在Python中,特别是在涉及到科学计算和数据处理的库NumPy中,randn
和rand
函数都用来生成随机数,但它们的用途和输出的随机数类型有所不同:
numpy.random.randn
:
randn
函数生成的是服从标准正态分布(均值为0,方差为1的正态分布)的随机数。np.random.randn(2, 3)
会生成一个2行3列的数组,数组中的每个元素都是从标准正态分布中随机抽取的。numpy.random.rand
:
rand
函数生成的是在区间[0, 1)内均匀分布的随机数。np.random.rand(2, 3)
会生成一个2行3列的数组,数组中的每个元素都是从[0, 1)区间的均匀分布中随机抽取的。简而言之,主要区别在于:
randn
用于生成符合标准正态分布的随机数。rand
用于生成符合均匀分布的随机数。具体到应用:
初始化权重矩阵:randn
Dropout正则化:rand
flatten
操作通常用于将多维数组(如矩阵或张量)变为一维数组(向量)
import numpy as np
a=np.random.rand(3,3)
print (a)
# [[0.81326486 0.08026124 0.38529666]
# [0.26521685 0.2712353 0.37634291]
# [0.70843229 0.34048282 0.32902673]]
a=a.flatten()
print(a)
#[0.81326486 0.08026124 0.38529666 0.26521685 0.2712353 0.37634291 0.70843229 0.34048282 0.32902673]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。