前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【踩坑】PyCharm和Terminal中模型/卷积的输出结果不一样

【踩坑】PyCharm和Terminal中模型/卷积的输出结果不一样

作者头像
小锋学长生活大爆炸
发布2024-05-25 09:09:17
600
发布2024-05-25 09:09:17
举报

目录

背景说明

问题分析

解决方法

背景说明

使用同一套代码、同一个虚拟环境、同样的输入文件、同一个GPU、固定的随机种子、同一个系统环境。也就是除了pycharm和terminal,其他所有的条件都是一样的。但是发现,在Pycharm中直接点运行,和在terminal中通过python xxx运行,两者的模型的输出结果竟然有差异。虽然差异不同,但可以看出很小 (这时候直觉上就可以怀疑是精度问题了)。


快餐时代,先说结论,感兴趣的可再往后看分析过程:

在两种方式下,对输入数据和模型、权重看dtype虽然都显示float32,但是实际上并非如此。如果在推理之前强制把输入数据明确指定为float32或者float64,那pycharm和terminal的输出就都一样了。猜测可能pycharm中pytorch默认读取数据是float32,terminal中默认是float64。也可能是其他原因导致的实际读取精度不一样,比如模型训练时候保存的权重就有精度问题?欢迎评论区补充~


问题分析

1、对于模型,逐层看一下是哪个层开始出问题的。

代码语言:javascript
复制
def forward(self, x, mode='eval'):
    x = self.layer1(x)
    print(x)
    exit()

如果layer1没问题,那就换成layer2继续看。发现我的情况是在layer1就出问题了。

2、对于目标层,再挨个看是哪个模块开始出问题的。

代码语言:javascript
复制
print(model.layer1[:1](data_a))
print(model.layer1[:2](data_a))
# ... ... 同上一层一层加

发现是在卷积层出的问题:

代码语言:javascript
复制
nn.Conv2d(3, 32, kernel_size=3, padding=1, bias=is_bias),

由于随机种子已经固定了,卷积的输出应该也不会发生变化才对。

3、检查下输入数据模型的精度

代码语言:javascript
复制
print(data_a.dtype)
print(model.layer1[2].weight.dtype)
print(model.layer1[2].bias.dtype)

显示的默认都是float32类型。看不出来什么差异。

4、尝试强制指定数据类型

代码语言:javascript
复制
# 输入数据指定为double类型(也就是float64)
model(data_a.double())
代码语言:javascript
复制
# 卷积指定为double类型(也就是float64)
nn.Conv2d(3, 32, kernel_size=3, padding=1, bias=is_bias).double(),

再次运行,发现两者的结果一致了。但是发现改为float()时,pycharm运行能变,而terminal的没变(即还是double时候的结果)。暂不清楚为何terminal的改不了float。

解决方法

那么知道了是pytorch的精度问题,为了统一管理,只需要在代码最开始就指定精度类型。

代码语言:javascript
复制
if __name__ == '__main__':
    torch.set_default_dtype(torch.double)
    # xxxxx
    # xxxxx

或者仅在需要的时候转一下类型:

代码语言:javascript
复制
out_a = model(data_a.double())
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景说明
  • 问题分析
  • 解决方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档