首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Deap模型存储为pickle对象

将Deap模型存储为pickle对象
EN

Stack Overflow用户
提问于 2021-04-01 03:25:36
回答 1查看 54关注 0票数 0

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

代码语言:javascript
复制
## 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", random.uniform, 0.00001, 0.999999)
        self.toolbox.register("individual",
                         tools.initRepeat,
                         self.creator.Individual,
                         self.toolbox.attr_float,
                         n=self.total_params)
        self.toolbox.register("population",
                         tools.initRepeat,
                         list,
                         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的身份运行它,它可以很好地工作,输出存储的类:

代码语言:javascript
复制
Stored the model info!
<__main__.TestClass object at 0x7f640308d190>

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

代码语言:javascript
复制
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将无法识别这些新类。对于这类问题,是否有已知的解决方案?我想要实现的是加载一个pickled对象,并且能够从任何新的python脚本(例如notebook )运行一些(它的)函数。

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2021-04-01 16:00:00

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

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

代码语言:javascript
复制
creator.create("FitnessMulti", self.base.Fitness, weights=(1.0, ))
creator.create("Individual", list, fitness=self.creator.FitnessMulti)

属性。通过在其他地方加载酸洗过的对象时执行相同的操作,这些类属性在加载对象时就已经定义好了(参见原始问题中的load_model ),它可以完美地工作。如果有比创建全局变量更好的解决方案,我还是想知道!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66894090

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档