如何恢复KerasClassifier?

如何恢复KerasClassifier?,keras,python-3.6,Keras,Python 3.6,在保存了KerasClassifier模型的权重和json配置之后,我需要恢复它并验证结果。 但是如果我恢复了权重和模型,那么我就有了一个连续的对象,如何从中重建原始的KerasClassifier???如果你有两个文件model.json和weights.h5,那么你就可以轻松地加载模型并使用它 from keras.models import model_from_json json_file = open('model.json', 'r') loaded_model_json = js

在保存了KerasClassifier模型的权重和json配置之后,我需要恢复它并验证结果。
但是如果我恢复了权重和模型,那么我就有了一个连续的对象,如何从中重建原始的KerasClassifier???

如果你有两个文件model.json和weights.h5,那么你就可以轻松地加载模型并使用它

from keras.models import model_from_json

json_file = open('model.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
loaded_model.load_weights("model.h5")

# evaluate loaded model on test data
loaded_model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
score = loaded_model.evaluate(X, Y, verbose=0)
print("%s: %.2f%%" % (loaded_model.metrics_names[1], score[1]*100))

我不确定我是否正确理解了你的意思,但提出以下解决方案
KerasClassifier
继承自
BaseWrapper
,它具有以下签名:

def __init__(self, build_fn=None, **sk_params):
    self.build_fn = build_fn
    self.sk_params = sk_params
    self.check_params(sk_params)
好的,什么是构建fn和sk_参数

build\u fn
应该构造、编译并返回一个Keras模型,该模型 然后将用于拟合/预测。下列情况之一 可以将三个值传递给
build\u fn

1.函数
2.实现
\uuuu调用\uuuu
方法的类的实例
3.没有一个这意味着您实现了一个继承自
KerasClassifier
KerasRegressor
。的
\uuuu call\uuuu
方法 当前类将被视为默认的
build\fn


sk_params
同时获取模型参数和拟合参数。法律模式 参数是
build\u fn
的参数。请注意,像所有其他 scikit中的估计器学习,
build\fn
应提供 它的参数,这样您就可以创建估计器,而无需传递任何
sk_参数的值


有些承诺被省略了

您可以在和链接上阅读完整的评论。
由于
build\u fn
需要返回编译后的keras模型的函数(无论是顺序的还是仅仅是
model
),您可以将其作为返回加载模型的值函数传递

编辑您还应该调用带有一些参数的
fit
,以使用该方法恢复模型

作为构建的负载模型\u fn

fit
方法调用一个
build\u fn
,因此每次尝试训练这样的分类器时,您将加载并安装加载的分类器。 例如:

from keras.models import load_model  # or another method - but this one is simpliest
from keras.wrappers.scikit_learn import KerasClassifier

def load_model(*args, **kwargs):
    """probably this function expects sk_params, so you can use it in theory"""
    path="my_model.hd5"
    model = load_model(path)
    return model

keras_classifier = KerasClassifier(load_model, sk_params)  # use your sk_params
keras_classifier.fit(X_tr, y_tr)  # I use slice (1, input_shape) to train
-它将工作,因为加载的模型几乎经过训练和编译。但是它给了你的模型一个小小的改变,即使你将它称为一批大小为1和1的历元

通过构建闭合加载

此外,您还可以先加载模型(如果您希望轻松提供路径,但硬代码路径不可接受),然后返回一个“build_fn-acceptable”函数:

将模型分配给其属性

如果您计划只加载并使用预先训练好的模型,则可以使用any来加载它,分配给
model
属性,而不调用
fit

build_fn = load_model_return_build_fn("model.hd5")
# or the function which realy builds and fits a model
keras_classifier = KerasClassifier(build_fn, sk_params)  # use your sk_params
keras_classifier.model = model  # assign model here, don't call fit
-在这种情况下,您可以显式地将模型设置为其属性。请注意,build\u fn应该是一个coorrect one build\u fn-否则它不会通过
self.check\u params(sk\u params)
测试

从KerasClassifier继承(不像我想的那么容易)
毕竟,我知道的最好的解决方案是从
KerasClassifier
继承,并添加
load
和/或
from_file
方法

class KerasClassifierLoadable(KerasClassifier):
    @classmethod
    def from_file(cls, path, *args, **kwargs):
        keras_classifier = cls(*args, **kwargs)
        keras_classifier.model = load_model(path)
        outp_shape = keras_classifier.model.layers[-1].output_shape[-1]
        if outp_shape > 1:
            keras_classifier.classes_ = np.arange(outp_shape, dtype='int32')
        else:
            raise ValueError("Inconsistent output shape: outp_shape={}".format(outp_shape))
        keras_classifier.n_classes_ = len(keras_classifier.classes_)
        return keras_classifier

    def load(self, path):
        self.model = load_model(path)
        outp_shape = keras_classifier.model.layers[-1].output_shape[-1]
        if outp_shape > 1:
            keras_classifier.classes_ = np.arange(outp_shape, dtype='int32')
        else:
            raise ValueError("Inconsistent output shape: outp_shape={}".format(outp_shape))
        self.n_classes_ = len(self.classes_)
在这里,我们应该将self.classes设置为正确的类标签,但我只使用`范围(0,n_类)中的整数值

用法(
build\u fn
可以是任何合适的
build\u fn
):


你所说的“我如何从中重建原始KerasClassifier”到底是什么意思?如何用给定的
顺序
实例化
KerasClassifier
?嘿,你能发布一些代码并更准确地说明“恢复和验证结果”的含义吗?我已经准备好使用你的代码,但我需要重建原始KerasClassifier,因为它将直接输出类预测,而不是概率。我想知道是否有一种简单的方法可以从顺序存储模型重建原始的Keras分类器
class KerasClassifierLoadable(KerasClassifier):
    @classmethod
    def from_file(cls, path, *args, **kwargs):
        keras_classifier = cls(*args, **kwargs)
        keras_classifier.model = load_model(path)
        outp_shape = keras_classifier.model.layers[-1].output_shape[-1]
        if outp_shape > 1:
            keras_classifier.classes_ = np.arange(outp_shape, dtype='int32')
        else:
            raise ValueError("Inconsistent output shape: outp_shape={}".format(outp_shape))
        keras_classifier.n_classes_ = len(keras_classifier.classes_)
        return keras_classifier

    def load(self, path):
        self.model = load_model(path)
        outp_shape = keras_classifier.model.layers[-1].output_shape[-1]
        if outp_shape > 1:
            keras_classifier.classes_ = np.arange(outp_shape, dtype='int32')
        else:
            raise ValueError("Inconsistent output shape: outp_shape={}".format(outp_shape))
        self.n_classes_ = len(self.classes_)
keras_classifier = KerasClassifierLoadable.from_file("model.hd5", build_fn=build_fn)

keras_classifier = KerasClassifierLoadable(build_fn=build_fn)
keras_classifier.load("model.hd5")