keras
keras copied to clipboard
TypeError: can't pickle _thread.RLock objects when using KerasClassifier with Keras and RandomizedSearchCV
I created a simple neural network for binary spam/ham text classification using pretrained BERT transformer. Now I want to apply randomized search for tuning the hyperparameters. For now the only hyperparameter I would like to tune is the dropout regularization probability.
I set up a sklearn pipeline with scikeras's KerasClassifier that contains my custom build_sequential_nn()
method. When merely fitting the pipeline, everything is fine; however, when I pass the pipeline into a sklearn RandomizedSearchCV
, the following error message pops up:
TypeError: can't pickle _thread.RLock objects
Full error message will be detailed at the end of the post.
A full reproducible code is as follows, including sample data:
import numpy as np
import pandas as pd
import sklearn
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.pipeline import Pipeline
from sklearn.model_selection import RandomizedSearchCV
from scikeras.wrappers import KerasClassifier
import tensorflow_hub as hub
import tensorflow as tf
import tensorflow_text
from tensorflow.keras.layers import Input, Dropout, Dense
class BertPreprocessor(TransformerMixin, BaseEstimator):
def __init__(self, preprocessor_model):
super().__init__()
self.preprocessor_model = preprocessor_model
def fit(self, X=None, y=None):
return self
def transform(self, X, y=None):
return self.preprocessor_model(X)
class BertEncoder(TransformerMixin, BaseEstimator):
def __init__(self, encoder_model):
super().__init__()
self.encoder_model = encoder_model
def fit(self, X=None, y=None):
return self
def transform(self, X, y=None):
return pd.DataFrame(self.encoder_model(X)['pooled_output'])
def build_nn_sequential(dropout_prob=0.1, epochs=10):
model = Sequential()
model.add(Input(shape=768, name='bert_pooled_output'))
model.add(Dropout(dropout_prob, name='dropout'))
model.add(Dense(1, activation='sigmoid', name='classification_output'))
metrics_list = [
tf.keras.metrics.AUC(name='auc'),
tf.keras.metrics.BinaryAccuracy(name='accuracy')
]
model.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = metrics_list)
return model
# Automatically fetch BERT preprocessor and encoder
bert_encoder_url = "https://tfhub.dev/tensorflow/bert_en_uncased_L-12_H-768_A-12/4"
bert_preprocessor_url = "https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3"
bert_preprocessor_model = hub.KerasLayer(bert_preprocessor_url)
bert_encoder_model = hub.KerasLayer(bert_encoder_url)
# Get train data
df = pd.read_json(...) # see data also below
X_train_ = df['comment_text']
y_train_ = df['label']
pipe = Pipeline([
('preprocess', BertPreprocessor(bert_preprocessor_model)),
('encode', BertEncoder(bert_encoder_model)),
('model', KerasClassifier(build_fn=build_nn_sequential)),
])
# pipe.fit(X_train_, y_train_) # This evaluates fine!
search_spaces = ({
'model__dropout_prob': np.logspace(np.log10(0.05), np.log10(0.67), 10),
'model__epochs': [10, 20, 30],
})
search = RandomizedSearchCV(
estimator=pipe,
param_distributions=search_spaces,
scoring='roc_auc',
cv=3,
verbose=0
).fit(X_train_, y_train_) # <--- row where error pops up
Sample data:
df = pd.read_json('{"comment_text":{"0":"problem wanted say problem trying redirect event schedule pakistan NUMBERTAG NUMBERTAG pakistan mother fucker boy want married sister ohhhh love sister boob hmmmmm yummyy","1":"get life fucking loser question ask ask katie goulet picture","2":"cum drinker hey wat nigga thought u could ban took long cuz wa busy az hell recently ill keep cumming back take word cumdrinker","3":"liar liar pant fire seriously looked contribution tennis portal page tennis page ha descussion ever please lie NUMBERTAG NUMBERTAG NUMBERTAG NUMBERTAG","4":"stop writing p nothing discus given lack bsinc education diplomacy","5":"wa fucking page one edit page","6":"question mad gay","7":"warning page nerd please leave one stay girl though pleeeeeeeeeeeeeaaaaaaaaaaaaaaaaaaaaaassssssssssssssssseeeeeeeeeeeee NUMBERTAG oneoneoneoneoneoneoneoneoneoneoenone","8":"full shit","9":"go fuck conrad black cheated thousand people pension anyone defends hm asshole apologist evil","10":"list office bearer national union student australia wp userfy userfied page located","11":"talk history scottish national party claim spying hi sentence someone belief npov claim mean someone belief npov claim","12":"section meant vice review btw magazine website writer name attached also like richardwilson NUMBERTAG even know question ninjarobotpirate wa responding happy criticise answer \\u2026 \\u2026 btw NUMBERTAG far know none editor either albanian croatian maybe airplane vision quite good think take care","13":"next time subtweet","14":"physicsyo yo yo dog","15":"self censorship tv show might might notable tv pre empted breaking news notable happens time","16":"article contains information soursed huddersfield aa street street","17":"utc onto something centrifugal force experienced mass exhibiting inertia result tiny little bullet hitting side ride merry go round rueda puthoff haisch described zero point field electronic lorenz equation coupling inertial frame reference give mass inertial reluctance rather resistance enable describe change velocity direction compare ac v dc tesla v edison NUMBERTAG NUMBERTAG NUMBERTAG june NUMBERTAG","18":"meant wa meant state either unblock create new account rendering block useless simple","19":"NUMBERTAG utc hi NUMBERTAG must mistakenly thought ian wa original member b c always viewed band definitive axeman NUMBERTAG yeah almost bought akai headrush looper year ago notorious role cab one guitarist recording settled bos loop station instead rather headrush boomerang due two reliability price issue respectively check hovercraft southpacific auburn lull kind hallucinitory guitar looping thought cab new lineup wa incredible saw NUMBERTAG skipped classic lineup NUMBERTAG compare two performance wise best NUMBERTAG NUMBERTAG NUMBERTAG may"},"label":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0}}')
Full error message:
TypeError Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_18240\1200168424.py in <module>
63 cv=3,
64 verbose=0
---> 65 ).fit(X_train_, y_train_)
66
67 # print(f"Best model parameters: {search.best_params_}, best score {search.best_score_}.")
~\AppData\Local\Programs\Python\Python37\lib\site-packages\skopt\searchcv.py in fit(self, X, y, groups, callback, **fit_params)
464 self.optimizer_kwargs_ = dict(self.optimizer_kwargs)
465
--> 466 super().fit(X=X, y=y, groups=groups, **fit_params)
467
468 # BaseSearchCV never ranked train scores,
~\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\model_selection\_search.py in fit(self, X, y, groups, **fit_params)
803 n_splits = cv_orig.get_n_splits(X, y, groups)
804
--> 805 base_estimator = clone(self.estimator)
806
807 parallel = Parallel(n_jobs=self.n_jobs, pre_dispatch=self.pre_dispatch)
~\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\base.py in clone(estimator, safe)
84 new_object_params = estimator.get_params(deep=False)
85 for name, param in new_object_params.items():
---> 86 new_object_params[name] = clone(param, safe=False)
87 new_object = klass(**new_object_params)
88 params_set = new_object.get_params(deep=False)
~\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\base.py in clone(estimator, safe)
62 # XXX: not handling dictionaries
63 if estimator_type in (list, tuple, set, frozenset):
---> 64 return estimator_type([clone(e, safe=safe) for e in estimator])
65 elif not hasattr(estimator, "get_params") or isinstance(estimator, type):
66 if not safe:
~\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\base.py in <listcomp>(.0)
62 # XXX: not handling dictionaries
63 if estimator_type in (list, tuple, set, frozenset):
---> 64 return estimator_type([clone(e, safe=safe) for e in estimator])
65 elif not hasattr(estimator, "get_params") or isinstance(estimator, type):
66 if not safe:
~\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\base.py in clone(estimator, safe)
62 # XXX: not handling dictionaries
63 if estimator_type in (list, tuple, set, frozenset):
---> 64 return estimator_type([clone(e, safe=safe) for e in estimator])
65 elif not hasattr(estimator, "get_params") or isinstance(estimator, type):
66 if not safe:
~\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\base.py in <listcomp>(.0)
62 # XXX: not handling dictionaries
63 if estimator_type in (list, tuple, set, frozenset):
---> 64 return estimator_type([clone(e, safe=safe) for e in estimator])
65 elif not hasattr(estimator, "get_params") or isinstance(estimator, type):
66 if not safe:
~\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\base.py in clone(estimator, safe)
84 new_object_params = estimator.get_params(deep=False)
85 for name, param in new_object_params.items():
---> 86 new_object_params[name] = clone(param, safe=False)
87 new_object = klass(**new_object_params)
88 params_set = new_object.get_params(deep=False)
~\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\base.py in clone(estimator, safe)
65 elif not hasattr(estimator, "get_params") or isinstance(estimator, type):
66 if not safe:
---> 67 return copy.deepcopy(estimator)
68 else:
69 if isinstance(estimator, type):
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
178 y = x
179 else:
--> 180 y = _reconstruct(x, memo, *rv)
181
182 # If is its own copy, don't memoize.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
279 if state is not None:
280 if deep:
--> 281 state = deepcopy(state, memo)
282 if hasattr(y, '__setstate__'):
283 y.__setstate__(state)
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_dict(x, memo, deepcopy)
239 memo[id(x)] = y
240 for key, value in x.items():
--> 241 y[deepcopy(key, memo)] = deepcopy(value, memo)
242 return y
243 d[dict] = _deepcopy_dict
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
178 y = x
179 else:
--> 180 y = _reconstruct(x, memo, *rv)
181
182 # If is its own copy, don't memoize.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
279 if state is not None:
280 if deep:
--> 281 state = deepcopy(state, memo)
282 if hasattr(y, '__setstate__'):
283 y.__setstate__(state)
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_tuple(x, memo, deepcopy)
219
220 def _deepcopy_tuple(x, memo, deepcopy=deepcopy):
--> 221 y = [deepcopy(a, memo) for a in x]
222 # We're not going to put the tuple in the memo, but it's still important we
223 # check for it, in case the tuple contains recursive mutable structures.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in <listcomp>(.0)
219
220 def _deepcopy_tuple(x, memo, deepcopy=deepcopy):
--> 221 y = [deepcopy(a, memo) for a in x]
222 # We're not going to put the tuple in the memo, but it's still important we
223 # check for it, in case the tuple contains recursive mutable structures.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_dict(x, memo, deepcopy)
239 memo[id(x)] = y
240 for key, value in x.items():
--> 241 y[deepcopy(key, memo)] = deepcopy(value, memo)
242 return y
243 d[dict] = _deepcopy_dict
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_dict(x, memo, deepcopy)
239 memo[id(x)] = y
240 for key, value in x.items():
--> 241 y[deepcopy(key, memo)] = deepcopy(value, memo)
242 return y
243 d[dict] = _deepcopy_dict
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
178 y = x
179 else:
--> 180 y = _reconstruct(x, memo, *rv)
181
182 # If is its own copy, don't memoize.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
279 if state is not None:
280 if deep:
--> 281 state = deepcopy(state, memo)
282 if hasattr(y, '__setstate__'):
283 y.__setstate__(state)
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_tuple(x, memo, deepcopy)
219
220 def _deepcopy_tuple(x, memo, deepcopy=deepcopy):
--> 221 y = [deepcopy(a, memo) for a in x]
222 # We're not going to put the tuple in the memo, but it's still important we
223 # check for it, in case the tuple contains recursive mutable structures.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in <listcomp>(.0)
219
220 def _deepcopy_tuple(x, memo, deepcopy=deepcopy):
--> 221 y = [deepcopy(a, memo) for a in x]
222 # We're not going to put the tuple in the memo, but it's still important we
223 # check for it, in case the tuple contains recursive mutable structures.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_dict(x, memo, deepcopy)
239 memo[id(x)] = y
240 for key, value in x.items():
--> 241 y[deepcopy(key, memo)] = deepcopy(value, memo)
242 return y
243 d[dict] = _deepcopy_dict
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
178 y = x
179 else:
--> 180 y = _reconstruct(x, memo, *rv)
181
182 # If is its own copy, don't memoize.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
279 if state is not None:
280 if deep:
--> 281 state = deepcopy(state, memo)
282 if hasattr(y, '__setstate__'):
283 y.__setstate__(state)
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_dict(x, memo, deepcopy)
239 memo[id(x)] = y
240 for key, value in x.items():
--> 241 y[deepcopy(key, memo)] = deepcopy(value, memo)
242 return y
243 d[dict] = _deepcopy_dict
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_list(x, memo, deepcopy)
214 append = y.append
215 for a in x:
--> 216 append(deepcopy(a, memo))
217 return y
218 d[list] = _deepcopy_list
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
178 y = x
179 else:
--> 180 y = _reconstruct(x, memo, *rv)
181
182 # If is its own copy, don't memoize.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
279 if state is not None:
280 if deep:
--> 281 state = deepcopy(state, memo)
282 if hasattr(y, '__setstate__'):
283 y.__setstate__(state)
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_tuple(x, memo, deepcopy)
219
220 def _deepcopy_tuple(x, memo, deepcopy=deepcopy):
--> 221 y = [deepcopy(a, memo) for a in x]
222 # We're not going to put the tuple in the memo, but it's still important we
223 # check for it, in case the tuple contains recursive mutable structures.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in <listcomp>(.0)
219
220 def _deepcopy_tuple(x, memo, deepcopy=deepcopy):
--> 221 y = [deepcopy(a, memo) for a in x]
222 # We're not going to put the tuple in the memo, but it's still important we
223 # check for it, in case the tuple contains recursive mutable structures.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_dict(x, memo, deepcopy)
239 memo[id(x)] = y
240 for key, value in x.items():
--> 241 y[deepcopy(key, memo)] = deepcopy(value, memo)
242 return y
243 d[dict] = _deepcopy_dict
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
178 y = x
179 else:
--> 180 y = _reconstruct(x, memo, *rv)
181
182 # If is its own copy, don't memoize.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
279 if state is not None:
280 if deep:
--> 281 state = deepcopy(state, memo)
282 if hasattr(y, '__setstate__'):
283 y.__setstate__(state)
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_dict(x, memo, deepcopy)
239 memo[id(x)] = y
240 for key, value in x.items():
--> 241 y[deepcopy(key, memo)] = deepcopy(value, memo)
242 return y
243 d[dict] = _deepcopy_dict
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_list(x, memo, deepcopy)
214 append = y.append
215 for a in x:
--> 216 append(deepcopy(a, memo))
217 return y
218 d[list] = _deepcopy_list
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
178 y = x
179 else:
--> 180 y = _reconstruct(x, memo, *rv)
181
182 # If is its own copy, don't memoize.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
279 if state is not None:
280 if deep:
--> 281 state = deepcopy(state, memo)
282 if hasattr(y, '__setstate__'):
283 y.__setstate__(state)
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_tuple(x, memo, deepcopy)
219
220 def _deepcopy_tuple(x, memo, deepcopy=deepcopy):
--> 221 y = [deepcopy(a, memo) for a in x]
222 # We're not going to put the tuple in the memo, but it's still important we
223 # check for it, in case the tuple contains recursive mutable structures.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in <listcomp>(.0)
219
220 def _deepcopy_tuple(x, memo, deepcopy=deepcopy):
--> 221 y = [deepcopy(a, memo) for a in x]
222 # We're not going to put the tuple in the memo, but it's still important we
223 # check for it, in case the tuple contains recursive mutable structures.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_dict(x, memo, deepcopy)
239 memo[id(x)] = y
240 for key, value in x.items():
--> 241 y[deepcopy(key, memo)] = deepcopy(value, memo)
242 return y
243 d[dict] = _deepcopy_dict
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
178 y = x
179 else:
--> 180 y = _reconstruct(x, memo, *rv)
181
182 # If is its own copy, don't memoize.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
279 if state is not None:
280 if deep:
--> 281 state = deepcopy(state, memo)
282 if hasattr(y, '__setstate__'):
283 y.__setstate__(state)
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_dict(x, memo, deepcopy)
239 memo[id(x)] = y
240 for key, value in x.items():
--> 241 y[deepcopy(key, memo)] = deepcopy(value, memo)
242 return y
243 d[dict] = _deepcopy_dict
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
178 y = x
179 else:
--> 180 y = _reconstruct(x, memo, *rv)
181
182 # If is its own copy, don't memoize.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
279 if state is not None:
280 if deep:
--> 281 state = deepcopy(state, memo)
282 if hasattr(y, '__setstate__'):
283 y.__setstate__(state)
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_dict(x, memo, deepcopy)
239 memo[id(x)] = y
240 for key, value in x.items():
--> 241 y[deepcopy(key, memo)] = deepcopy(value, memo)
242 return y
243 d[dict] = _deepcopy_dict
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
178 y = x
179 else:
--> 180 y = _reconstruct(x, memo, *rv)
181
182 # If is its own copy, don't memoize.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
279 if state is not None:
280 if deep:
--> 281 state = deepcopy(state, memo)
282 if hasattr(y, '__setstate__'):
283 y.__setstate__(state)
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_dict(x, memo, deepcopy)
239 memo[id(x)] = y
240 for key, value in x.items():
--> 241 y[deepcopy(key, memo)] = deepcopy(value, memo)
242 return y
243 d[dict] = _deepcopy_dict
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
178 y = x
179 else:
--> 180 y = _reconstruct(x, memo, *rv)
181
182 # If is its own copy, don't memoize.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
279 if state is not None:
280 if deep:
--> 281 state = deepcopy(state, memo)
282 if hasattr(y, '__setstate__'):
283 y.__setstate__(state)
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_tuple(x, memo, deepcopy)
219
220 def _deepcopy_tuple(x, memo, deepcopy=deepcopy):
--> 221 y = [deepcopy(a, memo) for a in x]
222 # We're not going to put the tuple in the memo, but it's still important we
223 # check for it, in case the tuple contains recursive mutable structures.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in <listcomp>(.0)
219
220 def _deepcopy_tuple(x, memo, deepcopy=deepcopy):
--> 221 y = [deepcopy(a, memo) for a in x]
222 # We're not going to put the tuple in the memo, but it's still important we
223 # check for it, in case the tuple contains recursive mutable structures.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_dict(x, memo, deepcopy)
239 memo[id(x)] = y
240 for key, value in x.items():
--> 241 y[deepcopy(key, memo)] = deepcopy(value, memo)
242 return y
243 d[dict] = _deepcopy_dict
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
178 y = x
179 else:
--> 180 y = _reconstruct(x, memo, *rv)
181
182 # If is its own copy, don't memoize.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
305 for key, value in dictiter:
306 key = deepcopy(key, memo)
--> 307 value = deepcopy(value, memo)
308 y[key] = value
309 else:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
178 y = x
179 else:
--> 180 y = _reconstruct(x, memo, *rv)
181
182 # If is its own copy, don't memoize.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
279 if state is not None:
280 if deep:
--> 281 state = deepcopy(state, memo)
282 if hasattr(y, '__setstate__'):
283 y.__setstate__(state)
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_dict(x, memo, deepcopy)
239 memo[id(x)] = y
240 for key, value in x.items():
--> 241 y[deepcopy(key, memo)] = deepcopy(value, memo)
242 return y
243 d[dict] = _deepcopy_dict
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
178 y = x
179 else:
--> 180 y = _reconstruct(x, memo, *rv)
181
182 # If is its own copy, don't memoize.
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
279 if state is not None:
280 if deep:
--> 281 state = deepcopy(state, memo)
282 if hasattr(y, '__setstate__'):
283 y.__setstate__(state)
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
148 copier = _deepcopy_dispatch.get(cls)
149 if copier:
--> 150 y = copier(x, memo)
151 else:
152 try:
~\AppData\Local\Programs\Python\Python37\lib\copy.py in _deepcopy_dict(x, memo, deepcopy)
239 memo[id(x)] = y
240 for key, value in x.items():
--> 241 y[deepcopy(key, memo)] = deepcopy(value, memo)
242 return y
243 d[dict] = _deepcopy_dict
~\AppData\Local\Programs\Python\Python37\lib\copy.py in deepcopy(x, memo, _nil)
167 reductor = getattr(x, "__reduce_ex__", None)
168 if reductor:
--> 169 rv = reductor(4)
170 else:
171 reductor = getattr(x, "__reduce__", None)
TypeError: can't pickle _thread.RLock objects
Versions:
numpy 1.21.5
pandas 1.3.5.
sklearn 1.0.2.
scikeras 0.6.1.
tensorflow 2.8.0.
tensorflow_text 2.8.1.
tensorflow_hub 0.12.0
Note:
- A very similar issue was reported in 2020 where the issue was reproducible on TFv2.3 as mentioned in this comment in that thread. However there was no clear solution/workaround provided there, rather this link. Having compared the code snippets provided in that blog post with my code above, I don't see any obvious inconsistencies or mistakes in my solution. Note that the linked blog post is actually only about incorporating a KerasClassifier into a grid/randomized search logic, and not about incorporating an entire sklearn pipeline. This might be important.
- Another time the same error message was reported here on github was this one. Yet, in this case the reason is seemingly unrelated.
-
In this thread on StackOverflow Marcin Możejko mentions that
keras
doesn't support parallelization via pickle which would be performed by default by grid/randomized search, and proposed explicitly settingn_jobs=1
to prevent multiprocessing. Makes total sense, I tried, yet I am still getting the same error message. -
Another bug report from 2020 also mentioned the same issue. Just like before, this was unfortunately also closed without solution. Note however, that in this case too, a pure
KerasClassifier
model was used and not asklearn
pipeline. Might be relevant.
@sachinprasadhs Was able to reproduce this issue on colab using TF v2.8.0 ,please find the gist here.Thanks!
Hi there, is there any update regarding this issue?
Facing same issue - It has sth to do with the keras.metrics.AUC() function because when I only use the tf.keras.metrics.BinaryAccuracy(name='accuracy') it runs fine
We are no longer maintaining KerasClassifier. Can you please forward this issue to https://github.com/adriangb/scikeras. Thanks!!
This issue has been automatically marked as stale because it has no recent activity. It will be closed if no further activity occurs. Thank you.
Closing as stale. Please reopen if you'd like to work on this further.