由于不可克隆性,将 KerasRegressor 与 cross_validate 一起使用失败
Posted
技术标签:
【中文标题】由于不可克隆性,将 KerasRegressor 与 cross_validate 一起使用失败【英文标题】:Using KerasRegressor with cross_validate fails because of uncloneability 【发布时间】:2021-11-19 18:41:52 【问题描述】:我正在使用 Keras 的 sklearn 包装器作为回归器,即 tf.keras.wrappers.scikit_learn.KerasRegressor
。
我希望这个回归器在 sklearn 的交叉验证方案中工作,即sklearn.model_selection.cross_validate
。
回归器通常在没有 CV 的情况下工作。
但是,后者失败了,因为我在回归器的 __init__
方法中有一个必要的参数,它定义了批处理输入形状,并且它似乎丢失了。
这似乎是因为MyRegressor
或KerasRegressor
不能使用clone(estimator)
正确克隆。具体报错信息为:
KeyError: 'batch_input_shape'
有没有办法让MyRegressor
与cross_validate
一起工作?我是否以某种方式违反了 sklearn 的要求?
请看这个精简的工作示例:
from sklearn.datasets import make_regression
from sklearn.model_selection import cross_validate
from tensorflow.keras.layers import Dense, LSTM
from tensorflow.keras.models import Sequential
from tensorflow.keras.wrappers.scikit_learn import KerasRegressor
class MyRegressor(KerasRegressor):
def __init__(self, batch_input_shape, build_fn=None, **kwargs):
self.batch_input_shape = batch_input_shape
super().__init__(**kwargs)
def __call__(self, *kwargs):
model = Sequential([
LSTM(16, stateful=True, batch_input_shape=self.batch_input_shape),
Dense(1),
])
model.compile(optimizer='adam', loss='mean_squared_error', metrics=['RootMeanSquaredError'])
return model
def reset_states(self):
self.model.reset_states()
X, y = make_regression(6400, 5)
X = X.reshape(X.shape[0], 1, X.shape[1])
batch_size = 64
batch_input_shape = (batch_size, 1, X.shape[-1])
# Works fine
reg = MyRegressor(batch_input_shape)
for i in range(10):
reg.fit(X, y, batch_size=batch_size)
reg.reset_states()
# Doesn't work
reg = MyRegressor(batch_input_shape)
results = cross_validate(reg, X, y, scoring=['neg_mean_squared_error'])
【问题讨论】:
【参考方案1】:可克隆性需要正确的get_params
方法。大多数情况下,这是通过继承 sklearn 的 BaseEstimator
获得的,但 KerasRegressor
直接实现了它自己的 (source)。它的执行方式与您的附加 batch_input_shape
不兼容;您可以对其进行调整以使其正常工作:
def get_params(self, deep=False):
res = self.sk_params.copy() # sk_params was set by KerasRegressor.__init__
res.update(
'build_fn': self.build_fn,
'batch_input_shape': self.batch_input_shape,
)
return res
(在此更新后,我在您的示例中遇到关于输入形状的错误。但我不太熟悉批量大小和 keras 以便能够回答后续问题。)
【讨论】:
感谢您的回答。这确实解决了最初的错误消息。后来产生的问题来自cross_validate
调用reg.fit
而没有定义batch_input_shape
。我不知道这是否真的可能,因为我认为 sklearn 只假设 X
和 y
用于 fit
方法。
@Felix, cross_validate
使用 fit_params
字典。 (但这并没有解决我的错误。)
感谢您的提示。你是对的,这并没有——但实际上应该——解决了这个问题。这是因为BaseWrapper
's fit
method is limited 到的一组参数并不代表KerasRegressor
。源代码中还有更多内容:“已弃用。请改用Sci-Keras。”以上是关于由于不可克隆性,将 KerasRegressor 与 cross_validate 一起使用失败的主要内容,如果未能解决你的问题,请参考以下文章
使用提前停止 - gridsearchcv - kerasregressor
Clonal hematopoiesis of indeterminate potential(意义不明的克隆性造血)-CHIP