一、过拟合、欠拟合及其解决方案
过拟合:模型在训练集上取得的效果较好,误差较低,但是在训练集上出现较大误差
欠拟合:建立的模型在训练集和测试集上均出现较高的误差。
解决方案
1.模型复杂度
假设我们要预测的目标函数是个 y关于x的平方函数。
(1)我们在建立模型的时候 选择了 y关于x的一次函数,那么预测出来的效果可能会很差,这时候 会造成欠拟合。过于简单的模型会造成欠拟合
(2)如果我们选择了y关于x的三次函数,那么在预测的时候可能在训练集上会得到较好的预测结果,但是一用到测试集上,可能效果就非常差,这就是过拟合。过于复杂的模型会造成过拟合
所以我们在构建模型的时候不能过于简单和复杂
2.权重衰减
也是我们说的正则化,有L2范数正则化,L1范数正则化等。
正则化通过为模型损失函数添加惩罚项使学出的模型参数值较小,是应对过拟合的常用手段。
L2范数是 对模型里每个权重参数的平方进行加总乘以一个正常数,这个常数是一个超参数
但常数接近于0时,表示施加的惩罚很小,对前面的模型影响不大。正常数越大对模型影响也越大。
而L1范数 则是在L2范数的情况上开根号
这里复习一下pytorch的简洁拟合:
w = torch.randn((num_inputs, 1), requires_grad = True)
b = torch.zeros(1, require_grad=True)
optim = nn.optimizer.SGD(lr=0.03)
for epoch in epochs:
for x,y in data:
y_hat = nn.Linear(x) ##写错了
l = nn.MSELoss(y_hat, y)
if w.grad is not None:
w.grad.data.zero_()
b.grad.data.zero_()
l.backward()
optim.step()
3.Dropout
在多层感知器中,我们对每个隐藏层的神经单元都做了全连接,使得数据生成要基于所有隐藏神经单元,这有可能会造成过拟合.所以我们在训练层上进行模拟的时候,每次的训练都会随机丢弃几个隐藏层里的神经单元,使得模型不过过度依赖某个神经单元.
二、梯度消失和爆炸
当我们构建的神经网络层数比较多的时候,我们的函数就会嵌套很多层.假设输入和所有层的权重参数都是标量,如权重参数为0.2和5,多层感知机的第30层输出为输入X分别与0.230(消失)和530(爆炸)的乘积。
我们通过梯度裁剪和选用relu等激活函数,对梯度消失和爆炸有一定抑制作用
对于循环神经网络 可以通过LSTM和GRU的设计等
三、循环神经网络进阶
LSTM/GRU/双向/深层
LSTM
图片源自https://zhuanlan.zhihu.com/p/32085405
LSTM主要原理就是在进行预测的时候,我们预测公式应该对邻近的话语(也就是短期记忆)和相隔较远的词语(长期记忆)有不同的权重影响,这样才能更贴合人类思维模式,而不是对含有前面所有信息的隐藏状态进行同等对待.
lstm不同于RNN. 在原有的隐藏状态下新增一个记忆细胞C,
C
t
C_t
Ct的状态是对上个
C
t
−
1
C_{t-1}
Ct−1加上一些数值。所以状态会改变的比较慢,作为长期记忆细胞.而
h
h
h每次状态改变比较大,我们可以作为短期记忆细胞.
这里我们引入四个新的数据
z
f
z^f
zf,
z
i
z^i
zi,
z
z
z,
z
o
z^o
zo, 这四个数据都是基于 当前输入
x
t
x^t
xt和上个隐藏状态
h
t
−
1
h^{t-1}
ht−1进行矩阵拼接之后做的函数变换.其中每个参数w和b都需要学习. 其中
z
z
z代表输入数据,而不是控制的开关
lstm三个主要阶段:
1.忘记阶段.对上个节点传进来的输入进行选择性忘记.“忘记不重要,记住重要的”.通过 z f z^f zf作为遗忘的权重系数乘以 c t − 1 c_{t-1} ct−1,来控制那些需要遗忘,那些需要留下.
2.选择记忆阶段.这个阶段我们将输入进行有选择的记忆,这次我们选择 z i z^i zi作为记忆权重系数乘以 z z z.
3.输出阶段。这个阶段将决定哪些将会被当成当前状态的输出。我们先将1.2两步的信息加总生成 c t c_t ct(并通过通过一个tanh激活函数进行变化).再通过 z o z^o zo 来进行控制的。生成 h t h_t ht.
-------引用自 https://zhuanlan.zhihu.com/p/32085405
GRU
图片来自 https://zhuanlan.zhihu.com/p/32481747
有了LSTM之后我们发现,需要求的系数有点多,计算速度偏慢,这时候又诞生一个新的模型就是GRU,在LSTM的基础上,缩减了参数个数,使得能得到差不多的效果但是更易于计算
这里我们有三个中间数据
r
r
r ,
z
z
z,
h
′
h'
h′ 分别是 重置门, 更新门, 和输入数据.
1.我们先使用 r r r乘以 h t − 1 h^{t-1} ht−1 生成一个新的 h t − 1 ′ h^{t-1'} ht−1′,也就是 重置上个隐藏状态
2.再有当前输入x和重置隐藏状态 h t − 1 ′ h^{t-1'} ht−1′ 通过tanh生成 h ′ h' h′ (先重置上个隐藏状态,在于当前x concat生成新状态)
3.最后我们 更新记忆,在这个阶段,我们同时进行了遗忘了记忆两个步骤。我们使用了先前得到的更新门控 z z z,
h t h^t ht = z * h t − 1 h^{t-1} ht−1 + (1-z) * h ′ h' h′
-------引用自 https://zhuanlan.zhihu.com/p/32085405