معلومات النظام
مرحبا جميعا! هذه أول مشاركة لي لذا أرجوك سامحني إذا فاتني شيء. لذلك أحاول استخدام خوارزمية جينية لتدريب وتقييم بنى NN متعددة لذا أحتاج إلى موازنتها على وحدة معالجة مركزية متعددة النواة. لذلك استخدمت كتاب العمل لمحاولة موازاة ذلك. ومع ذلك ، كنت عالقًا في كود tf.keras الخاص بي لأنه لم يكن قابلاً للمسح. بعد عدة ساعات من تصحيح الأخطاء ، أدركت أخيرًا أن نماذج tf.keras ليست قابلة للاختيار بينما نماذج keras.
صف السلوك الحالي
يعمل الكود أدناه ولكن إذا استبدلت keras بـ tf.keras ، فسيكون هناك خطأ:
لا يمكن اختيار المهمة لإرسالها إلى العمال.
صف السلوك المتوقع
من الآن فصاعدًا ، يجب أن تحل tf.keras محل keras ، وبالتالي يجب أن تكون tf.keras قابلة للخلل.
رمز إعادة إظهار المشكلة
#The following is a simple code to illustrate the problem:
from joblib import Parallel, delayed
import keras
import tensorflow as tf
def test():
model = keras.models.Sequential()
return
Parallel(n_jobs=8)(delayed(test)(i) for i in range(10)) #this works as intended
def test_tf():
model = tf.keras.models.Sequential()
return
Parallel(n_jobs=8)(delayed(test_tf)(i) for i in range(10)) #this will spit out the error above
تعليقات أخرى
أعتقد أن الإصلاح السريع سيكون مجرد استبدال جميع الكود الحالي بـ tf.keras إلى keras فقط ولكن بالنظر إلى أنه سيتم إيقاف دعم keras واستيعابه بواسطة Tensorflow 2.0 ، أعتقد أنه يجب إصلاح ذلك.
@ Edwin-Koh1
هل يمكنك التحقق من الإصدار الليلي ( !pip install tf-nightly==2.1.0dev20191201
) ومعرفة ما إذا كان الخطأ لا يزال قائمًا. هناك الكثير من التحسينات في الأداء في أحدث الإصدارات الليلية. شكر!
الإغلاق التلقائي بسبب نقص النشاط الأخير. يُرجى تحديث المشكلة عند توفر معلومات جديدة ، وسنعيد فتح المشكلة. شكر!
ravikyram ما زلت أرى هذه المشكلة على tensorflow == 2.1.0:
import pickle
import tensorflow as tf
def main():
model_1 = tf.keras.Sequential((
tf.keras.layers.Dense(16, activation='relu'),
tf.keras.layers.Dense(1, activation='linear'),
))
_ = model_1(tf.random.uniform((15, 3)))
model_2 = pickle.loads(pickle.dumps(model_1))
for w1, w2 in zip(model_1.get_weights(), model_2.get_weights()):
tf.debugging.assert_equal(w1, w2)
if __name__ == '__main__':
main()
النتائج في
Traceback (most recent call last):
File "/Users/hartikainen/conda/envs/softlearning-3/lib/python3.7/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/Users/hartikainen/conda/envs/softlearning-3/lib/python3.7/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/Users/hartikainen/github/rail-berkeley/softlearning-3/tests/test_pickle_keras_model.py", line 25, in <module>
main()
File "/Users/hartikainen/github/rail-berkeley/softlearning-3/tests/test_pickle_keras_model.py", line 18, in main
model_2 = pickle.loads(pickle.dumps(model_1))
TypeError: can't pickle weakref objects
$ pip freeze | grep "tf\|tensor"
tensorboard==2.1.0
tensorflow==2.1.0
tensorflow-estimator==2.1.0
tensorflow-probability==0.9.0
$ python --version
Python 3.7.5
لقد جربت على colab مع TF الإصدار 2.1.0-rc2 و 2.2.0-dev20200113 وتمكنت من إعادة إظهار المشكلة ، من فضلك ، ابحث عن جوهرها هنا . شكر!
ravikyram ، هل يجب أن تكون نماذج keras الوظيفية قابلة للاختيار أيضًا أم لا؟ أفترض إذا كانت النماذج المتسلسلة هي ثم النماذج الوظيفية يجب أن تكون كذلك؟ أم أن النماذج الوظيفية لها بعض الخصائص التي تجعل من الصعب تخليلها؟
$ python -m tests.test_pickle_keras_functional_model
2020-01-17 16:47:08.567598: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2020-01-17 16:47:08.581327: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x7fa0a55aa6c0 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-01-17 16:47:08.581362: I tensorflow/compiler/xla/service/service.cc:176] StreamExecutor device (0): Host, Default Version
Traceback (most recent call last):
File "/Users/hartikainen/conda/envs/softlearning-3/lib/python3.7/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/Users/hartikainen/conda/envs/softlearning-3/lib/python3.7/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/Users/hartikainen/github/rail-berkeley/softlearning-3/tests/test_pickle_keras_functional_model.py", line 20, in <module>
main()
File "/Users/hartikainen/github/rail-berkeley/softlearning-3/tests/test_pickle_keras_functional_model.py", line 13, in main
model_2 = pickle.loads(pickle.dumps(model_1))
TypeError: can't pickle _thread.RLock objects
مرحبا بالجميع ،
أحاول التبديل من قائمة keras
إلى tensorflow.keras
وفقًا للتوصية الموجودة على https://keras.io/.
أصاب نفس الاستثناء مثل https://github.com/tensorflow/tensorflow/issues/34697#issuecomment -575705599 مع joblib
(والذي يستخدم pickle
تحت الغطاء).
معلومات النظام:
البرنامج النصي لإعادة إنتاجه:
import joblib
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
model = Sequential()
model.add(Dense(1, input_dim=42, activation='sigmoid'))
model.compile(optimizer='Nadam', loss='binary_crossentropy', metrics=['accuracy'])
joblib.dump(model, 'model.pkl')
انتاج:
TypeError: can't pickle _thread.RLock objects
إليك إصلاح مقتبس من http://zachmoshe.com/2017/04/03/pickling-keras-models.html مخصص لحل المشكلة نفسها عندما كانت نماذج Keras غير قابلة للاختيار.
import pickle
import tempfile
from tensorflow.keras.models import Sequential, load_model, save_model, Model
from tensorflow.keras.layers import Dense
# Hotfix function
def make_keras_picklable():
def __getstate__(self):
model_str = ""
with tempfile.NamedTemporaryFile(suffix='.hdf5', delete=True) as fd:
save_model(self, fd.name, overwrite=True)
model_str = fd.read()
d = {'model_str': model_str}
return d
def __setstate__(self, state):
with tempfile.NamedTemporaryFile(suffix='.hdf5', delete=True) as fd:
fd.write(state['model_str'])
fd.flush()
model = load_model(fd.name)
self.__dict__ = model.__dict__
cls = Model
cls.__getstate__ = __getstate__
cls.__setstate__ = __setstate__
# Run the function
make_keras_picklable()
# Create the model
model = Sequential()
model.add(Dense(1, input_dim=42, activation='sigmoid'))
model.compile(optimizer='Nadam', loss='binary_crossentropy', metrics=['accuracy'])
# Save
with open('model.pkl', 'wb') as f:
pickle.dump(model, f)
epetrovski هل يجب أن أتصل بهذا الرمز عندما أكون على وشك اختيار نموذج أم يمكنني فقط الاتصال به في بداية طلبي (قبل إنشاء النموذج)؟
epetrovski هل يجب أن أتصل بهذا الرمز عندما أكون على وشك اختيار نموذج أم يمكنني فقط الاتصال به في بداية طلبي (قبل إنشاء النموذج)؟
يمكنك بالتأكيد الاتصال به مرة واحدة في بداية تطبيقك بعد استيراد tensorflow.keras.models.Model
. يؤدي تنفيذ الوظيفة إلى إضافة طريقتين جديدتين __getstate__()
و __setstate__()
إلى فئة tensorflow.keras.models.Model
لذلك يجب أن تعمل في كل مرة تريد فيها اختيار عضو من فئة طراز tf.keras المحدثة - بمعنى آخر. النموذج الخاص بك.
إليك بديل لإجابةepetrovski لا تتطلب الحفظ في ملف:
import pickle
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import Dense
from tensorflow.python.keras.layers import deserialize, serialize
from tensorflow.python.keras.saving import saving_utils
def unpack(model, training_config, weights):
restored_model = deserialize(model)
if training_config is not None:
restored_model.compile(
**saving_utils.compile_args_from_training_config(
training_config
)
)
restored_model.set_weights(weights)
return restored_model
# Hotfix function
def make_keras_picklable():
def __reduce__(self):
model_metadata = saving_utils.model_metadata(self)
training_config = model_metadata.get("training_config", None)
model = serialize(self)
weights = self.get_weights()
return (unpack, (model, training_config, weights))
cls = Model
cls.__reduce__ = __reduce__
# Run the function
make_keras_picklable()
# Create the model
model = Sequential()
model.add(Dense(1, input_dim=42, activation='sigmoid'))
model.compile(optimizer='Nadam', loss='binary_crossentropy', metrics=['accuracy'])
# Save
with open('model.pkl', 'wb') as f:
pickle.dump(model, f)
المصدر: https://docs.python.org/3/library/pickle.html#object.__reduce__
أشعر أنه ربما يمكن إضافة هذا إلى النموذج؟ هل هناك حالات لا يعمل فيها هذا؟
يبدو أن هناك سمتين لا يمكن اختيارهما في فئة متسلسلة. نجح هذا الإصلاح أيضًا بالنسبة لي:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
class PickableSequential(Sequential):
def __getstate__(self):
state = super().__getstate__()
state.pop("_trackable_saver")
state.pop("_compiled_trainable_state")
return state
model = PickableSequential(Dense(10))
import pickle
pickle.dumps(model)
~
لقد جربت في colab مع TF الإصدار 2.2 ، إصدارات ليلية وتمكنت من إعادة إنتاج المشكلة. من فضلك ، ابحث عن جوهرها هنا . شكرًا!
لقد جربت في colab مع TF الإصدار 2.2 ، إصدارات ليلية وتمكنت من إعادة إنتاج المشكلة. من فضلك ، ابحث عن جوهرها هنا . شكرًا!
نموذج keras قابل للاختيار ولكن tf.keras غير قابل للاختيار ، لذا فإن الحل البديل لذلك هو الرجوع إلى الكود أدناه
لقد رأيت دفتر ملاحظات Colab الخاص بك وقمت بإجراء التغييرات المطلوبة ، فقط قم بنسخ نفس الرمز على النحو التالي ، وقد انتهيت من حل الخطأ
استيراد tensorflow مثل tf
def main ():
model_1 = tf.keras.Sequential ((
tf.keras.layers.Dense (16 ، تنشيط = 'relu') ،
tf.keras.layers.Dense (1 ، التنشيط = "خطي") ،
))
_ = model_1(tf.random.uniform((15, 3)))
model_1.save('model_2.h5')
model_2 = tf.keras.models.load_model('model_2.h5')
for w1, w2 in zip(model_1.get_weights(), model_2.get_weights()):
tf.debugging.assert_equal(w1, w2)
إذا __name__ == '__الرئيسية__':
الأساسية()
@ Edwin-Koh1
وفقًا لاقتراح lahsrahtidnap ، لقد جربت في colab ولا أرى أي مشكلة ، من فضلك ، اعثر على الجوهر هنا ، شكرًا!
مرحبا بالجميع ،
أحاول التبديل من قائمةkeras
إلىtensorflow.keras
وفقًا للتوصية الموجودة على https://keras.io/.
أصاب نفس الاستثناء مثل # 34697 (تعليق) معjoblib
(والذي يستخدمpickle
تحت الغطاء).معلومات النظام:
- Debian 10 (باستر)
- بايثون 3.7.6
- جوبليب 0.14.1
- Tensorflow 2.1.0
البرنامج النصي لإعادة إنتاجه:
import joblib from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense model = Sequential() model.add(Dense(1, input_dim=42, activation='sigmoid')) model.compile(optimizer='Nadam', loss='binary_crossentropy', metrics=['accuracy']) joblib.dump(model, 'model.pkl')
انتاج:
TypeError: can't pickle _thread.RLock objects
استخدام المخلل أو Joblib لن يحل مشكلتك لأن Tensorflow.keras لا يدعم ذلك.
لذا فإن الحل البديل لذلك هو: -
بالنظر إلى الكود الخاص بك: -
استبدل هذا السطر: - joblib.dump (model، 'model.pkl')
مع: -
لحفظ استخدام النموذج: -
-----> model.save ('new_model.h5')
وإذا كنت تريد تحميل هذا النموذج فاستخدم: -
-----> new_model = tf.keras.models.load_model ('new_model.h5')
بالنظر إلى الكود الخاص بك: -
استبدل هذا السطر: - joblib.dump (model، 'model.pkl')
مع: -
لحفظ استخدام النموذج: -
-----> model.save ('new_model.h5')
وإذا كنت تريد تحميل هذا النموذج فاستخدم: -
-----> new_model = tf.keras.models.load_model ('new_model.h5')
يعمل هذا في بعض الحالات ، ومع ذلك ، فإنه لا يساعد عندما يتم مخلل نموذج كجزء من وظيفة أخرى ، في حالتي يحدث هذا عند استخدام مكتبة python multiprocessing
.
@ Edwin-Koh1
لا تزال هذه القضية؟
من فضلك تأكيد شكرا!
هل من الممكن تفريغ نموذج Keras المتسلسل في حاوية بايت
bytes_container = BytesIO()
joblib.dump(Keras_model, bytes_container, protocol=4)
# Error
TypeError: can't pickle _thread.RLock objects
pickle.dump(Keras_model, bytes_container, protocol=4)
# Error
TypeError: can't pickle _thread.RLock objects
dill.dump(Keras_model, bytes_container, protocol=4)
# Error
TypeError: can't pickle tensorflow.python._tf_stack.StackSummary objects
أو في ملف مؤقت
tempfile.TemporaryFile().write(Keras_model)
أو
save_model(Keras_model, bytes_container)
# Error
TypeError: expected str, bytes or os.PathLike object, not _io.BytesIO
لقد نجح هذا بشكل مثالي ، فقد لا تحتاج إلى base64 ، بالنسبة لي للتخزين في قاعدة البيانات التي قمت بها ، كل شيء في الذاكرة ، لا يوجد قرص لمس
from io import BytesIO
import dill,base64,tempfile
#Saving Model as base64
model_json = Keras_model.to_json()
def Base64Converter(ObjectFile):
bytes_container = BytesIO()
dill.dump(ObjectFile, bytes_container)
bytes_container.seek(0)
bytes_file = bytes_container.read()
base64File = base64.b64encode(bytes_file)
return base64File
base64KModelJson = Base64Converter(model_json)
base64KModelJsonWeights = Base64Converter(Keras_model.get_weights())
#Loading Back
from joblib import load
from keras.models import model_from_json
def ObjectConverter(base64_File):
loaded_binary = base64.b64decode(base64_File)
loaded_object = tempfile.TemporaryFile()
loaded_object.write(loaded_binary)
loaded_object.seek(0)
ObjectFile = load(loaded_object)
loaded_object.close()
return ObjectFile
modeljson = ObjectConverter(base64KModelJson)
modelweights = ObjectConverter(base64KModelJsonWeights)
loaded_model = model_from_json(modeljson)
loaded_model.set_weights(modelweights)
تضمين التغريدة
هذا حل جميل ، شكرا. كن حذرًا فقط إذا كنت تخطط لمواصلة تدريب هذا النموذج ، لأن هذه الطريقة لا تحافظ على حالة المحسن.
تضمين التغريدة
نعم ، يتعين علينا التجميع باستخدام المُحسِّن قبل التوافق مع البيانات الجديدة ، ولا ينبغي أن يستغرق ذلك وقتًا طويلاً ،
من الصعب جدًا تخزين model.save بالطريقة الأخرى في الذاكرة.
هناك طريقة أخرى وهي أننا نستطيع الحصول على get_config () و from_config () مع التهيئة والترجمة ، ثم يجب إجراء الملاءمة للبيانات الجديدة.
@ Edwin-Koh1
أي تحديث في هذا الموضوع من فضلك. شكرا!
تم وضع علامة على هذه المشكلة تلقائيًا على أنها قديمة نظرًا لعدم وجود نشاط حديث لها. سيتم إغلاقه إذا لم يحدث أي نشاط آخر. شكرا لك.
بالنظر إلى الكود الخاص بك: -
استبدل هذا السطر: - joblib.dump (model، 'model.pkl')
مع: -
لحفظ استخدام النموذج: -
-----> model.save ('new_model.h5')
وإذا كنت تريد تحميل هذا النموذج فاستخدم: -
-----> new_model = tf.keras.models.load_model ('new_model.h5')يعمل هذا في بعض الحالات ، ومع ذلك ، فإنه لا يساعد عندما يتم مخلل نموذج كجزء من وظيفة أخرى ، في حالتي يحدث هذا عند استخدام مكتبة python
multiprocessing
.
JohannesAck ، أعتقد أنه قد يكون لدي مشكلة مماثلة. أقوم بتدريب نموذج Keras على GPU ، وحفظه باستخدام تنسيق TensorFlow SavedModel باستخدام Keras API ، وإعادة تحميله في جلسة جديدة ومحاولة عمل تنبؤات بالتوازي على وحدات المعالجة المركزية المتعددة باستخدام مكتبة multiprocessing
و starmap
وظيفة. إذا قمت بتحميل النموذج قبل موازاة التوقعات ، فسأحصل على خطأ تخليل ( TypeError: can't pickle _thread.RLock objects
). إذا قمت بتحميل النموذج ضمن وظيفة التنبؤ الخاصة بي في كل مرة وقمت بحذفه في نهاية كل وظيفة ، فسيتم تعليقه بعد بضعة تنبؤات. هل لديك أي فكرة عما يمكن أن يحدث هنا؟
إغلاق كما لا معنى له. الرجاء إعادة الفتح إذا كنت ترغب في مزيد من العمل على هذا.
هذا ليس بالية بقدر ما أعرف.
في الثلاثاء ، 25 آب (أغسطس) 2020 ، 5:26 ص tensorflow-butler [بوت] <
[email protected]> كتب:
هل أنت راضٍ عن حل مشكلتك؟
نعم
https://docs.google.com/forms/d/e/1FAIpQLSfaP12TRhd9xSxjXZjcZFNXPGk4kc1-qMdv3gc6bEP90vY1ew/viewform؟entry.85265664=Yes&entry.2137816233=https://github.com/tensor/tensor
لا
https://docs.google.com/forms/d/e/1FAIpQLSfaP12TRhd9xSxjXZjcZFNXPGk4kc1-qMdv3gc6bEP90vY1ew/viewform؟entry.85265664=No&entry.2137816233=https://github.com/tensorflow/-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/tensorflow/tensorflow/issues/34697#issuecomment-679941192 ،
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/AANMPP2EF3PRKBYRYHOHY3TSCOGTXANCNFSM4JSZ4QSA
.
هل هذا هو WONTFIX بعد إغلاق المشكلة الآن؟
في حالتي ، لا يمكنني ببساطة استخدام model.save()
لأن عملية التخليل تتم من أداة خارجية توفر لها التعليمات البرمجية فقط نموذجًا متوافقًا مع scikit-Learn (يوفر صفي طريقة get_clf
). يمكنني حل المشكلة نظرًا لأن الكود الخاص بي كان (تقريبًا) متوافقًا مع Keras (وليس tf.keras) ، ومع Keras 2.3.1 (TF 1.15.0) يعمل التخليل بدون مشكلة.
mimxrt إذا كنت تبحث عن استخدام نماذج Keras داخل بيئة scikit-Learn ، يرجى مراجعة SciKeras (الكشف الكامل: أنا المؤلف). إذا كنت تبحث فقط عن طريقة لجعل كائنات Keras قابلة للانتقاء ، فتحقق من https://github.com/tensorflow/tensorflow/pull/39609 وعلى وجه الخصوص https://github.com/tensorflow/tensorflow/pull/39609#issuecomment 683370566
تحرير: ارتباط ثابت
نحن لا نعمل بنشاط على هذا في الوقت الحالي ، لكننا نعيد فتحه لأنه لا يزال يمثل مشكلة.
إغلاق كما لا معنى له. الرجاء إعادة الفتح إذا كنت ترغب في مزيد من العمل على هذا.
هذا سوف يتعطل مرة أخرى.
تم وضع علامة على هذه المشكلة تلقائيًا على أنها قديمة نظرًا لعدم وجود نشاط حديث لها. سيتم إغلاقه إذا لم يحدث أي نشاط آخر. شكرا لك.
التعليق الأكثر فائدة
إليك بديل لإجابةepetrovski لا تتطلب الحفظ في ملف:
المصدر: https://docs.python.org/3/library/pickle.html#object.__reduce__
أشعر أنه ربما يمكن إضافة هذا إلى النموذج؟ هل هناك حالات لا يعمل فيها هذا؟