Sistem Informasi
Halo semua! Ini adalah posting pertama saya jadi mohon maafkan saya jika saya melewatkan sesuatu. Jadi saya mencoba menggunakan algoritma genetika untuk melatih dan mengevaluasi beberapa arsitektur NN, jadi saya perlu memparalelkannya pada CPU multi-core. Oleh karena itu saya telah menggunakan joblib untuk mencoba memparalelkan ini. Namun, saya terjebak pada kode tf.keras saya karena tidak bisa dijadikan acar. Setelah berjam-jam debugging, saya akhirnya menyadari bahwa model tf.keras tidak dapat diawetkan sedangkan model keras.
Jelaskan perilaku saat ini
Kode di bawah ini berfungsi tetapi jika Anda mengganti keras dengan tf.keras, akan ada kesalahan:
Tidak dapat membuat acar tugas untuk dikirim ke pekerja.
Jelaskan perilaku yang diharapkan
Ke depan, tf.keras harus menggantikan keras dan oleh karena itu tf.keras juga harus menjadi acar.
Kode untuk mereproduksi masalah
#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
Komentar lain
Saya kira perbaikan cepat hanya akan mengganti semua kode yang ada dengan tf.keras menjadi hanya keras tetapi karena dukungan keras akan dihentikan dan diserap oleh Tensorflow 2.0, saya pikir ini harus diperbaiki.
@ Edwin-Koh
Bisakah Anda memeriksa dengan versi nightly ( !pip install tf-nightly==2.1.0dev20191201
) dan melihat apakah kesalahan masih berlanjut. Ada banyak peningkatan kinerja dalam versi nightly terbaru. Terima kasih!
Tutup otomatis karena kurangnya aktivitas baru-baru ini. Perbarui masalah saat informasi baru tersedia, dan kami akan membuka kembali masalah tersebut. Terima kasih!
@ravikyram Saya masih melihat masalah ini di 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()
menghasilkan
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
Saya telah mencoba colab dengan TF versi 2.1.0-rc2, 2.2.0-dev20200113 dan dapat mereproduksi masalah tersebut. Temukan intinya di sini . Terima kasih!
@ravikyram , haruskah model keras fungsional juga bisa di-picklable? Saya akan berasumsi jika model Sequential kemudian model fungsional juga harus? Atau apakah model fungsional memiliki beberapa sifat yang membuatnya lebih sulit untuk dijadikan acar?
$ 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
Halo semuanya,
Saya mencoba untuk beralih dari mandiri keras
menjadi tensorflow.keras
sesuai rekomendasi di https://keras.io/.
Saya mendapatkan pengecualian yang sama seperti https://github.com/tensorflow/tensorflow/issues/34697#issuecomment -575705599 dengan joblib
(yang menggunakan pickle
bawah tenda).
Sistem Informasi:
Script untuk direproduksi:
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')
Keluaran:
TypeError: can't pickle _thread.RLock objects
Berikut ini perbaikan yang diadaptasi dari http://zachmoshe.com/2017/04/03/pickling-keras-models.html dimaksudkan untuk memecahkan masalah yang sama saat model Keras dulu tidak dapat dijadikan acar.
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 Haruskah saya memanggil kode ini setiap kali saya akan membuat acar model atau dapatkah saya menyebutnya di awal aplikasi saya (sebelum membuat model)?
@epetrovski Haruskah saya memanggil kode ini setiap kali saya akan membuat acar model atau dapatkah saya menyebutnya di awal aplikasi saya (sebelum membuat model)?
Anda pasti dapat memanggilnya sekali di awal aplikasi Anda setelah mengimpor tensorflow.keras.models.Model
. Menjalankan fungsi menambahkan dua metode baru __getstate__()
dan __setstate__()
ke kelas tensorflow.keras.models.Model
sehingga harus bekerja setiap kali Anda ingin membuat acar anggota kelas Model tf.keras yang diperbarui - yaitu. model Anda sendiri.
Berikut adalah alternatif jawaban @epetrovski yang tidak memerlukan penyimpanan ke file:
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)
Sumber: https://docs.python.org/3/library/pickle.html#object.__reduce__
Saya merasa mungkin ini bisa ditambahkan ke Model? Apakah ada kasus dimana ini tidak akan berhasil?
Sepertinya ada dua atribut yang tidak bisa dipilih di kelas Sequential. Perbaikan ini juga berhasil untuk saya:
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)
~
Saya telah mencoba di colab dengan TF versi 2.2, versi nightly dan dapat mereproduksi masalah tersebut. Silakan, temukan intinya di sini. Terima kasih!
Saya telah mencoba di colab dengan TF versi 2.2, versi nightly dan dapat mereproduksi masalah tersebut. Silakan, temukan intinya di sini. Terima kasih!
model keras dapat dipilih tetapi tf.keras tidak dapat dipilih, jadi solusi alternatif untuk ini adalah merujuk kode di bawah ini
Saya melihat notebook colab Anda dan membuat perubahan yang diperlukan cukup salin kode yang sama seperti di bawah ini dan Anda selesai dengan menyelesaikan kesalahan
impor tensorflow sebagai 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_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)
jika __name__ == '__main__':
utama()
@ Edwin-Koh
Sesuai saran dari @lahsrahtidnap saya telah mencoba di colab dan saya tidak melihat masalah apa pun. Silakan, temukan intinya di sini. Terima kasih!
Halo semuanya,
Saya mencoba untuk beralih dari mandirikeras
menjaditensorflow.keras
sesuai rekomendasi di https://keras.io/.
Saya mendapatkan pengecualian yang sama seperti # 34697 (komentar) denganjoblib
(yang menggunakanpickle
bawah tenda).Sistem Informasi:
- Debian 10 (buster)
- Python 3.7.6
- joblib 0.14.1
- tensorflow 2.1.0
Script untuk direproduksi:
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')
Keluaran:
TypeError: can't pickle _thread.RLock objects
Menggunakan acar atau joblib tidak akan menyelesaikan masalah Anda karena tensorflow.keras tidak mendukung ini.
Jadi solusi alternatif untuk ini adalah: -
mempertimbangkan kode Anda: -
ganti baris ini: - joblib.dump (model, 'model.pkl')
dengan: -
untuk menghemat penggunaan model: -
-----> model.save ('new_model.h5')
dan jika Anda ingin memuat model ini, gunakan: -
-----> new_model = tf.keras.models.load_model ('new_model.h5')
mempertimbangkan kode Anda: -
ganti baris ini: - joblib.dump (model, 'model.pkl')
dengan: -
untuk menghemat penggunaan model: -
-----> model.save ('new_model.h5')
dan jika Anda ingin memuat model ini, gunakan: -
-----> new_model = tf.keras.models.load_model ('new_model.h5')
Ini berfungsi dalam beberapa kasus, namun, itu tidak membantu ketika model diawetkan sebagai bagian dari fungsi lain, dalam kasus saya ini terjadi saat menggunakan pustaka python multiprocessing
.
@ Edwin-Koh
Apakah ini masih menjadi masalah?
Mohon konfirmasi. Terima kasih!
Apakah mungkin untuk membuang Model Sekuensial Keras dalam wadah byteIO
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
atau di tempfile
tempfile.TemporaryFile().write(Keras_model)
atau
save_model(Keras_model, bytes_container)
# Error
TypeError: expected str, bytes or os.PathLike object, not _io.BytesIO
Ini bekerja dengan sempurna, Anda mungkin tidak perlu base64, untuk saya simpan di database yang saya lakukan, semua yang ada di memori, tidak ada disk yang menyentuh
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)
@hanifah
Ini solusi yang bagus, terima kasih. Berhati-hatilah jika Anda berencana untuk terus melatih model ini, karena metode ini tidak mempertahankan status pengoptimal.
@Johnny
Ya, kami harus mengkompilasi dengan pengoptimal sebelum melakukan fit dengan data baru, yang seharusnya tidak memakan waktu,
Cara lain model.save sangat sulit untuk disimpan dalam memori.
Cara lain adalah kita bisa melakukan get_config () dan from_config () dengan inisialisasi dan kompilasi kemudian fit harus dilakukan untuk data baru.
@ Edwin-Koh
Setiap pembaruan tentang masalah ini, terima kasih!
Masalah ini secara otomatis ditandai sebagai usang karena tidak ada aktivitas terbaru. Ini akan ditutup jika tidak ada aktivitas lebih lanjut. Terima kasih.
mempertimbangkan kode Anda: -
ganti baris ini: - joblib.dump (model, 'model.pkl')
dengan: -
untuk menghemat penggunaan model: -
-----> model.save ('new_model.h5')
dan jika Anda ingin memuat model ini, gunakan: -
-----> new_model = tf.keras.models.load_model ('new_model.h5')Ini berfungsi dalam beberapa kasus, namun, itu tidak membantu ketika model diawetkan sebagai bagian dari fungsi lain, dalam kasus saya ini terjadi saat menggunakan pustaka python
multiprocessing
.
@JohannesAck , saya pikir saya mungkin memiliki masalah serupa. Saya melatih model Keras di GPU, menyimpannya menggunakan format TensorFlow SavedModel menggunakan API Keras, memuatnya kembali di sesi baru dan mencoba membuat prediksi secara paralel di beberapa CPU menggunakan library multiprocessing
dan starmap
fungsi. Jika saya memuat model sebelum memparalelkan prediksi, saya mendapatkan kesalahan pengawetan ( TypeError: can't pickle _thread.RLock objects
). Jika saya memuat model dalam fungsi prediksi saya setiap kali dan menghapusnya di akhir setiap fungsi, panggilan akan macet setelah beberapa prediksi. Apakah Anda tahu apa yang mungkin terjadi di sini?
Menutup sebagai basi. Harap buka kembali jika Anda ingin menangani ini lebih lanjut.
Ini tidak basi sejauh yang saya tahu.
Pada Sel, 25 Agustus 2020, 05.26 tensorflow-butler [bot] <
[email protected]> menulis:
Apakah Anda puas dengan penyelesaian masalah Anda?
Iya
https://docs.google.com/forms/d/e/1FAIpQLSfaP12TRhd9xSxjXZjcZFNXPGk4kc1-qMdv3gc6bEP90vY1ew/viewform?entry.85265664=Yes&entry.2137816233=https://github.com/tensorflow/tensorflow/issues
Tidak
https://docs.google.com/forms/d/e/1FAIpQLSfaP12TRhd9xSxjXZjcZFNXPGk4kc1-qMdv3gc6bEP90vY1ew/viewform?entry.85265664=No&entry.2137816233=https://github.com/tensorflow/tensorflow/issues-
Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/tensorflow/tensorflow/issues/34697#issuecomment-679941192 ,
atau berhenti berlangganan
https://github.com/notifications/unsubscribe-auth/AANMPP2EF3PRKBYRYHOHY3TSCOGTXANCNFSM4JSZ4QSA
.
Apakah ini WONTFIX setelah masalah ditutup sekarang?
Dalam kasus saya, saya tidak bisa begitu saja menggunakan model.save()
karena pengawetan dilakukan dari alat eksternal yang kode saya hanya menyediakan model yang kompatibel dengan scikit-learn (kelas saya menyediakan metode get_clf
). Saya dapat mengatasi masalah ini karena kode saya (hampir) kompatibel dengan Keras (bukan tf.keras), dan dengan pengawetan Keras 2.3.1 (TF 1.15.0) bekerja tanpa masalah.
@mimxrt jika Anda ingin menggunakan model Keras dalam scikit-learn env, silakan lihat SciKeras (pengungkapan lengkap: Saya penulisnya). Jika Anda hanya mencari cara untuk membuat objek Keras dapat dipilih, periksa https://github.com/tensorflow/tensorflow/pull/39609 dan khususnya https://github.com/tensorflow/tensorflow/pull/39609#issuecomment -683370566
Edit: tautan tetap
Kami tidak sedang mengerjakannya secara aktif sekarang, tetapi membuka kembali karena masih menjadi masalah.
Menutup sebagai basi. Harap buka kembali jika Anda ingin menangani ini lebih lanjut.
Ini akan terhenti lagi.
Masalah ini secara otomatis ditandai sebagai usang karena tidak ada aktivitas terbaru. Ini akan ditutup jika tidak ada aktivitas lebih lanjut. Terima kasih.
Komentar yang paling membantu
Berikut adalah alternatif jawaban @epetrovski yang tidak memerlukan penyimpanan ke file:
Sumber: https://docs.python.org/3/library/pickle.html#object.__reduce__
Saya merasa mungkin ini bisa ditambahkan ke Model? Apakah ada kasus dimana ini tidak akan berhasil?