PyTorch + NumPy这么做会降低模型准确率,这是bug还是预期功能?

从零实现手写数字识别:基于PyTorch与LeNet-5的深度学习入门实战 卷积神经网络(CNN)是计算机视觉领域的核心模型,其通过局部连接和权值共享的机制,能够高效地从图像数据中提取空间层次化特征。这一原理使其在图像分类、目标检测等任务中展现出巨大技术价值。作为经典的入门实践,手写数字识别项目是理解CNN工作原理和深度学习全流程的绝佳场景。本文以PyTorch为框架,详细拆解了LeNet-5这一经典CNN架构的实现,涵盖了从环境搭建、数据预处理、模型构建、训练调优到性能评估的完整工程实践。通过此项目,开发者可以直观掌握如何利用PyTorch构建和训练一个高效的图像分类模型,为后续 阅读详情

来源:机器之心

来自:机器学习研究组订阅

著作权归作者所有,本文仅作学术分享,若侵权,请联系后台删文处理

近日,有用户在自己的项目中发现了一个微小的 bug,在 PyTorch 同时使用 NumPy 的随机数生成器和多进程数据加载会导致相同的扩充数据,只有专门设置 seed 才可以解决这个 bug,否则会降低模型的准确率。不过,有人认为这并不是一个 bug,而是预期功能,是「按预期工作的」。

行内人都知道,机器学习(ML)代码中的 bug 很难修复,并且它们不会造成编译错误,而是悄悄地降低准确率。这些 bug 简直防不胜防。最近,一位专注于机器学习的用户遇到了一个非常熟悉的 bug,修复了之后性能有了大幅度提升。这是一个什么样的 bug 呢?

根据用户的描述,bug 是这样的:除非你在 DataLoader 中使用 worker_init_fn 选项专门设置 seed,否则在 PyTorch 同时使用 NumPy 的随机数生成器和多进程数据加载会导致相同的扩充数据。用户没有这样做,因而这个 bug 悄悄地降低了模型的准确率。

该 bug 非常小并且很容易出现。所以,这位用户很好奇会不会也对其他项目造成损害呢?ta 从 GitHub 上下载了 10 万个导入 PyTorch 的库,并分析了这些库的源代码。之后,ta 保留了那些具有自定义数据集、同时使用 NumPy 的随机数生成器和多进程数据加载以及或多或少使用抽象语法树进行分析的项目。

结果显示,95% 以上的库存在着这个 bug,如 PyTorch 的官方教程、OpenAI 的代码以及 NVIDIA 的项目。甚至特斯拉 AI 负责人 Andrej Karpathy 也曾遭受过该 bug 的困扰。

OpenAI 的 ebm_code_release 项目。

这个 bug 究竟怎样影响模型的准确率?这位用户从以下两个示例中进行了简要描述。

bug 描述

在 PyTorch 中加载、预处理和扩充数据的标准方法是子类化 torch.utils.data.Dataset 并重写 __getitem__方法。要应用扩充方法(如随机裁剪、图像翻转),__getitem__方法经常使用 NumPy 来生成随机数,然后将 map-styled 数据集传递给 DataLoader 来创建 batch。这种训练 pipeline 可能会受到数据预处理的阻碍,因此并行加载数据是有意义的。可以通过增加 DataLoader 对象中的 num_workers 参数来实现。

问题是,这个工作流导致了相同的数据扩充。

PyTorch 使用多进程并行加载数据,worker 进程是使用 fork start 方法创建的。这意味着每个工作进程继承父进程的所有资源,包括 NumPy 的随机数生成器的状态。

示例 1

为了更加形象地描述问题,用户从以下两个示例中进行了简要概述。

示例 1 为一个示例数据集,它返回三个元素的随机向量。示例使用两个和四个工作进程的 batch 大小。

代码返回如下结果:每个进程返回的随机数都是相同的。

示例 2

示例 2 演示了如何在 face-landmarks 数据集上使用 Dataset 和 DataLoader 类。此外,还提到了数据扩充的重要性,并提供了一个随机裁剪扩充的例子。这是使用 NumPy 的随机数生成器实现的。

