我有一个Python 3.6脚本,它训练SKLearn模型,然后使用以下代码保存模型:
with open('filepath', 'wb') as f:
pickle.dump(trained_model, f, protocol=2)
当我尝试在python 3.6中加载pickle时,事情就好了:
>>with open('filepath', 'rb') as f:
>> model = pickle.load(f)
>>
>>model
RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
max_depth=None, max_features='auto', max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, n_estimators=80, n_jobs=1,
oob_score=False, random_state=None, verbose=0,
warm_start=False)
当我在Python 2.7中运行这个相同的pickle.load命令时,我收到以下错误:
>>with open('filepath', 'rb') as f:
>> model = pickle.load(f)
ValueError: non-string names in Numpy dtype unpickling
查看文档和类似情况,将协议设置为2 应该使pickle文件兼容。是什么导致了这个问题,我该如何解决它?
答案 0 :(得分:1)
您可以使用pickle._load()
代替.load()
来force using a pure-Python implementation,并获得更有用的追溯。
如果故障部分在numpy
的代码中,您仍然需要使用C调试器或手动跟踪源代码...
...或者在numpy
的unpickling例程中使用numpy
pickle format spec 并尝试猜测它有什么问题!
pickletools.dis()
为您做到了这一点!它会打印一个反汇编数据的反汇编,并附有补偿。虽然您可能仍需要规范来查明违规的性质。尽管如此,3.4. Model persistence — scikit-learn 0.19.1 documentation确实警告说不支持在另一个版本和/或架构中加载模型数据,而是建议保存源材料。