加载pickle模型参数时出现sklearn模块缺失错误求助
解决pickle加载模型时ModuleNotFoundError: No module named 'sklearn.metrics.regression'的问题
问题背景
使用以下代码加载pickle格式的模型参数文件:
import pickle model_params = pickle.load(open('./cp/logP/model_parameters.pkl', 'rb'))
本地MacOS环境(scikit-learn 0.20.2、PyTorch 1.13.1)运行正常,但在GPU云服务器(scikit-learn 1.2.1、PyTorch 1.6.0、Python 3.8)触发报错,提示找不到sklearn.metrics.regression模块。该模型文件包含r2_score等评估指标,来自ReLeaSE项目,未直接调用scikit-learn,推测是pickle反序列化依赖旧版本模块路径导致。
问题原因
scikit-learn版本迭代中,sklearn.metrics.regression子模块被合并到sklearn.metrics主模块中,新版本不再保留该子模块。而pickle序列化时会记录对象的原始模块路径,反序列化时要求完全匹配,因此新版本环境无法识别旧路径的模块。
解决办法
1. 降级scikit-learn到匹配版本
直接将云服务器的scikit-learn版本降级到与本地一致的0.20.2,确保环境依赖完全匹配:
pip install scikit-learn==0.20.2
2. 创建模块别名兼容旧路径
若不想降级版本,可手动创建兼容模块:
- 在Python环境的
site-packages/sklearn/metrics目录下,新建regression.py文件 - 在文件中添加以下代码,将新版本的指标函数导入到旧模块路径下:
这样pickle反序列化时就能找到对应的模块和函数。from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error __all__ = ['r2_score', 'mean_squared_error', 'mean_absolute_error']
3. 自定义Unpickler替换模块路径(进阶)
在加载pickle文件时,自定义反序列化逻辑,将旧模块路径映射到新路径:
import pickle class CustomUnpickler(pickle.Unpickler): def find_class(self, module, name): # 将旧模块路径替换为新路径 if module == 'sklearn.metrics.regression': return getattr(__import__('sklearn.metrics'), name) return super().find_class(module, name) # 使用自定义Unpickler加载文件 with open('./cp/logP/model_parameters.pkl', 'rb') as f: model_params = CustomUnpickler(f).load()
内容的提问来源于stack exchange,提问作者learner
相关产品推荐
相关产品推荐