通过增加 num_workers 来加速数据加载,可以得到相同的裁剪结果:


batch 大小为 8, num_workers 为 2,random crop augmentation(随机裁剪扩充)

这个 bug 很容易产生。在某些情况下,它对最终性能的影响很小。在另一些情况下,相同的扩充会导致严重的退化。

基于对开放源码 PyTorch 项目的分析,发现 bug 的这位用户担心这个问题在许多支持真实产品的代码库中都存在。

究竟是 bug,还是预期功能或特征?

这位用户描述的 bug 也引起了众多网友的热议,其中一些人并不认为这是 bug。

用户「amasterblaster」认为,这不是一个 bug,而是所有种子随机函数的预期功能。这是因为即使在随机实验中,有时你想要对比静态参数的变化,并得到相同的随机数。只有当你被读为真随机(true random)时,才会根据 OS time 设置 seed。

用户「xicor7017」表示自己也遇到了相同的问题,也认为它并不是一个 bug,而是一个可能不为人所知的特征。如果忽略它的话,调试问题时会很麻烦。

与此同时,另一些人表达出了不同的观点,认为既然「如果事情朝着人们不希望的方向发展,那么它就不应该这样,也就构成了 bug。」

用户「IntelArtiGen」称自己意识到了这个 bug,认为它是不正常的,并且对自己的项目造成了一些小问题。用户「gwern」赞同这种观点,认为如果 95% 以上的用户使用时出现错误,则代码就是错的。

用户「synonymous1964」进一步解读了这个 bug。ta 认为,人们可能误解了这个问题,问题不在于设置特定的随机种子会导致每次训练过程中生成相同序列的随机数,这显然是按预期工作的。相反,问题在于多个数据下载进程中(由 PyTorch 中的 num_workers 设置)的每个进程都会在某个特定的训练过程中输出相同序列的随机数。毫无疑问,这当然会对项目造成影响,具体取决于你如何进行数据加载和扩充。所以,即使这个 bug 是「按预期工作的」,但向更多其他用户指出来也挺好的。

不知道机器之心的读者,有没有遇到过类似的 bug 呢?如果有,可以在评论中发表自己对该 bug 的观点。

参考链接:

https://tanelp.github.io/posts/a-bug-that-plagues-thousands-of-open-source-ml-projects/

https://www.reddit.com/r/MachineLearning/comments/mocpgj/p_using_pytorch_numpy_a_bug_that_plagues/

PyTorch手撕CNN实战:从原理到部署的完整闭环 卷积神经网络(CNN)是计算机视觉的基石模型,其核心在于利用局部感受野、权值共享与池化操作,协同解决图像的空间冗余、参数爆炸和位置敏感性三大工程挑战。PyTorch凭借动态计算图、Tensor/NumPy无缝互操作和细粒度设备控制,成为理解CNN底层机制与开展工业级调试的理想框架。掌握卷积核尺寸选择、padding/stride对特征图尺寸的精确影响、ReLU对梯度流的调控作用,以及DataLoader配置、state_dict保存、混合精度训练等实操细节,是构建鲁棒可部署模型的关键技术价值。本文聚焦MNI 阅读详情

相关推荐

2026深度学习框架怎么选?PyTorch两小时速通指南

深度学习框架是构建神经网络模型的基础工具,其核心设计直接影响开发体验与学习曲线。动态计算图与自动求导机制让模型调试变得直观,而生态活跃度则决定了从论文复现到工业落地的顺畅程度。在当前主流的 TensorFlow 与 PyTorch 之间,如何做出适合自身需求的选择,是深度学习入门者面临的首要问题。基于框架演进历程与核心差异,梳理出适用于科研与工程实践的选型思路,并整理了一条从环境搭建到图像分类实战的 PyTorch 快速学习路线,帮助初学者在最短时间内跑通完整训练流程。

weixin_34344403的博客 379

Pytorch 保证实验结果可重复性质

