微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将 Deap 模型存储为泡菜对象

如何解决将 Deap 模型存储为泡菜对象

我最近一直在尝试首先创建一个基于 Deap 库 (https://deap.readthedocs.io/en/master/) 进行某种形式进化的类,一旦经过训练,它就会存储为一个泡菜对象。我面临的问题的最小工作示例如下:

## minimal test
import random
from deap import base,creator,tools
import dill as pickle

def store_model(model_class,path,verbose = True):
    
    f = open(path,"wb")
    pickle.dump(model_class,f)
    f.close()
    
    if verbose:
        print("Stored the model info!")
    

def load_model(path,verbose = True):

    
    f = open(path,"rb")
    unpickled_model = pickle.load(f)
    f.close()

    return unpickled_model

class TestClass:

    def __init__(self):
        self.creator = creator
        self.toolBox = base.ToolBox()
        self.total_params = 5
        self.base = base


    def mutReg(self,individual,p=1):
        """
        Custom mutation operator used for regularization optimization.

        :param individual: individual (vector of floats)
        :return individual: An individual solution.
        """

        individual[0] += random.random() * self.reg_constant
        return individual,def somefun(self):
        
        self.toolBox.register("attr_float",random.uniform,0.00001,0.999999)
        self.creator.create("fitnessMulti",self.base.fitness,weights=(1.0,))
        self.creator.create("Individual",list,fitness=self.creator.fitnessMulti)

        self.toolBox.register("attr_float",0.999999)
        self.toolBox.register("individual",tools.initRepeat,self.creator.Individual,self.toolBox.attr_float,n=self.total_params)
        self.toolBox.register("population",self.toolBox.individual,n=100)
        self.toolBox.register("mate",tools.cxUniform,indpb=0.5)
        self.toolBox.register("mutate",tools.mutGaussian,mu=0,sigma=0.2,indpb=0.2)
        self.toolBox.register("mutReg",self.mutReg)
        self.toolBox.register("select",tools.selTournament)




clx = TestClass()
clx.somefun() # initialize the evolution classes

store_model(clx,"test.pickle") # Store as a pickled class

model = load_model("test.pickle") # Load as a class

print(model)

在这里,如果我只是将它作为 python minimal_test_load.py 运行,它工作正常,输出存储的类:

Stored the model info!
<__main__.TestClass object at 0x7f640308d190>

但是,如果我尝试从不同的 python 文件调用 load_model(pickled_object_path),它会抛出:

AttributeError: Can't get attribute 'Individual' on <module 'deap.creator' from '/home/someuser/miniconda3/envs/someenv/lib/python3.9/site-packages/deap-1.3.1-py3.9-linux-x86_64.egg/deap/creator.py'>

问题似乎是 deap 库额外创建的新类,如果环境发生变化,pickle 无法识别这些类。是否有针对此类问题的任何已知解决方案?我想要实现的只是加载一个腌制对象,并能够从任何新的 Python 脚本(或例如笔记本)运行一些(它的)函数

谢谢!

解决方法

我能够绕过这个问题(工作结果如下):

导入创建者时,我全局创建了

creator.create("FitnessMulti",self.base.Fitness,weights=(1.0,))
creator.create("Individual",list,fitness=self.creator.FitnessMulti)

属性。通过在其他地方加载腌制对象时执行相同操作,在加载对象时已经定义了这些类属性(请参阅原始问题中的 load_model),它完美无缺。如果有比创建全局变量更优雅的解决方案,我仍然想知道!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。