如何在位级别上确保持久性sklearn模型

问题描述 投票:0回答:1

我想创建一个持久的scikit-learn模型,稍后通过哈希对其进行引用。使用joblib进行序列化,如果我的数据没有变化,我期望完全(位级)完整性。但是每次我运行代码时,磁盘上的模型文件都会具有不同的哈希值。为什么会这样,并且每次我运行代码不变时如何进行真正相同的序列化?设置固定的种子无济于事(在这个简单的示例中,不确定sklearn的算法是否完全利用随机数)。

import numpy as np
from sklearn import linear_model
import joblib
import hashlib

# set a fixed seed … 
np.random.seed(1979)

# internal md5sum function
def md5(fname):
    hash_md5 = hashlib.md5()
    with open(fname, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()

# dummy regression data
X = [[0., 0., 0.,1.], [1.,0.,0.,0.], [2.,2.,0.,1.], [2.,5.,1.,0.]]
Y = [[0.1, -0.2], [0.9, 1.1], [6.2, 5.9], [11.9, 12.3]]

# create model
reg = linear_model.LinearRegression()

# save model to disk to make it persistent
with open("reg.joblib", "w"):
    joblib.dump(reg, "reg.joblib")

# load persistant model from disk
with open("reg.joblib", "r"):
    model = joblib.load("reg.joblib")

# fit & predict
reg.fit(X,Y)
model.fit(X,Y)
myprediction1 = reg.predict([[2., 2., 0.1, 1.1]])
myprediction2 = model.predict([[2., 2., 0.1, 1.1]])

# run several times … why does md5sum change everytime?
print(md5("reg.joblib"))
print(myprediction1, myprediction2)
python hash scikit-learn joblib
1个回答
0
投票

经过一番研究,我找到了我问题的答案。对于每次运行,joblib文件具有不同的哈希值的问题与scikit-learn或训练后的模型无关。实际上,可以使用joblib.hash(reg)证明纯模型的MD5和是相同的,这意味着训练后的回归模型的权重没有变化。这个方便的功能现在也解决了我原来的“业务”问题。

转储文件的不可复制MD5总和的根本原因在于pickle所基于的基础joblib.dump序列化模型的实现。决定性的提示来自How to hash a large object (dataset) in Python?old finding在互联网深度的某个位置提供了一些背景信息:

由于pickle数据格式实际上是一种很小的面向堆栈的编程语言,并且某些对象的编码具有一定的自由度,所以两个模块可能为同一输入对象生成不同的数据流。但是,可以保证它们始终能够读取彼此的数据流。

© www.soinside.com 2019 - 2024. All rights reserved.