由于在模型训练的过程中存在大量的随机操作,使得对于同一份代码,重复运行后得到的结果不一致。因此,为了得到可重复的实验结果,我们需要对随机数生成器设置一个固定的种子。 许多博客都有介绍如何解决这个问题,但是很多都不够全面,往往不能保证结果精确一致。我经过许多调研和实验,总结了以下方法,记录下来。 全部设置可以分为三部分:   1. CUDNN cudnn中对卷积操作进行了优化,牺牲了精...

分享日常的学习,开展的项目,编写的软件,解决的问题等~ 4478

PyTorch模型生产部署实战:从Notebook到高稳低延推理服务

机器学习模型服务化是AI工程落地的核心环节,涉及模型序列化、API封装、GPU推理优化、流量治理与可观测性等关键技术。其本质是将训练阶段的静态计算图转化为可弹性伸缩、具备容错能力、满足SLA要求的在线服务。关键挑战在于环境一致性、数据预处理隔离、并发推理稳定性及资源精细化管控。实践中,TorchServe凭借原生GPU上下文共享显著降低P99延迟,FastAPI通过异步IO提升吞吐,Nginx实现限流与健康检查,三者协同构建分层加固架构。本文聚焦真实生产场景中的模型服务化与推理延迟优化,覆盖Docker容器

图灵教育官方博客 380

DataLoader的num_workers=0对训练有什么影响?如何弥补?可以通过增加训练的epoch弥补吗?...

PyTorch的DataLoader类中的num_workers参数表示数据读取时使用的线程数量。如果num_workers=0,则表示不使用多线程,数据读取和预处理都在主线程中进行。 在这种情况下,如果数据预处理时间过长,会导致训练的速度变慢。因此,可以通过设置num_workers>0来弥补,以并行地加速数据读取和预处理。 增加训练的epoch可以提高训练的精度,但不能弥补数据读取的速度...

weixin_42611177的博客 2364

PyTorch从零实现花卉图像分类CNN实战

图像分类是计算机视觉的基础任务,其核心在于利用卷积神经网络(Convolutional Neural Net)建模局部空间特征与层级语义关系。原理上,卷积层通过滑动窗口检测边缘、纹理等低级模式,池化层增强平移不变性,而BatchNorm与ReLU的组合顺序直接影响梯度流动与收敛稳定性。这类轻量级CNN具备参数可控、部署友好、可解释性强的技术价值,广泛应用于农业识别、工业质检、移动终端等边缘场景。本文以5类常见花卉为数据载体,完整呈现一个不依赖预训练模型、适配笔记本GPU的端到端PyTorch实现过程,涵盖数

dihuangxiu8828的博客 388

深度学习模型改进实战:PyTorch自定义模块集成与性能优化指南

深度学习模型改进是提升算法性能的关键技术路径,其核心原理在于通过结构化调整网络架构来增强特征表达能力。从技术价值看,有效的模型改进能突破性能瓶颈、适配特定任务需求并提升计算效率,广泛应用于计算机视觉、自然语言处理等领域。本文聚焦于模块复用与组合这一基础创新层次,通过PyTorch实战演示如何为卷积神经网络集成注意力机制模块,其中通道注意力机制和残差连接等热词技术被深入应用于特征重校准过程,为模型定制化开发提供可复现的工程范例。

weixin_33919950的博客 289

num_workers

pytorch中num_work的使用方法

shajie的博客 5153

PyTorch从零手搭神经网络:MNIST实战入门指南

神经网络是深度学习的核心范式,其本质是通过前向传播计算输出、反向传播更新参数、梯度下降优化损失的可微分计算图。PyTorch凭借动态计算图与autograd机制,让这一过程高度透明且贴近数学直觉,显著降低初学者理解门槛。相比预训练模型调用或静态图框架,从零构建全连接网络能深入掌握维度对齐、梯度生命周期、模型状态切换等工程契约。以MNIST为起点,因其数据规整、干扰极小,成为验证前向传播逻辑、调试反向传播路径、观察梯度下降效果的理想沙盒。本文聚焦PyTorch原生实现,覆盖张量加载、nn.Module封装、C

