Pytorch基础:torch.load_state_dict()方法在加载时不会检查类型

相关阅读

Pytorch基础https://blog.csdn.net/weixin_45791458/category_12457644.html?spm=1001.2014.3001.5482


笔者在使用torch.nn.module的load_state_dict中出现了一个问题,一个被注册的张量在加载后居然没有变化,一开始以为是加载出现了问题,但发现其他参数加载成功,思索后发现是注册的张量的类型是整型而checkpoint中保存为浮点数类型,恰好注册时的默认值给的是0,而checkpoint中的浮点数又在0到1之间,因此出现了这个令人困惑的bug。

下面首先复现这个bug。

import torch
import torch.nn as nn

# 定义一个简单的线性模型,参数类型为整数
class SimpleModel(nn.Module):
    def __init__(self):
        super(SimpleModel, self).__init__()
        self.register_buffer('test', torch.tensor(0)) # 注册一个整型张量

# 创建一个简单模型实例
model = SimpleModel()

# 创建一个浮点数作为参数
float_parameter = torch.tensor(0.6)

# 将注册名指向另一个浮点型张量
model.test = float_parameter

# 保存模型
torch.save(model.state_dict(), 'model.pth')

# 直接使用原模型加载
checkpoint = torch.load('model.pth')
model.load_state_dict(checkpoint)

# 打印加载后的参数
print(model.test)

# 直接使用新模型加载
model_1 = SimpleModel()
model_1.load_state_dict(checkpoint)

# 打印加载后的参数
print(model_1.test)

输出:
tensor(0.6000)
tensor(0)

可以看到,当模型中注册的名字(test),指向了一个类型不符的张量后,并不会导致浮点型张量被截断为整型,这是因为此处是直接使用赋值号=,使名字指向了另一个张量。

但使用load_state_dict()方法与使用赋值号是不同的,load_state_dict()方法的实现中,调用了_load_from_state_dict()方法,其中调用了copy_()方法,进行了原位(in-place)数据替换,这可能会进行截断,下面是原位替换的一个例子。

python 复制代码
import torch

# 创建两个张量
a = torch.tensor([[1, 2], [3, 4]])
b = torch.tensor([[5.1, 6.1], [7.1, 8.1]])

# 查看张量对象的id
print(id(a))
print(id(b))

# 查看底层存储的内存地址
print(a.storage().data_ptr())
print(b.storage().data_ptr())

# 将张量 b 中的值复制到张量 a 中
a.copy_(b)

# 打印复制后的结果
print(a)

# 查看张量对象的id
print(id(a))
print(id(b))

# 查看底层存储的内存地址
print(a.storage().data_ptr())
print(b.storage().data_ptr())
python 复制代码
输出:
2604425272672
2604426953808  
2604511348096  
2602930352832  
tensor([[5, 6],
        [7, 8]])
2604425272672
2604426953808
2604511348096
2602930352832

在保存了模型的状态字典后,使用load_state_dict()方法加载后,也不会有任何截断问题,因为对于原模型而言,名字test指向的是一个浮点型张量,此时原位替换,类型吻合。但是对于一个新的模型,此时的test指向的是一个整型张量,此时原位替换,会发生截断。

因此,在注册一个张量时,需要确保其在注册时和保存时的类型吻合,此处除了指形状,还有类型,否则可能会出现意想不到的bug。

相关推荐
桃花键神15 分钟前
AI可信论坛亮点:合合信息分享视觉内容安全技术前沿
人工智能
野蛮的大西瓜36 分钟前
开源呼叫中心中,如何将ASR与IVR菜单结合,实现动态的IVR交互
人工智能·机器人·自动化·音视频·信息与通信
CountingStars6191 小时前
目标检测常用评估指标(metrics)
人工智能·目标检测·目标跟踪
tangjunjun-owen1 小时前
第四节:GLM-4v-9b模型的tokenizer源码解读
人工智能·glm-4v-9b·多模态大模型教程
冰蓝蓝1 小时前
深度学习中的注意力机制:解锁智能模型的新视角
人工智能·深度学习
橙子小哥的代码世界1 小时前
【计算机视觉基础CV-图像分类】01- 从历史源头到深度时代:一文读懂计算机视觉的进化脉络、核心任务与产业蓝图
人工智能·计算机视觉
黄公子学安全2 小时前
Java的基础概念(一)
java·开发语言·python
新加坡内哥谈技术2 小时前
苏黎世联邦理工学院与加州大学伯克利分校推出MaxInfoRL:平衡内在与外在探索的全新强化学习框架
大数据·人工智能·语言模型
程序员一诺2 小时前
【Python使用】嘿马python高级进阶全体系教程第10篇:静态Web服务器-返回固定页面数据,1. 开发自己的静态Web服务器【附代码文档】
后端·python
小木_.2 小时前
【Python 图片下载器】一款专门为爬虫制作的图片下载器,多线程下载,速度快,支持续传/图片缩放/图片压缩/图片转换
爬虫·python·学习·分享·批量下载·图片下载器