31,32,33_过拟合、欠拟合的概念、L2正则化,Pytorch过拟合欠拟合,交叉验证-Train-Val-Test划分,划分训练集和测试集,K-fold,Regularization
1.26.过拟合、欠拟合及其解决方案
1.26.1.过拟合、欠拟合的概念
1.26.1.1.训练误差和泛化误差
1.26.1.2.验证数据集与K-fold验证
1.26.1.3.过拟合和欠拟合
1.26.1.4.导致过拟合和欠拟合的关键因素
1.26.2.L2正则化
1.26.3.drop out
1.27.Pytorch过拟合&欠拟合
1.27.1.理想化情况
1.27.1.1.场景一:线性模型—房价预测
1.27.1.2.场景二:非线性模型—GPA
1.27.2.真实情况
1.27.3.模型学习能力
1.27.4.欠拟合与过拟合
1.28.Train-Val-Test划分
1.28.1.1.How to detect(如何检测)
1.28.1.2.Splitting(划分训练集和测试集)
1.28.1.3.for example
1.28.1.4.test while train
1.28.1.5.train test trade-off
1.28.1.6.for others judge
1.28.1.7.train-val-test
1.28.1.8.K-fold cross-validation
1.28.1.9.k-fold cross validation
1.26.过拟合、欠拟合及其解决方案
1.26.1.过拟合、欠拟合的概念
1.26.1.1.训练误差和泛化误差
前者指模型在训练数据集上表现出的误差,后者模型在任意一个测试数据样本上表现的误差的期望,并常常通过测试数据集上的误差来近似。
1.26.1.2.验证数据集与K-fold验证
预留一部分在训练数据集和测试数据集以外的数据来进行模型选择,这部分数据被称为验证数据集,简称验证集(validation set)。在K折交叉验证中,把原始训练数据集分割成K个不重合的子数据集,然后做K次模型训练和验证。每一次,使用一个子数据集验证模型,并使用其他K-1个子数据集来训练模型。在这K次训练和验证中,每次用来验证模型的子数据集都不同。最后,对这K次训练误差和验证误差分别求平均。
1.26.1.3.过拟合和欠拟合
欠拟合:模型无法得到较低的训练误差。
过拟合:模型的训练误差远小于它在测试数据集上的误差。
1.26.1.4.导致过拟合和欠拟合的关键因素
数据集大小:影响欠拟合和过拟合的另一个重要因素是训练数据集的大小。一般来说,如果训练数据集中样本数过少,特别是比模型参数数量(按元素计)更少时,过拟合更容易发生。此外,泛化误差不会随训练数据集里样本数量增加而减小。因此,在计算资源允许的范围之内,通常希望训练数据集大一些,特别是在模型复杂度较高时,例如层数较多的深度学习模型。
模型复杂程度:
1.26.2.L2正则化
1.26.3.drop out
1.27.Pytorch过拟合&欠拟合
1.27.1.理想化情况
1.27.1.1.场景一:线性模型—房价预测
横坐标是房屋面积,纵坐标是房屋价格。可以看出这两者呈现线性关系。
1.27.1.2.场景二:非线性模型—GPA
老师给学生打分时,往往大部分学生一般的成绩,成绩差或成绩好的则占少数。因此总体上趋近于高斯模型,呈现非线性关系。
1.27.2.真实情况
从以上两个例子中,我们都已经提前知道了问题中的具体模型,不知道的只有模型的参数,如期望,方差。然而在现实生活中,大部分要解决的问题是不知道具体模型的。如手写数字识别,我们既不知道它的模型,也不知道里面需要包含什么参数。那么如何解决这个问题呢?
另外我们还要考虑另一个因素的影响:噪声。并不是所有的数据集都是严格按照模型的。如房价关系的线性模型,房价与面积在呈线性关系的同时往往有些许误差。我们可以认为误差服从高斯分布,因此为了尽量减少误差的影响,我们需要大量的数据集来训练模型。同时,如果数据集太少,可能被误认为不满足线性关系,而采用其他关系进行预测。
1.27.3.模型学习能力
我们对利用数据训练模型时,往往会选择不同的模型,可能一次方,二次方。。。到n次方,不同类型,不同次方的模型,次方越高,模型波动越大越复杂。
那么如何衡量不同模型的学习能力?
可以看出,只有一个参数的常数函数,学习能力最差,输出的是固定值,随着次方增加,参数越来越多,学习能力越来越强。
最近的深度学习网络层次越来越深,参数也越来越大,也从侧面反映出模型的model capacity越来越强。
1.27.4.欠拟合与过拟合
接下来我们观察两种情况:
情况一:欠拟合
我们用的模型复杂度小于真实数据模型的复杂度,就好像利用线性模型去预测非线性模型的GPA函数。这种情况会造成模型的表达能力不够,无法表达真实数据模型,这种情况叫做欠拟合。
再举一个WGAN的例子,早期的WGAN对模型加了许多约束,导致生成的数据表达能力不够强,上面三幅图无法像下面三幅图一样表达许多精美的图片。
那么欠拟合如何体现出来,我们如何发现模型出现欠拟合?
训练集准确度低
测试集准确度低
情景二:过拟合
我们训练出的模型为了拟合所有数据变得过分复杂,为了降低loss,模型趋近于每一个点,训练模型复杂度大于真实数据集复杂度,这样会导致在训练集上的效果非常好,但是在测试集上的效果不好,这种情况叫做过拟合。
那么过拟合如何体现出来,我们如何发现模型出现过拟合?
上面的图分别表示:欠拟合,适配良好,过拟合
1.28.Train-Val-Test划分
1.28.1.1.How to detect(如何检测)
1.28.1.2.Splitting(划分训练集和测试集)
合理的 Train/Test 集划分会有效地减少 under-fitting 和 over-fitting 现象
以数字识别为例,正常一个数据集我们要划分出来训练部分和测试部分,如下图所示:
左侧橘色部分作为训练部分,神经网路在该区域内不停地学习,将特征转入到函数中,学习好后得到一个函数模型。随后将上图右面白色区域的测试部分导入到该模型中,进行accuracy和loss的验证
通过不断地测试,查看模型是否调整到了一个最佳的参数,及结果是否发生了over-fitting现象。
1.28.1.3.for example
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transformsbatch_size=200
learning_rate=0.01
epochs=10# 使用 train=True 或 train=False来进行数据集的划分
# train=True时为训练集,相反即为测试集
train_db = datasets.MNIST('../data', train=True, download=True,transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,))]))# 训练-测试代码写法
# 一般使用DataLoader函数来让机器学习或测试
train_loader = torch.utils.data.DataLoader(train_db,batch_size=batch_size, shuffle=True)test_db = datasets.MNIST('../data', train=False, transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,))
]))
test_loader = torch.utils.data.DataLoader(test_db,batch_size=batch_size, shuffle=True)
1.28.1.4.test while train
1.28.1.5.train test trade-off
1.28.1.6.for others judge
其实正常情况下除了Train Set和挑选最佳参数的Test Set外,一般还要有Validation Set。
Val Set代替Test Set的功能,而Test Set则要交给客户,进行实际验证,正常情况下Test Set是不加入到测试中的
说个很具体的场景,就比方说 Kaggle 竞赛中,比赛的主办方给你训练的数据集,一般我们拿来都会自己分成 Train Set 和 Val Set 两部分,用 Train Set 训练,Val Set 挑选最佳参数,训练好以后提交模型,此时主办方会用它自己的数据集,即 Test Set 去测试你的模型,得到一个 Score。
从上面的过程能看出,Val Set可以理解为是从Train Set找拆出来的一部分,而与Test Set没有关系
# 这里注意,正常情况下数据集是要有validation(验证)集的,若没有设置,即将test和val集合并为一个了
# 这里注意,正常情况下数据集是要有validation(验证)集的,若没有设置,即将test和val集合并为一个了
print('train:', len(train_db), 'test:', len(test_db))
# 首先先查看train和test数据集的数量,看看是否满足预订的分配目标
# 随机分配法将数据分为50k和10k的数量
train_db, val_db = torch.utils.data.random_split(train_db, [50000, 10000])
print('db1:', len(train_db), 'db2:', len(val_db))
train_loader = torch.utils.data.DataLoader(train_db,batch_size=batch_size, shuffle=True)
val_loader = torch.utils.data.DataLoader(val_db,batch_size=batch_size, shuffle=True)
1.28.1.7.train-val-test
1.28.1.8.K-fold cross-validation
1.28.1.9.k-fold cross validation
hold-out(留出法)
直接将数据集划分为两个互斥的集合
但是这种方法,只有新划分的训练集会参与到backward过程中
K-fold cross-validation(K拆交叉验证)
即把数据分成K份,每次拿出一份作为验证集,剩下k-1份作为训练集,重新K次。最后平均K次的结果,作为误差评估的结果。
这种方法可以将验证集充分利用起来,从而使得每个数据集都可以参与backward过程中。
不过这种方法对模型的提升有限,毕竟数据集并没有增加。
1.30.Regularization
为了解决torch.optim优化器只能实现L2正则化以及惩罚网络中的所有参数的缺陷,这里实现类似于TensorFlow正则化的方法。
1.30.1.自定义正则化Regularization类
这里封装成一个实现正则化的Regularization类,各个方法都给出了注释。
# -*- coding: UTF-8 -*-import torch# 检查GPU是否可用
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# device='cuda'
print("--------device:{}".format(device))
print("--------Pytorch version:{}".format(torch.__version__))class Regularization(torch.nn.Module):def __init__(self, model, weight_decay, p=2):''':param model 模型:param weight_decay: 正则化参数:param p: 范数计算中的幂指数值,默认求2范数,当p=0为L2正则化,p=1为L1正则化'''super(Regularization, self).__init__()if weight_decay <= 0:print("param weight_decay can not <=0")exit(0)self.model = modelself.weight_decay = weight_decayself.p = pself.weight_list = self.get_weight(model)self.weight_info(self.weight_list)def to(self, device):'''指定运行模式:param device: cuda or cpu:return:'''self.device = devicesuper().to(device)return selfdef get_weight(self, model):'''获得模型的权重列表:param model::return:'''weight_list = []for name, param in model.named_parameters():if 'weight' in name:weight = (name, param)weight_list.append(weight)return weight_listdef regularization_loss(self, weight_list, weight_decay, p=2):'''计算张量范数:param weight_list::param weight_decay::param p: 范数计算中的幂指数值,默认求2范数:return:'''reg_loss = 0for name, w in weight_list:l2_reg = torch.norm(w, p=p)reg_loss = reg_loss + l2_regreg_loss = weight_decay * reg_lossreturn reg_lossdef weight_info(self, weight_list):'''打印权重列表信息:param weight_list::return:'''print("-------regularization weight--------")for name, w in weight_list:print(name)print("------------------------------------")def forward(self, model):# 获得最新的权重self.weight_list = self.get_weight(model)reg_loss = self.regularization_loss(self.weight_list, self.weight_decay, p=self.p)return reg_loss
1.30.2.Regularization使用方法
使用方法很简单,就当一个普通Pytorch模块来使用,例如:
# 检查GPU是否可用
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")print("------device:{}".format(device))
print("------Pytorch version:{}".format(torch.__version__))weight_decay = 100.0 #正则化参数
learning_rate=0.01model = Regularization().to(device)
# 初始化正则化
if weight_decay > 0:reg_loss = Regularization(model, weight_decay, p=2).to(device)
else:print("no regularization")# CrossEntropyLoss=softmax+cross entropy
criterion = nn.CrossEntropyLoss().to(device)
# 不需要指定参数weight_decay
optimizer = optim.Adam(model.parameters(), lr=learning_rate)# train
batch_train_data = ...
batch_train_label = ...out = model(batch_train_data)# loss and regularization
loss = criterion(input=out, target=batch_train_label)
if weight_decay > 0:loss = loss + reg_loss(model)
total_loss = loss.item()# backprop
# 清除当前所有的累积梯度
optimizer.zero_grad()
total_loss.backward()
optimizer.step()
训练时输出的 loss和Accuracy信息:
(1)当weight_decay=0.0时,未使用正则化
(2)当weight_decay=10.0时,使用正则化
(3)当weight_decay=10000.0时,使用正则化
对比torch.optim优化器的实现L2正则化方法,这种Regularization类的方法也同样达到正则化的效果,并且与TensorFlow类似,loss把正则化的损失也计算了。
此外更改参数p,如当p=0表示L2正则化,p=1表示L1正则化。
31,32,33_过拟合、欠拟合的概念、L2正则化,Pytorch过拟合欠拟合,交叉验证-Train-Val-Test划分,划分训练集和测试集,K-fold,Regularization相关推荐
- R语言决策树、bagging、随机森林模型在训练集以及测试集的预测结果(accuray、F1、偏差Deviance)对比分析、计算训练集和测试集的预测结果的差值来分析模型的过拟合(overfit)情况
R语言决策树.bagging.随机森林模型在训练集以及测试集的预测结果(accuray.F1.偏差Deviance)对比分析.计算训练集和测试集的预测结果的差值来分析模型的过拟合(overfit)情况 ...
- 看图就懂:为什么L1正则化比L2正则化更容易得到稀疏解?为什么L2正则化可以用于防止过拟合?
相信大部分人都见到过,下面的这两张对比图,用来解释为什么L1正则化比L2正则化更容易得到稀疏解,然而很多人会纠结于"怎么证明相切点是在角点上?",呃,不必就纠结于此,请注意结论中的 ...
- 花书+吴恩达深度学习(五)正则化方法(防止过拟合)
目录 0. 前言 1. 参数范数惩罚 2. Dropout 随机失活 3. 提前终止 4. 数据集增强 5. 参数共享 如果这篇文章对你有一点小小的帮助,请给个关注,点个赞喔~我会非常开心的~ 花书+ ...
- 动手学深度学习(PyTorch实现)(三)--过拟合与欠拟合
过拟合与欠拟合 1. 过拟合与欠拟合 1.1 训练误差和泛化误差 1.2 模型选择 1.2.1 验证数据集 1.2.2 K折交叉验证 1.3 过拟合与欠拟合 1.3.1 模型复杂度 1.3.2 训练数 ...
- 机器学习基础 线性回归及一些基础概念(正则化、过拟合、欠拟合等)
文章目录 一.线性回归简介 1. 线性回归应用场景 2. 什么是线性回归 2.1 定义与公式 2.2 线性回归的特征与目标的关系分析 3. 小结 二.线性回归api初步使用 1. 线性回归API 2. ...
- 欠拟合与过拟合、泛化能力概念总结及python示例
目录 1. 基本概念 2. python示例 3. 欠拟合产生的原因与解决方法 4. 过拟合产生的原因与解决方法 5. 欠拟合和过拟合的简明判断方法 1. 基本概念 机器学习中欠拟合(underfit ...
- 机器学习-过拟合、正则化、稀疏性、交叉验证概述
在机器学习中,我们将模型在训练集上的误差称之为训练误差,又称之为经验误差,在新的数据集(比如测试集)上的误差称之为泛化误差,泛化误差也可以说是模型在总体样本上的误差.对于一个好的模型应该是经验误差约等 ...
- 【机器学习】交叉验证防止过拟合(含义+代码+演示)
什么是过拟合? 对训练集拟合效果很好,对测试集拟合效果比较差,这种情况叫做过拟合. 一 训练集 vs 测试集 在模式识别(pattern recognition)与机器学习(machine learn ...
- 深度学习模型在训练集上很好而在测试集表现得不好而拟合次数并不多_机器学习中的过拟合,欠拟合和偏倚方差折衷...
过度拟合在机器学习中很重要. 很直观的解释过拟合:假设我们现在让机器学习考试做题,想象一种情况,机器逐字记住每个问题的答案(拟合非常好-完美).然后,我们可以在练习题上得分很高:我们这样做是基于希望实 ...
最新文章
- 【自然框架 NatureFW】里的两种“映射”方式
- 我的天,你工作5年了,连Java agent都不知道...
- 【Python】5个方便好用的Python自动化脚本
- STM32 - 定时器高级应用说明 - 多触波的实现 (N-pulse waveform generation using timer synchronization)- 01
- java jedis_Java操作Redis之Jedis用法详解
- 读书笔记 数据化营销
- 服务器找不到硬盘如何解决方案,Linux云服务器磁盘不见了?解决方案在这里
- 全国超300所大学图书馆收藏本人作品
- MongoDB 基本命令
- Java技术面试汇总
- Unity Web前端研究
- 计算机四则运算的原理,计算机组成原理第九讲(除法-补码运算规则及浮点四则运算)(科大罗克露)...
- 《大明王朝》倒严的号角
- java较全的面试题
- 笔划码、五笔码、拼音码软键盘中文输入
- 洛谷P1873-砍树(二分答案)
- 简单好用的网络保护软件 lulu for mac 支持big sur系统
- 依赖倒转原则 (Dependence Inversion Principle)
- 转载和积累系列 - HTTPS原理和HTTP缓存机制
- JCcreator 4.5 注册码
热门文章
- linux终端每次都要输入密码,ubuntu chrome 下每次打开都需要输入密码
- 《Python游戏编程快速上手》第五章--龙穴探险
- Python自动化运维——IP地址处理模块
- 《高性能JavaScript》第五章 字符串和正则表达式
- nsga2多目标优化之核心知识点(快速非支配排序、拥挤距离、精英选择策略)详解(python实现)
- boost::type_erasure::ostreamable相关的测试程序
- boost::phoenix::bind相关的测试程序
- boost::pfr::detail::offset_based_getter相关的测试程序
- boost::intrusive::value_traits用法的测试程序
- GDCM:检索dicom文件中某个位置存在的Icon测试程序