Traceback (most recent call last): File "C:\Users\唐添美.DESKTOP-95B881R\Desktop\MNIST实现\test.py", line 38, in <module> mynet = torch.load('MNIST_4_acc_0.9692999720573425.pth', map_location=torch.device('cpu')) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\唐添美.DESKTOP-95B881R\.conda\envs\python高级应用\Lib\site-packages\torch\serialization.py", line 1524, in load raise pickle.UnpicklingError(_get_wo_message(str(e))) from None _pickle.UnpicklingError: Weights only load failed. This file can still be loaded, to do so you have two options, do those steps only if you trust the source of the checkpoint. (1) In PyTorch 2.6, we changed the default value of the `weights_only` argument in `torch.load` from `False` to `True`. Re-running `torch.load` with `weights_only` set to `False` will likely succeed, but it can result in arbitrary code execution. Do it only if you got the file from a trusted source. (2) Alternatively, to load with `weights_only=True` please check the recommended steps in the following error message. WeightsUnpickler error: Unsupported global: GLOBAL __main__.MyNet was not an allowed global by default. Please use `torch.serialization.add_safe_globals([__main__.MyNet])` or the `torch.serialization.safe_globals([__main__.MyNet])` context manager to allowlist this global if you trust this class/function. Check the documentation of torch.load to learn more about types accepted by default with weights_only https://pytorch.org/docs/stable/generated/torch.load.html. 针对上述报告着重修改下列代码 mynet = torch.load('MNIST_4_acc_0.9692999720573425.pth', map_location=torch.device('cpu'))
时间: 2025-05-28 14:46:47 浏览: 25
### PyTorch加载模型时解决`_pickle.UnpicklingError`错误的方法
当在PyTorch中使用`torch.load`函数加载模型权重文件时,可能会遇到`_pickle.UnpicklingError`错误。这种错误通常发生在序列化和反序列化的环境中不一致的情况下。以下是可能的原因以及解决方案:
#### 原因分析
1. **模块路径问题**
如果定义模型的类位于脚本中的`__main__`命名空间下,则在尝试通过`torch.load`恢复模型实例时会引发此错误[^1]。
2. **Python版本或环境差异**
加载模型的环境与保存模型的环境可能存在差异,例如不同的Python解释器版本或者不同版本的依赖库[^2]。
3. **`weights_only=True`参数的作用**
使用`torch.save(model.state_dict(), PATH)`仅保存模型的状态字典而非整个模型对象可以有效规避此类问题。如果设置`map_location`参数并指定设备映射也可以帮助解决问题[^3]。
#### 解决方案
##### 方法一:重构代码结构以避免`__main__`命名冲突
将模型定义移出`if __name__ == "__main__":`块之外,并将其放置在一个独立的模块中导入。这样能够确保模型类可以在任何地方被正确解析而不会受限于当前运行脚本的上下文。
```python
# model.py 文件内容如下:
import torch.nn as nn
class MyNet(nn.Module):
def __init__(self):
super(MyNet, self).__init__()
self.fc = nn.Linear(10, 1)
def forward(self, x):
return self.fc(x)
```
随后,在主程序中引入该模型类而不是直接定义它:
```python
from model import MyNet
model = MyNet()
state_dict = torch.load('model.pth')
model.load_state_dict(state_dict)
```
##### 方法二:只存储状态字典而不存完整的模型对象
推荐的做法是仅仅保存网络层参数即状态字典(`state_dict`),这不仅减少了磁盘占用还提高了兼容性和灵活性。
```python
torch.save(model.state_dict(), 'model_weights.pth') # 只保存权重
loaded_state_dict = torch.load('model_weights.pth', map_location=torch.device('cpu'))
new_model = MyNet() # 创建新的模型实例
new_model.load_state_dict(loaded_state_dict) # 载入之前训练好的权重
```
此处需要注意的是,即使原始模型是在GPU上创建的,只要设置了合适的`map_location`选项就可以顺利迁移到CPU或其他目标设备上去执行推理操作[^4]。
##### 方法三:调整Pickler的安全策略 (适用于高级场景)
对于某些特定需求下的安全性考量,可以通过自定义方式修改默认行为来放宽限制条件;不过一般情况下并不建议这样做除非完全理解其潜在风险。
---
### 总结
综上所述,最简单可靠的办法就是采用方法二——单独处理模型参数并通过重新构建相同的架构后再应用这些已学得的知识表示形式完成迁移过程。同时也要注意保持源端口与目的端之间的一致性比如软件栈配置等方面因素的影响以免再次触发类似的异常状况。
阅读全文
相关推荐

















