前言:
前面讲了Overfitted,这里重点讲解一下如何防止
Overfitting ,以及其中的方案之一 Regularization
模型的参数量,模型的表达能力远超模型本身复杂度.
与之对应的是奥卡姆剃刀原理:
如何用最简单的方法得到最好的效果
找到关键的部分,简单灵活地去处理,你会发现,成功并不那么复杂。
目录:
1 more data
2: constraint model complexity
3 Dropout
4 data argumentation
5 Early Stopping
6 Regularization
一: More data
增加Train Data 数据集大小
有的时候,我们项目中没有办法获得那么大的数据集,
这个时候可以通过Gain 或者编码器 合成数据集,达到增加数据集容量
二 constraint model complexity(限制模型复杂度)
2.1 shallow:
单隐藏层神经网络就是典型的浅层(shallow)神经网络,即只包含一层隐含层
2.2 regularization
正规化 分为L1 正规化,和L2 正规化
在机器学习里面是一种最常用的方案
三 Dropout
dropout(随机失活):dropout是通过遍历神经网络每一层的节点,然后通过对该层的神经网络设置一个keep_prob(节点保留概率),即该层的节点有keep_prob的概率被保留,keep_prob的取值范围在0到1之间。通过设置神经网络该层节点的保留概率,使得神经网络不会去偏向于某一个节点(因为该节点有可能被删除),从而使得每一个节点的权重不会过大,有点类似于L2正则化,来减轻神经网络的过拟合。
1 首先随机(临时)删掉网络中一半的隐藏神经元(以dropout rate为0.5为例),输入输出神经元保持不变
2 然后把输入x 通过修改后的网络前向传播,然后把得到的损失结果通过修改的网络反向传播。一 小批(这里的批次batch_size由自己设定)训练样本执行完这个过程后,在没有被删除的神经元()上按照随机梯度下降法更新对应的参数(w,b)
重复以下过程:
sub-1、恢复被删掉的神经元()(此时被删除的神经元保持原样,而没有被删除的神经元已经有所更新),因此每一个mini- batch都在训练不同的网络。
sub-2、从隐藏层神经元中随机选择一个一半大小的子集临时删除掉(备份被删除神经元的参数)。
sub-3、对一小批训练样本,先前向传播然后反向传播损失并根据随机梯度下降法更新参数(w,b) (没有被删除的那一部分参数得到更新,删除的神经元参数保持被删除前的结果)。
四 data argumentation
数据增强,这在图像处理里面常用
随机旋转一般情况下是对输入图像随机旋转[0,360) |
随机裁剪是对输入图像随机切割掉一部分 |
色彩抖动指的是在颜色空间如RGB中,每个通道随机抖动一定的程度。 |
是指在图像中随机加入少量的噪声。该方法对防止过拟合比较有效 |
水平翻转 |
竖直翻转 |
五 Early Stopping
使用Validation Data 做一个提前终止
六 Regularization
正规化有两种,一种是L1 正规化(有降维的效果)
另一种是L2正规化
对于L2 正规化有默认的参数可以直接配置
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 26 16:56:05 2023
@author: chengxf2
"""
import torch
from torch import optim
from torch import nn
# 先定义一个三层感知机,激活函数使用Relu(小于0的,都转换为0)
class MLP(nn.Module):
def __init__(self, in_dim, hid_dim1, hid_dim2, out_dim):
super(MLP, self).__init__()
#使用Sequential快速搭建三层感知机
self.layer = nn.Sequential(
# 第一层
nn.Linear(in_dim, hid_dim1),
nn.ReLU(),
nn.Linear(hid_dim1, hid_dim2),
nn.ReLU(),
nn.Linear(hid_dim2, out_dim),
nn.ReLU()
)
def forward(self, x):
y = self.layer(x)
return y
def train():
print("\n step1 init model")
learning_rate =1e-3
net =MLP(28*28, 300, 200, 10)
optimizer = optim.SGD(net.parameters(),lr =learning_rate, weight_decay=0.01) #L2正规化
criteon = nn.CrossEntropyLoss()
print("\n step2 forward")
data = torch.randn(10, 28*28)
output = net(data)
label = torch.Tensor([1, 0, 4, 7, 9, 3, 4, 5, 3, 2]).long()
print("\n step3 backward")
loss = criteon(output, label)
# 清空梯度,在每次优化前都要进行此操作
optimizer.zero_grad()
# 损失的反向传播
loss.backward()
# 利用优化器进行梯度更新
optimizer.step()
if __name__ == "__main__":
train()
针对L1 正规化,PyTorch 需要自己实现,方案如下
# -*- coding: utf-8 -*-
"""
Created on Thu Apr 27 15:23:56 2023
@author: chengxf2
"""
import torch
from torch import optim
from torch import nn
# 先定义一个三层感知机,激活函数使用Relu(小于0的,都转换为0)
class MLP(nn.Module):
def __init__(self, in_dim, hid_dim1, hid_dim2, out_dim):
super(MLP, self).__init__()
#使用Sequential快速搭建三层感知机
self.layer = nn.Sequential(
# 第一层
nn.Linear(in_dim, hid_dim1),
nn.ReLU(),
nn.Linear(hid_dim1, hid_dim2),
nn.ReLU(),
nn.Linear(hid_dim2, out_dim),
nn.ReLU()
)
def forward(self, x):
y = self.layer(x)
return y
net =MLP(100, 50, 25, 10)
optimizer = optim.SGD(net.parameters(),lr=1e-3)
regularization_loss = 0.0
criteon = nn.CrossEntropyLoss()
for param in net.parameters():
L1= torch.abs(param)
regularization_loss +=L1
data = torch.randn(10, 28*28)
logits = net(data)
target = torch.Tensor([1, 0, 4, 7, 9, 3, 4, 5, 3, 2]).long()
classify_loss = criteon(logits, target)
loss = classify_loss+0.01*regularization_loss
optimizer.zero_grad()
loss.backward()
optimizer.step()
参考
Dropout的深入理解(基础介绍、模型描述、原理深入、代码实现以及变种)_dropout模型_ㄣ知冷煖★的博客-CSDN博客
数据增强(Data Argumentation)_左小田^O^的博客-CSDN博客