发布时间:2026/9/2 6:59:13
【深度学习】模型选择、过拟合与欠拟合 一、训练误差 vs 泛化误差训练误差Training Error模型在训练数据上的误差。泛化误差Generalization Error模型在从未见过的新数据上的误差。类比训练误差 平时做课堂练习的正确率泛化误差 期末考试的成绩。关键结论我们真正关心的是泛化误差而不是训练误差。因为我们训练模型不是为了在训练集上得高分而是为了处理将来遇到的新数据。二、验证数据集 vs 测试数据集为了正确地估计泛化误差我们需要把手里的数据拆成三份2.1 训练数据集Training Set用来训练模型参数。比如把全部数据的 60% 拿来。2.2 验证数据集Validation Set用来选择/评估模型、调超参数学习率、层数、Dropout 比例等。不能和训练数据混在一起否则失去意义。比如把 60% 训练集里再拿出 20% ~ 50% 作为验证集。# 从训练集中划分出验证集n_trainint(0.8*len(train_dataset))train_subtorch.utils.data.Subset(train_dataset,range(0,n_train))val_subtorch.utils.data.Subset(train_dataset,range(n_train,len(train_dataset)))# train_sub 用于训练val_sub 用于调参2.3 测试数据集Test Set只用一次的数据集最终评估性能用。在任何情况下都不能用来调超参数否则结果就是作弊。类比验证集 模拟考试可以反复做用来调整复习方向测试集 正式高考只考一次考完就定论了如果你拿高考真题来练手那高考成绩就毫无意义了为什么不能拿测试集调参因为一旦你根据测试集的结果调整了模型测试集就不再没见过了它的评估就失去了泛化意义——就像上过考场见过真题的人成绩已经不反映真实水平。三、K-折交叉验证K-Fold Cross Validation当数据不够多的时候单纯拿出一部分做验证集太浪费。这时用K-折交叉验证。3.1 算法过程算法K-折交叉验证把训练数据均匀分成 K 块For i 1, 2, …, K:使用第 i 块作为验证数据集其余 K-1 块合并作为训练数据集训练模型记录第 i 折的验证误差报告 K 个验证误差的平均值常用 K 5 或 K 10。数据分割示意K5 折1: [验证][训练][训练][训练][训练] 折2: [训练][验证][训练][训练][训练] 折3: [训练][训练][验证][训练][训练] 折4: [训练][训练][训练][验证][训练] 折5: [训练][训练][训练][训练][验证] ↑ 每折轮流当一次验证集3.2 代码实现importtorchfromtorch.utils.dataimportDataset,DataLoaderdefk_fold_cross_validation(dataset,k,train_fn): 对 dataset 做 K-折交叉验证。 train_fn: 训练函数接收 (train_loader, val_loader)返回验证集误差 total_lenlen(dataset)fold_sizetotal_len//k val_losses[]foriinrange(k):# 第 i 折的验证集索引val_indiceslist(range(i*fold_size,(i1)*fold_size))train_indiceslist(set(range(total_len))-set(val_indices))train_subtorch.utils.data.Subset(dataset,train_indices)val_subtorch.utils.data.Subset(dataset,val_indices)train_loaderDataLoader(train_sub,batch_size256,shuffleTrue)val_loaderDataLoader(val_sub,batch_size256,shuffleFalse)# 每一折重新训练一个模型val_losstrain_fn(train_loader,val_loader)val_losses.append(val_loss)print(f折{i1}: 验证误差 {val_loss:.6f})# 报告 K 个验证误差的平均returnfloat(torch.tensor(val_losses).mean())K5avg_lossk_fold_cross_validation(train_dataset,K,my_train_fn)print(f{K}-折平均验证误差 {avg_loss:.6f})3.3 K5 和 K10 怎么选选项优点缺点适用K5训练快每折训练 80% 数据验证集稍大偏差稍高数据中等追求速度K10每折训练 90% 数据更接近全量训练慢成本高数据少且珍贵追求精度原则数据越少、越珍贵K 越大数据很多时直接固定一个验证集就行不必交叉验证。四、多项式函数拟合实战我们用一个三次多项式做实验4.1 生成带噪声的真实数据importtorchimportmatplotlib.pyplotasplt n_train100# 训练样本n_test100# 测试样本# 真实函数y 1.2x - 3.4x^2 5.6x^3 5再加一点噪声deftrue_fn(x):return1.2*x-3.4*x**25.6*x**35# 生成 x 和带噪声的 yfeaturestorch.randn(n_trainn_test,1)noisetorch.normal(0,0.5,sizefeatures.shape)labelstrue_fn(features)noise# 用多项式特征扩展把一列 x 变成 [x, x^2, x^3, ...]defpoly_features(x,degree):returntorch.cat([x**iforiinrange(1,degree1)],1)# 我们用次数 3 的多项式特征去拟合和真实函数次数一致degree3poly_featurespoly_features(features,degree)4.2 三个模型对比欠拟合 / 合适 / 过拟合我们用三种模型容量来拟合——次数不足、刚好、过高模型用它拟合结果线性次数 1三次数据欠拟合三次多项式次数 3三次数据刚好合适高次多项式次数 e.g.7三次数据过拟合importtorchfromtorchimportnndeftrain_poly(degree,epochs500,lr1e-2):用指定次数的多项式模型去拟合三次函数的数据# 多项式特征features_polytorch.cat([features**iforiinrange(1,degree1)],1)n_train100train_ffeatures_poly[:n_train]train_llabels[:n_train]test_ffeatures_poly[n_train:]test_llabels[n_train:]# 线性模型对多项式特征做线性组合等价于多项式拟合netnn.Linear(degree,1,biasFalse)net.weight.data.normal_(0,0.01)lossnn.MSELoss()trainertorch.optim.SGD(net.parameters(),lrlr)forepochinrange(epochs):trainer.zero_grad()lloss(net(train_f),train_l)l.backward()trainer.step()train_lossloss(net(train_f),train_l).item()test_lossloss(net(test_f),test_l).item()returntrain_loss,test_lossfordegreein[1,3,7]:tr,tetrain_poly(degree)print(f次数{degree}: 训练误差{tr:.6f}| 泛化(测试)误差{te:.6f})五、过拟合与欠拟合欠拟合Underfitting模型过于简单训练误差都无法降低。连课堂例题都做不对。过拟合Overfitting模型过于复杂训练误差很低但泛化误差很高。把例题全背下来了换个问法就废。六、模型容量与 VC 维7.1 模型容量Model Capacity模型容量 模型拟合各种函数的能力。低容量模型难以拟合训练数据欠拟合。高容量模型可以记住所有训练数据但往往过拟合。两种极端都不好。我们的目标是容量刚好够拟合真实规律但又不会大到把噪声也背下来。7.2 VC 维VC Dimension怎么定量衡量模型容量一个常用指标就是VC 维。VC 维的定义一个模型最多能打散shatter多少个数据点——即不管这些点的标签怎么排列正/负模型都能找到一个参数把这组点完全分开。二维平面上的线性分类器VC 维 3。它最多能完全分开 3 个点任意正负组合都能用一条直线分开但 4 个点就不行了比如 XOR 布局。数据点越多、越分散需要的 VC 维越大。VC 维 3二维直线的例子3 个点无论正负怎么排总能画一条直线分开 → 能打散VC维至少34 个点存在排法如 XOR无法用直线分开 → 打不散所以 VC维 4结论二维线性分类器 VC 维 3直觉VC 维越大模型越能记但也越容易过拟合。而在我们的代码里多项式次数越高等价于 VC 维越高。八、触发过拟合的典型场景场景为什么容易过拟合训练数据太少模型把少量样本的噪声当成了规律模型参数太多容量过大拟合能力超过真实复杂度训练轮数过多epoch 过长越训越背训练集验证误差开始反弹特征维度远大于样本数如基因数据、图像展平向量八、应对过拟合的策略8.1 降低模型容量少几层网络 / 少几个隐藏单元高次多项式 → 降到合适的次数前面实验里次数 7 → 次数 38.2 数据增强Data Augmentation让数据变多变花降低对噪声的记忆# 图像随机翻转 旋转制造更多样本transformtorchvision.transforms.Compose([torchvision.transforms.RandomHorizontalFlip(),torchvision.transforms.RandomRotation(10),torchvision.transforms.ToTensor(),])8.3 正则化Regularization给损失函数加上对大权重的惩罚让模型不要太张狂。L2 正则化权重衰减 Weight Decay# 优化器自带 weight_decaytrainertorch.optim.SGD(net.parameters(),lr0.01,weight_decay0.05)# weight_decay 让每一步更新时权重都往 0 缩一点抑制过拟合8.4 Dropout训练时随机失活一部分神经元防止过度依赖某些特征netnn.Sequential(nn.Linear(784,256),nn.ReLU(),nn.Dropout(0.5),# 训练时随机丢弃 50% 神经元nn.Linear(256,128),nn.ReLU(),nn.Dropout(0.5),nn.Linear(128,10),)8.5 早停Early Stopping在验证误差开始回升的那一刻停止训练best_valfloat(inf)forepochinrange(num_epochs):train_one_epoch()val_lossevaluate(model,val_loader)ifval_lossbest_val:# 出现了更低的验证误差best_valval_loss torch.save(model.state_dict(),best.pt)# 存最好的# 如果连续 N 轮验证误差不再下降就早停ifno_improve_countpatience:break参考资料《动手学深度学习》第 4 章模型选择、欠拟合和过拟合Bishop, C. (2006). Pattern Recognition and Machine Learning.

