【随机种子初始化】一个神经网络模型初始化的大坑
1 问题起因和经过
半年前写了一个模型,取得了不错的效果(简称项目文件1),于是整理了一番代码,保存为了一个新的项目(简称项目文件2)。半年后的今天,我重新训练这个整理过的模型,即项目文件2,没有修改任何的超参数,并且保持完全一致的随机种子,但是始终无法完全复现出半年前项目文件1跑出来的结果(按道理来说,随机种子控制好后,整个训练过程都应该能够复现,第一个epoch的accuracy就应该对上)。我找到项目文件1,跑了跑,能复现之前的训练结果。并且,分别训练项目文件1和2的模型,都能重复自己的训练结果,而两个项目文件的结果无法对上。
花了半天的时间反复仔细检查数据集和训练超参数的设置后,也没能看出项目文件2有什么毛病。非常奇怪,为什么同样的模型、配置、服务器、随机种子,在不同的项目文件中出现不同的结果?!实在想不通。
于是,决定动手debug看看问题出在了哪里。
我发现第一个epoch的结果就对不上,所以我猜测问题出在了模型的初始化上,那初始化与什么相关呢?很自然地,我把问题聚焦在了随机种子上,是不是没有有效固定住随机性?所以我将两个项目文件构建model后的参数打印出来看了看,发现,完全不同!
项目文件1中的部分打印结果:
项目文件2中的部分打印结果:
很明显地说明了一件事:同样的随机种子,在这两个项目文件中,产生了完全不一样的初始化值! 这个结果是违背我的常识的,为什么会出现这样的情况?
于是,我 猜测是不是因为两个项目在同一服务器上发生了未知的冲突,所以我copy了一份项目文件1为项目文件3,然后跑项目文件3的初始化结果,发现和项目文件1的初始化结果一致,居然没问题!?那这个项目文件2怎么回事,凭空出现了不同的初始化值?
排除了项目冲突这个猜想后,我把视野放在了模型本身上。我试着print(model)进行观察,发现项目文件2相比项目文件1的模型架构多了一些参数,这些参数是我当初在整理代码并补充新算法时补充定义的(比如:self.gamma = Parameter(torch.randn((1, self.num_heads, 1, 1)))
),但是后面并没有真正用上这个参数。
于是,我又有了一个新的猜想:是不是因为多出来的这些新定义的参数,导致在同一随机种子的设置下,仍然出现不一致的初始化行为?
顺着这个思路,我给项目文件1做了如下简单的尝试:直接给模型架构多定义一个模块,但无需使用它,看看初始化是否受影响。 这里我简单加了个nn.Linear()进去。
代码解释如下,原本的架构为:
class Attention(Module):"""Obtained from timm: github.com:rwightman/pytorch-image-models"""def __init__(self, dim, num_heads=8, attention_dropout=0.1, projection_dropout=0.1):super().__init__()self.num_heads = num_headshead_dim = dim // self.num_headsself.scale = head_dim ** -0.5self.qkv = Linear(dim, dim * 3, bias=False)self.attn_drop = Dropout(attention_dropout)self.proj = Linear(dim, dim)self.proj_drop = Dropout(projection_dropout)self.relu = ReLU()self.eps = 1e-8self.alpha = Parameter(torch.ones(1, self.num_heads, 1, 1), requires_grad=False)self.alpha.data.fill_(1.0)def forward(self, x):B, N, C = x.shapeqkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)q, k, v = qkv[0], qkv[1], qkv[2]...
我在init函数中多定义一行线性层后为:
class Attention(Module):"""Obtained from timm: github.com:rwightman/pytorch-image-models"""def __init__(self, dim, num_heads=8, attention_dropout=0.1, projection_dropout=0.1):super().__init__()self.num_heads = num_headshead_dim = dim // self.num_headsself.scale = head_dim ** -0.5self.qkv = Linear(dim, dim * 3, bias=False)self.attn_drop = Dropout(attention_dropout)self.proj = Linear(dim, dim)self.proj_drop = Dropout(projection_dropout)self.relu = ReLU()self.eps = 1e-8self.alpha = Parameter(torch.ones(1, self.num_heads, 1, 1), requires_grad=False)self.alpha.data.fill_(1.0)self.linear = Linear(dim, dim) # 这里是新加的模块,但是无需使用def forward(self, x):B, N, C = x.shapeqkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)q, k, v = qkv[0], qkv[1], qkv[2]...
于是,打印初始化参数得到:
初始化的结果仍然改变了!!! 看来果然是模型架构的不一致性导致了随机种子“失效”。
2 总结上述问题
两个项目文件,看似模型、超参数、数据集、随机种子、服务器完全一致时,发现训练时两者无法保持完全一致,并且进一步发现两个项目文件在初始化模型参数时就不一致了。
而单独地重复训练每一个项目文件,都能重复自身的结果。
直观感觉就是随机种子并没有有效地作用到另一个项目上,是一个很奇怪的问题,有点违背常识。
3 总结解决方案
训练过程不一致是表象,实际上是模型初始化就不一致了。
如果想要用随机种子控制模型初始化参数完全一致,就必须保证模型的架构完全一致! 但凡在model类的init函数里多定义一个无用参数比如Linear,都会改变整个初始化结果,从而影响后面的训练进程(应该是很微小的影响,但是对于我们复现项目时扣细节来说,会放大这个影响)。
4 可能的解释
咨询了一些遇到过这个问题的同学,大概有如下的可能的解释:在模型的定义中加入了新的模块后,不管是否真正使用,都会影响初始化(已控制了随机种子)。因为加入了新的模块后,整个初始化的顺序会发生改变,于是就乱套了。随机种子只能保证你调用后生成的随机数列是一样的,而在构建模型时的调用顺序,是会随着模型架构的改变而改变的。
相关文章:
【随机种子初始化】一个神经网络模型初始化的大坑
1 问题起因和经过 半年前写了一个模型,取得了不错的效果(简称项目文件1),于是整理了一番代码,保存为了一个新的项目(简称项目文件2)。半年后的今天,我重新训练这个整理过的模型&…...
翻过那座山——Gitlab流水线任务疑难之编译有子模块的项目指南
📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,我们面对的不是…...
手机照片删除后如何恢复
在如今移动互联网和智能手机时代,拍摄照片已经成为了人们常见的一种生活方式,尤其是通过手机拍摄照片已经成为了许多人记录生活点滴、分享经验和表达情感等的必备工具。但是,随着手机照片量的激增,意外删除手机中珍贵照片的事件也…...
SpringBoot 线上服务假死,CPU 内存正常,什么情况?
背景 开发小伙伴都知道线上服务挂掉,基本都是因为cpu或者内存不足,出现GC频繁OOM之类的情况。本篇文章区别以上的情况给小伙伴们带来不一样的服务挂掉。 还记得哔哩哔哩713事故中那场诡计多端的0吗? 图片 对就是这个0,和本次事…...
kotlin从入门到精通之内置类型
基本类型 声明变量 val(value的简写)用来声明一个不可变的变量,这种变量在初始赋值之后就再也不能重新赋值,对应Java中的final变量。 var(variable的简写)用来声明一个可变的变量,这种变量在初始…...
实战指南:使用Spring Boot实现消息的发送和接收
当涉及到消息发送和接收的场景时,可以使用Spring Boot和消息中间件RabbitMQ来实现。下面是一个简单的示例代码,展示了如何在Spring Boot应用程序中创建消息发送者和接收者,并发送和接收一条消息。 首先,你需要进行以下准备工作 确…...
常用的数据结构——栈
目录 1、入栈 2、出栈 3、获取栈顶的元素 4、从栈中查找元素 栈是一种常见的数据结构,栈的特点是后进先出,就像我们叠盘子,拿走上面的盘子才能拿到下一个。java中的栈java.util.Stack是通过java.util.Vector实现的,所以底层都…...
C++完成淄博烧烤节管理系统
背景: 这次我们结合今年淄博烧烤做一个餐厅管理系统,具体需求如下,我们选择的是餐饮商家信息管理 问题描述: 淄博烧烤今年大火,“进淄赶烤”是大家最想干的事情,淄博烧烤大火特火的原因,火的…...
我心中的TOP1编程语言
目录 一、评选最佳编程语言时需要考虑哪些标准 (一)易用性 (二)执行效率 (三)语言功能特性 (四)工具生态环境 (五)开发者社区 二、不同编程语言的优点…...
Linux工具之gdb(含移植到arm-linux系统)
文章目录 文件目录结构移植ncurses库移植gdb移植到arm板调试测试 linux主机:ubuntu-18.04 交叉编译器:arm-buildroot-linux-gnueabihf 开发板kernel:Linux 5.4.0-150-generic x86_64 开发板:100ASK_STM32MP157_PRO开发板 arm-…...
DolphinScheduler
参考 Apache DolphinScheduler v1.3.9 使用手册 内置组件 masterserverworkserverzookeepertask queuealertapiui 设计 去中心化设计 通过zk选举 UI功能 队列管理 Yarn调度器的资源队列 用户管理 租户对应的是Linux系统用户,是Worker执行任务使用的用户 用户…...
10大白帽黑客专用的 Linux 操作系统
平时在影视里见到的黑客都是一顿操作猛如虎,到底他们用的都是啥系统呢? 今天给大家分享十个白帽黑客专用的Linux操作系统。 ▍1. Kali Linux Kali Linux是最著名的Linux发行版,用于道德黑客和渗透测试。Kali Linux由Offensive Security开发&…...
Golang每日一练(leetDay0099) 单词规律I\II Word Pattern
目录 290. 单词规律 Word Pattern 🌟 291. 单词规律 II Word Pattern ii 🌟🌟 🌟 每日一练刷题专栏 🌟 Rust每日一练 专栏 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 …...
linux_centos7.9/ubuntu20.04_下载镜像及百度网盘分享链接
1、镜像下载站点 网易开源镜像:http://mirrors.163.com/ 搜狐开源镜像:http://mirrors.sohu.com/ 阿里开源镜像:https://developer.aliyun.com/mirror/ 首都在线科技股份有限公司:http://mirrors.yun-idc.com/ 常州贝特康姆软件技…...
Reqable HTTP一站式开发+调试工具(小黄鸟作者另一力作、小黄鸟完美替代品)
本文所有教程及源码、软件仅为技术研究。不涉及计算机信息系统功能的删除、修改、增加、干扰,更不会影响计算机信息系统的正常运行。不得将代码用于非法用途,如侵立删!Reqable HTTP一站式开发+调试工具(小黄鸟作者另一力作、小黄鸟替代品) 环境 win10pixel4Android13概览 …...
Yacc 与 Lex 快速入门
Yacc 与 Lex 快速入门 简介: Lex 和 Yacc 是 UNIX 两个非常重要的、功能强大的工具。事实上, 如果你熟练掌握 Lex 和 Yacc 的话,它们的强大功能使创建 FORTRAN 和 C 的编译器如同儿戏。本文详细的讨论了编写自己的语言和编译器所 用到的这两…...
【开源与项目实战:开源实战】80 | 开源实战二(下):从Unix开源开发学习应对大型复杂项目开发
上两节课,我们分别从代码编写、研发管理的角度,学习了如何应对大型复杂软件开发。在研发管理这一部分,我们又讲到比较重要的几点,它们分别是编码规范、单元测试、持续重构和 Code Review。其中,前三点在专栏的理论部分…...
【单周期CPU】LoongArch | 立即数扩展模块Ext | 32位算术逻辑运算单元(ALU)
前言:本章内容主要是演示在vivado下利用Verilog语言进行单周期简易CPU的设计。一步一步自己实现模型机的设计。本章先介绍单周期简易CPU中基本组合逻辑部件的设计。 💻环境:一台内存4GB以上,装有64位Windows操作系统和Vivado 201…...
Python实现数据结构的基础操作
目录 一、列表(List) 二、字典(Dictionary) 三、集合(Set) 四、链表的实现 五、队列和栈 数据结构是计算机科学中非常重要的概念,它用于存储和组织数据以便有效地进行操作。Python作为一种…...
20230624----重返学习-vue-响应式处理思路-仿源码
day-098-ninety-eight-20230624-vue-响应式处理思路-仿源码 vue vue大体概念 Vue是渐进式框架 所谓渐进式框架,就是把一套全面的框架设计体系,拆分成为多个框架,项目中需要用到那些需求,再导入对应的框架,以此来保证…...
【MongoDB】三、使用Java连接MongoDB
【MongoDB】三、使用Java连接MongoDB 实验目的实验内容练习1、开启Eclipse,创建Java Project项目,命名为Mongo12、添加项目依赖的jar包3、创建类MongoDemo4、连接数据库5、查看集合6、创建集合7、删除集合8、查看文档9、插入文档10、更新文档11、删除文档…...
【C++】通讯录的基本实现,附有源码分享
目录 1、运行环境 2、系统实现功能 2.1菜单功能 2.2退出通讯录功能 2.3添加联系人功能 2.4显示联系人功能 2.5删除联系人功能 2.6查找联系人功能 2.7修改联系人功能 2.8清空联系人功能 2.9动态扩容功能 2.10选择优化功能 2.11文件操作 3、源码分享 1、运行环境 …...
UI 自动化测试 —— selenium的简单介绍和使用
selenium 是 web 应用中基于 UI 的自动化测试框架,支持多平台、多浏览器、多语言。 提到 UI 自动化就先了解什么是自动化测试? 目录 1. 自动化测试 2. UI 自动化 2.1 UI 自动化的特点 2.2 UI 自动化测试的优缺点 2.3 UI 自动化测试的使用对象 2.4…...
mybatisPlus中apply的使用以进行联表等复杂sql语句
在 MyBatis-Plus 中,apply() 方法可以用于添加任意的 SQL 片段,包括联表查询。因此,你可以使用 apply() 方法来处理各种类型的联表查询。 使用 apply() 方法的好处是可以在查询条件中直接添加原生的 SQL 片段,而不受 MyBatis-Plu…...
自学Python技术的方法
目录 一、Python技术介绍 二、学习前的准备工作 三、学习时的具体操作 四、如何巩固学习 Python是一种高级编程语言,被广泛用于软件开发、数据分析、人工智能和科学计算等领域。它于1991年由Guido van Rossum创建,并且其简洁、易读的语法以及丰富的标…...
python熟悉python基础语法,了解html网络结构,了解json格式数据,含有字符串
前言 Python网络爬虫是利用Python编写的程序,通过自动化地访问网页、解析html或json数据,并提取所需信息的技术。下面将详细介绍一些与Python网络爬虫相关的重要知识点。 1、Python基础语法: 变量和数据类型:学习如何声明变量以及…...
linux mail -s发送邮件异常解决
异常: Error initializing NSS: Unknown error -8015. "/root/dead.letter" 11/301 . . . message not sent. 出现此问题,大概率是和证书相关。如果没有安装证书,请先安装: 1,下载 yum -y install mailx …...
Netty核心技术七--Google Protobuf
1.编码和解码的基本介绍 编写网络应用程序时,因为数据在网络中传输的都是二进制字节码数据,在发送数据时就需要编码,接收数据时就需要解码 codec(编解码器) 的组成部分有两个:decoder(解码器)和encoder(编码器)。encoder 负责把…...
【Docker】Docker常用命令总结
文章目录 一、帮助命令二、镜像命令三、容器命令四、常用的其他命令 在开发过程中,经常涉及到 docker 的相关操作,本文对常用的指令进行汇总。 一、帮助命令 docker version # 显示docker版本信息 docker info # 显示docker系统信息ÿ…...
React 对比class与Effect Hook优化响应式数据更新监听,感受useEffect真正的强大
还是之前写过的一个组件 import React from "react"export default class index extends React.Component{constructor(props){super(props);this.state {name: "小猫猫"}}componentDidMount ()>{document.title this.state.name;}componentDidUpda…...
免费发帖论坛大全/2022网站seo
最近写GIF解析,使用了很多结构体指针。 常常出现在指针delete的时候 异常。 具体如下: RGBQUAD *GIFGlobolColorTable;//保存全局颜色列表GIFGlobolColorTable new RGBQUAD[gct]; memset(GIFGlobolColorTable,0,gct*sizeof(RGBQUAD)); if (GIFGlobolCo…...
做商铺的网站有那些/seo线下培训课程
python的mysql操作参照 python操作mysql数据库 ,python对mysql的操作基本都可以在教程中学会,由于初次用python使用mysql,经历了一些坑,为了警醒自己和帮助小白少走弯路,在博客中记录下python调用mysql的注意事项&a…...
php网站开发好学吗/如何做营销活动
项目介绍 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时…...
海南省建设与执业资格注册中心网站/广西南宁市有公司网站设计
概述 more 命令是一个基于 vi 编辑器的文本过滤器,它以全屏幕的方式按页显示文本文件的内容。more 指令中内置了许多快捷键可以使用。 注:类似于 cat 命令,但 cat 命令是显示整个文件的内容到屏幕上,而 more 命令会一页一页的显…...
东莞公司网站设计/太原做网站的
一、今天说的是哪种蛇形矩阵蛇形矩阵有多种,今天说的是下面这种回形的蛇形矩阵。如4x4的回形蛇形矩阵如5x5的回形蛇形矩阵通过分析发现,这种矩阵,在走一圈以后又变成一个小2个的矩阵,如5x5的矩阵,从1、2、3。。。到14、…...
怎么做网站收录的关键词/百度搜索网页
CVUI 之 打印 格式化输出文本 Python import numpy as np import cv2 import cvuidef printf_test():WINDOW_NAME Printf-Test# 创建画布frame np.zeros((300, 400, 3), np.uint8)# 初始化窗口cvui.init(WINDOW_NAME)#value 3.1415927while True:# 画布填色frame[:] (50, …...