过拟合(over-fitting)其实就是所建的机器学习模型或者是深度学习模型在训练样本中表现得过于优越,导致在验证数据集以及测试数据集中表现不佳。
欠拟合(under-fitting),训练样本被提取的特征比较少,导致训练出来的模型不能很好地匹配,表现得很差,甚至样本本身都无法高效的识别。
抑制过拟合
过拟合的原因有可以归结为:参数过多
1、定义的损失函数后面加入一项永不为0的部分,那么最后经过不断优化损失函数还是会存在。其实这就是所谓的“正则化”。
image.png
def l2_normalize(x, axis=None):
square_sum = T.sum(T.square(x), axis=axis, keepdims=True)
norm = T.sqrt(T.maximum(square_sum, epsilon()))
return x / norm
2、dropout :dropout的思想是当一组参数经过某一层神经元的时候,去掉这一层上的一部分神经元,让参数只经过一部分神经元进行计算。注意这里的去掉并不是真正意义上的去除,只是让参数不经过一部分神经元计算而已。
在2012年,Alex、Hinton在其论文《ImageNet Classification with Deep Convolutional Neural Networks》中用到了Dropout算法,用于防止过拟合。
image.png
正常的流程是:我们首先把x通过网络前向传播,然后把误差反向传播以决定如何更新参数让网络进行学习。
image.png
- dropout
首先随机(临时)删掉网络中一半的隐藏神经元,输入输出神经元保持不变
然后把输入x通过修改后的网络前向传播,然后把得到的损失结果通过修改的网络反向传播。一小批训练样本执行完这个过程后,在没有被删除的神经元上按照随机梯度下降法更新对应的参数(w,b)。
然后继续重复这一过程:
. 恢复被删掉的神经元(此时被删除的神经元保持原样,而没有被删除的神经元已经有所更新). 从隐藏层神经元中随机选择一个一半大小的子集临时删除掉(备份被删除神经元的参数)。. 对一小批训练样本,先前向传播然后反向传播损失并根据随机梯度下降法更新参数(w,b) (没有被删除的那一部分参数得到更新,删除的神经元参数保持被删除前的结果)。
- 更新过程
Dropout说的简单一点就是我们让在前向传导的时候,让某个神经元的激活值以一定的概率p,让其停止工作。
更简单一点:按伯努利分布丢弃,并保持期望不变。
代码层面实现让某个神经元以概率p停止工作,其实就是让它的激活函数值以概率p变为0。比如我们某一层网络神经元的个数为1000个,其激活函数输出值为y1、y2、y3、......、y1000,我们dropout比率选择0.4,那么这一层神经元经过dropout后,1000个神经元中会有大约400个的值被置为0。之后, rescale,也就是乘以1/(1-p)
def dropout(x, level, noise_shape=None, seed=None):
"""Sets entries in `x` to zero at random,
while scaling the entire tensor.
# Arguments
x: tensor
level: fraction of the entries in the tensor
that will be set to 0.
noise_shape: shape for randomly generated keep/drop flags,
must be broadcastable to the shape of `x`
seed: random seed to ensure determinism.
"""
if level < 0. or level >= 1:
raise ValueError('Dropout level must be in interval [0, 1[.')
if seed is None:
seed = np.random.randint(1, 10e6)
if isinstance(noise_shape, list):
noise_shape = tuple(noise_shape)
rng = RandomStreams(seed=seed)
retain_prob = 1. - level
if noise_shape is None:
random_tensor = rng.binomial(x.shape, p=retain_prob, dtype=x.dtype)
else:
random_tensor = rng.binomial(noise_shape, p=retain_prob, dtype=x.dtype) #生成一个0、1分布的向量,0表示这个神经元被屏蔽,不工作了,也就是dropout了
random_tensor = T.patternbroadcast(random_tensor,
[dim == 1 for dim in noise_shape])
x *= random_tensor
x /= retain_prob #rescale
return x
why rescale?
dropout做rescale主要保证了神经元的期望均值与无dropout时一致,但未保证期望方差(标准差)一致。方差会产生一个与dropout系数p相关的偏移
结合资料理解下 https://cs231n.github.io/neural-networks-2/#reg
- 两种dropout
image.png
rescale rate = 1 / (1 - dropout rate) ,克服测试中没有使用dropout所带来的副作用
https://www.zhihu.com/question/61751133
3、 减少网络深度:随着网路深度的增加,同时参数也不断增加,并且增加速度、规模都很大,容易过拟合
参考:https://blog.csdn.net/hjimce/article/details/50413257
网友评论