相关新闻

2026/9/2 6:59:13

C++初阶——vector

目录 一 vector的介绍及使用 1、vector的介绍 2、vector的使用 二 vector在OJ中的使用 三 vector深度剖析及模拟实现 一、vector的介绍及使用 1、vector的介绍 std::vector是动态顺序数组,底层是一块连续堆内存;会自动扩容,下标随机访问O…

2026/9/2 6:59:13

DeepEvidence: Empowering Biomedical Discovery with Deep Knowledge Graph Research——通过深度知识图谱研究赋能生物医学发现

DeepEvidence 是一个专门针对生物医学知识图谱设计的“深度研究”AI智能体框架,旨在解决生物医学知识分散、异构、难以整合的痛点,通过系统化的知识图谱探索和推理,加速从药物发现到临床应用的完整生物医学研究生命周期。 一、研究背景与问题…

2026/9/2 6:59:13

【Day 11】Agent做错了怎么办?让它自己检查

摘要 try-except只能捕获代码崩溃,发现不了逻辑错误。本文实现Reflexion模式:执行后LLM自我评估,不通过则反思错因并存入记忆,带着反思重试。核心约80行,免费运行。 你让Agent算购物总价:3本书每本45元、2…

2026/9/2 7:14:14

用Claude Code搭建农业物联网监测平台:完整实战指南