图灵教育官方博客 398

深度学习训练中“num_workers”的作用

在深度学习训练中,是一个常见的参数,特别是在使用数据加载器(如PyTorch的DataLoader)时。指定了用于数据加载的。这个参数对于提高数据加载的效率和加速训练过程至关重要。

llf000000的博客 2866

pytorch绘制并显示loss曲线和acc曲线,LeNet5识别图像准确率

我用的是Anaconda3 ,用spyder编写pytorch的代码,在Anaconda3中新建了一个pytorch的虚拟环境(虚拟环境的名字就叫pytorch)。 以下内容仅供参考哦~~ 1.首先打开Anaconda Prompt,然后输入activate pytorch,进入pytorch. 2.输入pip install tensorboardX,安装完成后,输入python,用from tensorboardX import SummaryWriter检验是否安装成功。如下图所示: 3.安装完成之后,先给大家看一下我的文件夹,如下图: 假设用LeNet5框架识别图像的准确率,LeN

【Proteus】NE555纯硬件实现LED呼吸灯效果,附源文件,效果展示

本设计通过NE555与三极管的巧妙配合,仅用基础元件实现了呼吸灯效果。核心在于利用RC积分电路将PWM信号转换为控制电压,并通过负反馈动态调节占空比。Proteus仿真验证了方案的可行性,读者可进一步优化参数或扩展功能,探索更多硬件设计可能性。

2201_75797484的博客 2983

PyTorch + NumPy 这么做会降低模型准确率,这是 bug 还是预期功能?

转自 | 机器之心编辑 | 维度近日,有用户在自己的项目中发现了一个微小的 bug,在 PyTorch 同时使用 NumPy 的随机数生成器和多进程数据加载会导致相同的扩充数据,只有专门设...

AI蜗牛车 445

【阿里云大模型高级工程师ACP习题集】2.3 优化提示词改善答疑机器人回答质量

【摘要】这是我精心整理出对应的习题集,里面足足有 30 道题目,从基础概念到深度拓展,全方位覆盖章节重点、难点。不管你是想检验自己的学习成果,还是想针对薄弱环节进行强化训练,它都能完美适配!

davidkorhenn的博客 1633

PyTorch里这个bug,你知道吗?

机器之心报道编辑:维度近日,有用户在自己的项目中发现了一个微小的 bug,在 PyTorch 同时使用 NumPy 的随机数生成器和多进程数据加载会导致相同的扩充数据,只有专门设置 see...

zandaoguang的博客 232

海思Hi3519AV100 sensor移植实战:IMX586驱动调试与硬件验证全流程

本文详细解析了在海思Hi3519AV100平台上移植索尼IMX586传感器的全流程实战。内容涵盖从硬件I2C通信验证、驱动代码移植与修改,到内核配置、时钟设定,以及使用示波器进行硬件信号深度验证和ISP图像调优等关键步骤,为开发者提供了一套清晰、可复现的sensor移植与调试方法。

weixin_29168393的博客 395

【MFRC522】STM32与MFRC522的SPI通信优化及常见问题解析

本文深入解析了STM32与MFRC522进行SPI通信的优化方法与常见问题。从基础的硬件连接到SPI时序优化,再到关键的寄存器配置(如RFCfgReg设为0x4F以提升读卡稳定性),文章提供了详细的调试技巧和实战排坑指南,帮助开发者实现稳定高效的IC读卡应用。

yhn45678901的博客 842

PyTorch深度学习实践手记:从NumPy反向传播到可调试CNN

深度学习不是纯数学,而是数据、计算与工程的三位一体。理解张量维度、自动微分机制和梯度生命周期,是让模型真正跑通的基础前提;PyTorch的动态图特性与NumPy的手动实现对照,能打通‘公式→代码→运行’的认知闭环。这种‘代码即教材’的路径,显著降低初学者在数据加载、loss.backward()、Normalize参数等高频卡点上的调试成本,适用于已掌握Python基础并尝试过机器学习项目的工程师。本文聚焦手写数字识别这一经典任务,以可追踪、可打印、可归因的实操方式,还原真实开发中的决策逻辑与排错过程。

