inplace-operation-error 【已解决】

article/2025/9/23 21:58:51

最近在搞CT医学图像分割模型的领域泛化优化,结果就出现了报错:

 关于这个问题stackoverflow上有非常多的讨论,可以过去围观:

指路:中文版stackoverflow - 堆栈内存溢出 (stackoom.com)

Stack Overflow - Where Developers Learn, Share, & Build Careers

看了很多问题和我这个问题都不太一样。

one of the variables needed for gradient computation has been modified by an inplace operation 归根结底是梯度计算所需的变量之一已被就地操作修改,相信大家都已经尝试过用

with torch.autograd.set_detect_anomaly(True)来查看问题出错的地方,一般能够通过这个方法来找出错误的人,可以看看报错问题的附近能不能使用.clone()或者将+=和*=写完整,这些一般是修改模型时出问题可以考虑的。

但是我是做领域泛化优化的,只改进了训练方式,并没修改模型。在做优化前,我的模型可以正常运行,但是报错却指出我的normalization有问题,如下图所示: 

找一下附近的代码:

def forward_ffn(self, src):src2 = self.linear2(self.dropout2(self.activation(self.linear1(src))))src = src.clone() + self.dropout3(src2)src = self.norm2(src)return srcdef forward(self, src, pos, reference_points, spatial_shapes, level_start_index, padding_mask=None):# self attentionsrc2 = self.self_attn(self.with_pos_embed(src, pos), reference_points, src, spatial_shapes, level_start_index, padding_mask)src = src.clone() + self.dropout1(src2)src = self.norm1(src)# ffnsrc = self.forward_ffn(src)return src

发现这边的代码写得没毛病啊,到底是哪里的问题呢?

后来仔细观察了一下改写后的训练代码

            self.optimizer.zero_grad()self.meta_optimizer.zero_grad()if self.fp16:with torch.autograd.set_detect_anomaly(True):with autocast():output_meta=self.network(data_meta)output_main=self.network(data_main)## theta hat (meta-updata)l1=self.loss(output_meta,target_meta)Lmain=self.loss(output_main,target_main)del output_maindel output_meta# batch for meta updateif do_backprop:## 反向传播梯度self.amp_grad_scaler.scale(l1).backward()# unscale 梯度,可以不影响clip的thresholdself.amp_grad_scaler.unscale_(self.meta_optimizer)# 梯度裁剪,防止梯度爆炸torch.nn.utils.clip_grad_norm_(self.network.parameters(), 12)# 更新模型参数self.amp_grad_scaler.step(self.optimizer)self.amp_grad_scaler.update()self.meta_optimizer.zero_grad()with autocast():output_meta=self.network(data_meta)del data_metaoutput_main=self.network(data_main)del data_mainLadapt=self.loss(output_meta,target_meta)Lrecall=self.loss(output_main,target_main)del output_maindel output_metadel target_meta## theta hat (meta-updata)l2=self.meta_beta*Lrecall+self.meta_gama*Ladapt+Lmainif do_backprop:## 反向传播梯度self.amp_grad_scaler.scale(l2).backward()# unscale 梯度,可以不影响clip的thresholdself.amp_grad_scaler.unscale_(self.optimizer)# 梯度裁剪,防止梯度爆炸torch.nn.utils.clip_grad_norm_(self.network.parameters(), 12)# 更新模型参数self.amp_grad_scaler.step(self.meta_optimizer)self.amp_grad_scaler.update()

文章经过四次前向传播,和两次反向传播,但是每次都是第二次反向传播出错,主要原因在于第二次反向传播用到的loss函数中,用到了第一次反向传播之前计算的一个Loss,因此,直接使用该loss就会出现inplace operation error,因此需要Detach一下将其复制过来,而不是在原来的地址上操作。

l2=self.meta_beta*Lrecall+self.meta_gama*Ladapt+Lmain.detach()

后面就没事了!


http://chatgpt.dhexx.cn/article/ZJXT7ilZ.shtml

相关文章

pandas数据排序sort_values后面inplace=True与inplace=False的实例驱动理解

目 录 1 引子 2 inplace参数理论理解 3 inplace参数实例驱动理解 3.1 inplace True 3.2 inplace False 1 引子 Series 的排序:Series.sort_values(ascendingTrue, inplaceFalse) 参数说明: ascending:默认为True升序排序,为F…

Python中inplace参数