Claude Code 的 100 个实战案例中,农业物联网监测平台是很有代表性的一种。它并不是让 AI 单纯生成几个页面,而是涉及传感器数据采集、协议解析、存储建模、接口服务、告警计算和可视化展示的完整链路。把这条链路交给 Claude Code 来辅助搭建&#xff0…

2026/9/2 7:14:14

超迷你DC-ATX电源:小机箱空间利用与供电改造完全指南

这次我们来看一个能直接改变小机箱内部布局的电源方案:超迷你 DC-ATX 电源。它的体积往往只有一张名片大小,甚至“手指大小”,却能输出上百瓦功率,把传统 ATX 电源挤出机箱之外。对于折腾 ITX、A4 结构、NAS、软路由、HTPC 的玩家…

2026/9/2 7:14:14

C语言医院挂号系统实战:链表与文件操作的综合应用

简介:本资源是一个基于C语言开发的轻量级医院挂号系统实现,面向C语言初学者与课程设计实践者,旨在通过真实业务场景帮助学习者掌握结构体设计、链表管理、文件持久化及模块化函数开发等核心编程能力。压缩包为ZIP格式,大小56KB&am…

2026/9/2 7:14:14

基于知识图谱与推荐系统的药物靶点预测:从数据到AI模型实战

简介:本资源是一套面向计算机及相关专业本科生的课程设计与期末大作业实战项目,聚焦于生物信息学交叉场景——利用知识图谱与推荐系统协同预测药物-靶点相互作用。项目代码完整、结构清晰,涵盖数据预处理(如hetionet.py、yamanish…

2026/9/1 16:02:17

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/9/1 8:27:47

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/9/1 7:04:43

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/9/2 0:03:41

单片机毕业设计-基于单片机与蓝牙通讯的输液状态监测终端设计与开发 基于 STM32 或 51 单片机的液位‑滴速‑温度多参数输液监护装置设计(024005)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/9/2 0:03:41

DeepSeek字幕翻译实战:从API调用到批量SRT转中文的完整方案

这次我们来看一个很实用的 DeepSeek 落地场景:用 DeepSeek 把英文视频字幕自动翻译成中文。具体案例是《恶魔君》1989 年第 28 集的英转中字幕任务,标题写得很直白,但背后其实是一整套可以复用的技术流程:字幕解析、模型调用、批量…

2026/9/2 0:03:41

用Python搭建搞笑语音助手:从语音识别到语音合成全教程

当你家里摆着一台天猫精灵,却总希望语音助手偶尔“不正经”一点,不用官方腔回答问题,而是张口就接几句搞笑段子,会是什么体验?我最近动手验证了一下这个想法——没有去改装任何市面上现有的智能音箱,而是直…

2026/9/2 1:15:22

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/2 1:15:22

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/2 1:15:20

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…