Some day ago I was trying to add a Keras model to scikit-learn Pipeline using SKLearnClassifier (wrapper), but I got this error when doing .fit() (notwithstanding the model was already compiled):
RuntimeError: Given model needs to be compiled, and have a loss and an optimizer.
So I made this example code to check if the clone_model function that the API uses does indeed keep the compiled model:
from keras.layers import Dense, Input
from keras.models import Sequential, clone_model
clf = Sequential()
clf.add(Input((7,)))
clf.add(Dense(8, activation="relu"))
clf.add(Dense(1, activation="sigmoid"))
clf.compile(optimizer="adam", loss="binary_crossentropy", metrics=["accuracy"])
print("Original compiled?", clf.compiled)
cloned = clone_model(clf)
print("Cloned compiled?", cloned.compiled)
And the output:
Original compiled? True
Cloned compiled? False
I think that's probably the reason why SKLearnClassifier is not working well. Unfortunately, I couldn't find a way to solve this issue.
Comment From: de-odex
I was able to work around this issue by passing a function to SKLearnClassifier
instead of the instance. Not sure why this works though
E: seems like fit()
calls _get_model()
which always clones the model: https://github.com/keras-team/keras/blob/v3.8.0/keras/src/wrappers/sklearn_wrapper.py#L146. Doesn't happen if you use a function/callable for model=
Comment From: J-ATJ
I'm glad to say that the proposed solution worked perfectly, I was able to integrate the Neural Network to the SKlearn Pipeline and export it to use it in another Python project.
I was able to work around this issue by passing a function to
SKLearnClassifier
instead of the instance. Not sure why this works thoughE: seems like
fit()
calls_get_model()
which always clones the model: https://github.com/keras-team/keras/blob/v3.8.0/keras/src/wrappers/sklearn_wrapper.py#L146. Doesn't happen if you use a function/callable formodel=