chenzhuofei4155的博客 509

告别信息过载:我是如何用Feedly RSS阅读器打造个人专属信息流的(附Chrome插件使用技巧)

本文分享了如何利用Feedly RSS阅读器有效管理信息过载,打造个人专属信息流的方法。通过科学组织订阅源、智能过滤和跨平台同步技巧,帮助用户从被动接收转为主动筛选,提升信息获取效率。特别推荐使用Feedly的Chrome插件和AI过滤功能,实现高效的信息管理。

weixin_42526015的博客 358

pytorch 可复现性

官网说明: Reproducibility — PyTorch 1.8.0 documentation 参考博客: PyTorch模型可复现性总结 - 简书 pytorch 固定随机数种子踩过的坑_yqf3838751的博客-优快云博客 PyTorch设置随机数种子使结果可复现 - 简书 代码设置: 1. 训练文件: ...

wzg2016的博客 708

ansys license许可证问题:Ansys License Manager Release 2024 R1...如何解决?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 5371

解决com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60027, active 20, maxActive 20错误

全网详细解决com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60027, active 20, maxActive 20, creating 0, createErrorCount 24的错误

念兮为美 417

2026深度学习框架选型:TensorFlow与PyTorch对比及PyTorch实战

深度学习框架是构建神经网络模型的工程化工具,其核心价值在于自动求导、算子库与设备调度,让研究者无需手动推导梯度公式,即可高效完成模型训练。在众多框架中,TensorFlow与PyTorch是最主流的两大选择:前者在工业部署和服务端场景积累深厚,后者凭借动态计算图和Python化风格成为学术研究与论文复现的事实标准。对于入门者而言,理解两者的核心差异、按自身目标做出合理选型,比盲目跟风更重要。本文从基础概念出发,解析框架的底层原理与技术价值,并结合移动端部署、科研实验等典型应用场景,给出清晰的选型建议。同时,

weixin_33871366的博客 387

​非线性分析-增加位移量可能出现下面错误。虽然求解无法在所有时间点完成,但在某些点上仍能够求解部分结果。请参阅“帮助系统”中的故障排除,以了解更多信息详情。由于受约束,规划求解引擎无法收敛

基于收敛状态拆分载荷步‌:在已收敛的载荷步基础上,将未收敛的关键区域拆分为更细的子步,比如在载荷突变点前设置5~10个子步,逐步加载。替换冲突约束为弱约束‌:若存在约束冲突,将刚性约束替换为弱弹簧约束(刚度设为1e-6~1e-4),既限制刚体位移,又不影响结构的变形自由度,命令流:SPRING, NODE, K, 1e-6。部分区域约束完整,但存在未被约束的刚体自由度,或约束类型与大变形/接触逻辑冲突,比如某部件的位移约束在初始阶段有效,但大变形后约束位置脱离实际受力点,导致求解器在该阶段无法收敛。

qq_15963745的博客 149

PyTorch极速入门与TensorFlow对比:深度学习框架选型指南

深度学习框架是构建神经网络的核心工具,其核心机制围绕张量计算与自动求导展开,帮助开发者高效完成模型训练与部署。在AI工程实践中,框架选型直接影响学习成本和项目落地效率。PyTorch凭借动态计算图、灵活的调试体验以及在大模型生态中的主导地位,成为科研与工业应用的热门选择;TensorFlow则在特定部署场景中仍有优势。本文从张量操作、自动求导到完整训练一个分类模型,带读者快速上手PyTorch,并结合行业趋势给出框架选型与职业发展建议,帮助新手和技术决策者找到适合自己的技术路径。

weixin_34378969的博客 360

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

上一篇: 哈哈哈!当前的人工智能有多智障?
下一篇: 注意力机制是如何学习到模型所应注意的区域的?
机器学习算法那些事
博客等级 码龄9年 1633粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值