【小白从小学Python、C、Java】 【Python-计算机等级考试二级】 【Python-数据分析】 Python中inplace参数 [太阳]选择题 对于以下python代码表述错误的一项是? import pandas as pd df pd.DataFrame({c1:[11undefined22]}) print(【执行】print(df):\nundefineddf) print(【…

inplace=True (原地操作)

Pytorch的很多地方有inplace这个参数,最近遇到的是nn.ReLU(inplaceTrue)。还有torch.sigmoid_等 inplace默认是False inplace的含义是是否进行覆盖运算。即改变一个tensor的值的时候,不经过复制操作,而是直接在原来的内存上改变它的值 比如&a…

Pytorch中inplace操作

文章目录 前言Inplace操作概述inplace操作的优缺点常见的inplace操作总结参考链接 前言 之前在写训练代码时,遇到了inplace operation导致的问题,所以就了解了一下pytorch的inplace operation,在此记录一下inplace操作的一些知识。报错信息如…

PyTorch的inplace的理解

inplace的理解 我们平时看到的 nn.ReLU(inplaceTrue)、nn.LeakyReLU(inplaceTrue),这些语句中的inplace是什么意思? inplaceTrue指的是进行原地操作,选择进行原地覆盖运算。 比如 x1则是对原值x进行操作,然后将得到的结果又直接覆…

mysql如何改连接端口号_MYSQL修改端口号

系统:Windows Server 2016 MYSQL版本:5.7.20 1、打开MYSQL根目录查看是否存在my.ini,若不存在,创建一个my.ini文件 复制下面的code到my.ini中 [client] port2512 default-character-setutf8 [mysqld] # 设置为自己MYSQL的安装目录…

Linux如何查询mysql的端口号

Linux如何查询mysql的端口号 如何查询mysql的端口号(使用root): netstat -anp|grep mysql netstat -anp|grep mysql

MAC:查看和更改Mysql端口号(保姆级解决方案)

MAC:查看和更改Mysql端口号 第零步: 进入终端,使用sudo su命令,并输入用户密码开启root高权限 sudo su第一步: 终端输入命令如下,输入密码后进入mysql mysql -u root -p第二步: 输入命令(…

查看 mysql端口 和进程_mysql 端口号(怎么查看mysql的端口号)

mysql 端口号(怎么查看mysql的端口号) 2020-05-07 21:54:58 共10个回答 如何查看mysql的端口号 --输入以下命令:SHOWVARIABLESWHEREVARIABLE_NAMEport就可以查看当前连接的端口号,--例如:mysql>SHOWVARIABLESWHEREVARIABLE_NAMEport; mysql的默认端口号是多少 mysql默认端口…

mysql有多少个端口号_mysql默认端口号(mysql端口号是多少)

mysql默认端口号(mysql端口号是多少) 2020-05-07 22:14:36 共10个回答 mysql的默认端口号是多少 mysql默认端口号为3306,修改端口号方法:修改配置文件/etc/my.cnf mysql使用的默认端口号是哪个端口 mysql的默认端口是3306,可以编辑用户目录下的.my.cnf文件进行修改.sqlserver默…

linux mysql修改端口号

1.登陆MySQL数据库 mysql -u root -p 2.输入show global variables like port;查看当前端口号 mysql> show global variables like port; Ps:port后面的值就是当前端口号 3.修改mysql配置文件,一般是在/etc/my.cnf,早期版本有可能是my.conf文件…

宝塔面板修改mysql端口号

为了站点安全起见,常用端口都建议修改,那么宝塔面板的Mysql端口需要怎么修改呢? 1、 找到软件商店-运行环境-Mysql-的设置菜单 2、打开后选择端口选项,将默认的3306改为自定义端口。 3、改完端口后记得在安全菜单中放行修改后的…

mysql有多少个端口号_查看mysql端口号(mysql端口号是多少)

查看mysql端口号(mysql端口号是多少) 2020-05-07 22:11:45 共10个回答 如何查看mysql的端口号 1使用命令showglobalvariableslikeport;查看端口号2修改端口,编辑/etc/my.cnf文件,早期版本有可能是my.conf文件名,增加端口参数,并且设定端口,注意该端口未被使用,保存退出.总结:注…

【修改MySQL端口号(没有my.ini文件)详细图解】

修改MySQL端口号(没有my.ini文件) 前置方案安装服务方案 前置方案 PS:修改MySQL端口号,网上大部分都是修改my.ini文件 有my.ini文件的参考地址 安装服务方案 对于没有my.ini文件使用如下步骤: 1,已安装M…

Docker部署项目更改Mysql端口号

问题情景: 师弟在阿里云服务器上通过Tomcat部署java Web项目 程序端口8080 mysql端口3306 我通过Dokcer部署了前后端分离项目,为了避免端口冲突,服务器6612:3306映射端口。 本以为需要在java后端配置文件中更改url为&#xff1…

linux下查看mysql端口号和修改端口号方法

一、查看端口号 1、登录mysql [rootlocalhost ~]# mysql -uroot -p Enter password: 输入数据库密码; 2、使用show global variables like port; 命令查看端口号, 3307即为当前端口号。 二、修改mysql端口号 1、编辑/etc/my.cnf文件 [rootlocalhost ~]# vi /…

linux下修改mysql端口号

1.登录mysql mysql -u root -p 2.查看当前端口号 show global variables like port; 3.修改端口 vim /etc/my.cnf 4. 增加或修改端口参数,然后保存退出 port3308 5.重启mysql service mysqld restart 6.查看mysql状态 systemctl status mysqld 7.阿里云上安全…

如何修改mysql占用的端口号_修改mysql端口号(mysql的端口号)

修改mysql端口号(mysql的端口号) 2020-05-07 22:12:00 共10个回答 如何查看mysql默认端口号和修改端口号 登录mysql,使用命令showglobalvariableslikeport;查看端口号修改端口在配置文件my.ini,修改后重新启动.[mysqld]port3506 如何修改修改mysql默认端口号3306 在配置文件my.…

虚拟机查看MySQL端口号

先进入MySQL mysql -hhadoop102 -uroot -p 再查看端口号 show variables like ‘port’;

mysql怎么看端口号_mysql端口号(怎么查看mysql的端口号)

mysql端口号(怎么查看mysql的端口号) 2020-05-07 21:54:58 共10个回答 如何查看mysql的端口号 1使用命令showglobalvariableslikeport;查看端口号2修改端口,编辑/etc/my.cnf文件,早期版本有可能是my.conf文件名,增加端口参数,并且设定端口,注意该端口未被使用,保存退出.总结:注…