Tensorflow: Keras λͺ¨λΈμ€ 피클 κ°€λŠ₯ν•˜μ§€λ§Œ tf.keras λͺ¨λΈμ€ 피클 κ°€λŠ₯ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

에 λ§Œλ“  2019λ…„ 11μ›” 29일  Β·  34μ½”λ©˜νŠΈ  Β·  좜처: tensorflow/tensorflow

μ‹œμŠ€ν…œ 정보

  • μœˆλ„μš° 10
  • Tensorflow 2.0 (CPU)
  • joblib 0.14.0
  • 파이썬 3.7.5
  • μΌ€ 라슀 2.3.1

λͺ¨λ‘λ“€ μ•ˆλ…•! 이것은 λ‚˜μ˜ 첫 번째 κ²Œμ‹œλ¬Όμ΄λ―€λ‘œ λ‚΄κ°€ λ­”κ°€λ₯Ό λ†“μΉœ 경우 λ‚˜λ₯Ό μš©μ„œν•˜μ‹­μ‹œμ˜€. κ·Έλž˜μ„œ μœ μ „ μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜μ—¬ 닀쀑 NN μ•„ν‚€ν…μ²˜λ₯Ό ν›ˆλ ¨ν•˜κ³  ν‰κ°€ν•˜λ €κ³ ν•˜λ―€λ‘œ 닀쀑 μ½”μ–΄ CPUμ—μ„œ λ³‘λ ¬ν™”ν•΄μ•Όν•©λ‹ˆλ‹€. λ”°λΌμ„œ λ‚˜λŠ” 이것을 λ³‘λ ¬ν™”ν•˜κΈ° μœ„ν•΄ joblibλ₯Ό μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 피클 ν•  수 μ—†κΈ° λ•Œλ¬Έμ— 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에 μ˜ν•΄ ν‘μˆ˜λ¨μ— 따라 이것이 μˆ˜μ •λ˜μ–΄μ•Όν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.

TF 2.2 keras awaiting tensorflower bug

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

λ‹€μŒμ€ νŒŒμΌμ— μ €μž₯ν•  ν•„μš”κ°€μ—†λŠ” @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__

이것이 λͺ¨λΈμ— μΆ”κ°€ 될 μˆ˜μžˆμ„ 것 κ°™μŠ΅λ‹ˆκΉŒ? 이것이 μž‘λ™ν•˜μ§€ μ•ŠλŠ” κ²½μš°κ°€ μžˆμŠ΅λ‹ˆκΉŒ?

λͺ¨λ“  34 λŒ“κΈ€

@ 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

TF 버전 2.1.0-rc2, 2.2.0-dev20200113으둜 colab을 μ‹œλ„ν–ˆμœΌλ©° 문제λ₯Ό μž¬ν˜„ ν•  μˆ˜μžˆμ—ˆμŠ΅λ‹ˆλ‹€. μ—¬κΈ° μ—μ„œ μš”μ μ„ 찾으

@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

μ•ˆλ…•ν•˜μ„Έμš” μ—¬λŸ¬λΆ„,
https://keras.io/ 의 ꢌμž₯ 사항에 따라 독립 μ‹€ν–‰ ν˜• keras μ—μ„œ tensorflow.keras 둜 μ „ν™˜ν•˜λ €κ³ ν•©λ‹ˆλ‹€ .
https://github.com/tensorflow/tensorflow/issues/34697#issuecomment -575705599와 joblib (λ‚΄λΆ€μ—μ„œ pickle μ‚¬μš©)와 같은 μ˜ˆμ™Έκ°€ λ°œμƒν•©λ‹ˆλ‹€.

μ‹œμŠ€ν…œ 정보:

  • Debian 10 (λ²„μŠ€ν„°)
  • 파이썬 3.7.6
  • joblib 0.14.1
  • ν…μ„œ ν”Œλ‘œμš° 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

λ‹€μŒμ€ Keras λͺ¨λΈμ΄ 피클 ν•  수 μ—†μ—ˆλ˜ λ™μΌν•œ 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ http://zachmoshe.com/2017/04/03/pickling-keras-models.html μ—μ„œ μˆ˜μ • 된 μˆ˜μ • μ‚¬ν•­μž…λ‹ˆλ‹€.

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 Model 클래슀의 멀버λ₯Ό 피클 ν•  λ•Œλ§ˆλ‹€ μž‘λ™ν•©λ‹ˆλ‹€. 즉. μžμ‹ μ˜ λͺ¨λΈ.

λ‹€μŒμ€ νŒŒμΌμ— μ €μž₯ν•  ν•„μš”κ°€μ—†λŠ” @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__

이것이 λͺ¨λΈμ— μΆ”κ°€ 될 μˆ˜μžˆμ„ 것 κ°™μŠ΅λ‹ˆκΉŒ? 이것이 μž‘λ™ν•˜μ§€ μ•ŠλŠ” κ²½μš°κ°€ μžˆμŠ΅λ‹ˆκΉŒ?

Sequential ν΄λž˜μŠ€μ—μ„œ 선택할 μˆ˜μ—†λŠ” 두 가지 μ†μ„±μ΄μžˆλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. 이 μˆ˜μ • 사항은 μ €μ—κ²Œλ„ νš¨κ³Όμ μ΄μ—ˆμŠ΅λ‹ˆλ‹€.

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)
~                     

TF 버전 2.2, μ•Όκ°„ λ²„μ „μœΌλ‘œ colabμ—μ„œ μ‹œλ„ν•΄ λ³΄μ•˜κ³  문제λ₯Ό μž¬ν˜„ ν•  μˆ˜μžˆμ—ˆμŠ΅λ‹ˆλ‹€. μ—¬κΈ° μ—μ„œ μš”μ μ„ 찾으

TF 버전 2.2, μ•Όκ°„ λ²„μ „μœΌλ‘œ colabμ—μ„œ μ‹œλ„ν•΄ λ³΄μ•˜κ³  문제λ₯Ό μž¬ν˜„ ν•  μˆ˜μžˆμ—ˆμŠ΅λ‹ˆλ‹€. μ—¬κΈ° μ—μ„œ μš”μ μ„ 찾으

keras λͺ¨λΈμ€ 선택할 수 μžˆμ§€λ§Œ tf.kerasλŠ” 선택할 수 μ—†μœΌλ―€λ‘œ 이에 λŒ€ν•œ λŒ€μ²΄ μ†”λ£¨μ…˜μ€ μ•„λž˜ μ½”λ“œλ₯Ό μ°Έμ‘°ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€
colab λ…ΈνŠΈλΆμ„ λ³΄μ•˜κ³  ν•„μš”ν•œ λ³€κ²½ 사항을 μ•„λž˜μ™€ 같은 μ½”λ“œλ₯Ό λ³΅μ‚¬ν•˜λ©΄ 였λ₯˜ 해결이 μ™„λ£Œλ©λ‹ˆλ‹€

tensorflowλ₯Ό 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)

__name__ == '__main__'인 경우 :
λ³Έκ΄€()

@ Edwin-Koh1

@lahsrahtidnap 의 μ œμ•ˆμ— 따라 μ—¬κΈ° μ—μ„œ μš”μ μ„ 찾으

μ•ˆλ…•ν•˜μ„Έμš” μ—¬λŸ¬λΆ„,
https://keras.io/ 의 ꢌμž₯ 사항에 따라 독립 μ‹€ν–‰ ν˜• keras μ—μ„œ tensorflow.keras 둜 μ „ν™˜ν•˜λ €κ³ ν•©λ‹ˆλ‹€ .
joblib (λ‚΄λΆ€μ—μ„œ pickle μ‚¬μš© ) 와 ν•¨κ»˜

μ‹œμŠ€ν…œ 정보:

  • Debian 10 (λ²„μŠ€ν„°)
  • 파이썬 3.7.6
  • joblib 0.14.1
  • ν…μ„œ ν”Œλ‘œμš° 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

pickle λ˜λŠ” 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 Sequential Model을 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

λ˜λŠ” μž„μ‹œ νŒŒμΌμ—μ„œ

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 , λΉ„μŠ·ν•œ λ¬Έμ œκ°€μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. GPUμ—μ„œ Keras λͺ¨λΈμ„ ν›ˆλ ¨μ‹œν‚€κ³ , Keras APIλ₯Ό μ‚¬μš©ν•˜μ—¬ TensorFlow SavedModel ν˜•μ‹μ„ μ‚¬μš©ν•˜μ—¬ μ €μž₯ν•˜κ³ , μƒˆ μ„Έμ…˜μ—μ„œ λ‹€μ‹œλ‘œλ“œν•˜κ³ , multiprocessing λΌμ΄λΈŒλŸ¬λ¦¬μ™€ starmap μ‚¬μš©ν•˜μ—¬ μ—¬λŸ¬ CPUμ—μ„œ λ³‘λ ¬λ‘œ μ˜ˆμΈ‘μ„ μ‹œλ„ν•©λ‹ˆλ‹€. TypeError: can't pickle _thread.RLock objects )κ°€ λ°œμƒν•©λ‹ˆλ‹€. 맀번 λ‚΄ 예츑 ν•¨μˆ˜ λ‚΄μ—μ„œ λͺ¨λΈμ„λ‘œλ“œν•˜κ³  각 ν•¨μˆ˜ 호좜 λμ—μ„œ μ‚­μ œν•˜λ©΄ 두 번의 예츑 후에 μ€‘λ‹¨λ©λ‹ˆλ‹€. μ—¬κΈ°μ„œ 무슨 일이 λ²Œμ–΄ μ§ˆμ§€ μ•„μ‹­λ‹ˆκΉŒ?

λΆ€μ‹€ μƒνƒœλ‘œ μ’…λ£Œλ©λ‹ˆλ‹€. 이 μž‘μ—…μ„ κ³„μ†ν•˜λ €λ©΄ λ‹€μ‹œμ—¬μ‹­μ‹œμ˜€.

문제 해결에 λ§Œμ‘±ν•˜μ‹­λ‹ˆκΉŒ?
예
μ•„λ‹ˆ

λ‚΄κ°€ μ•„λŠ” ν•œ 이것은 λΆ€μ‹€ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

2020 λ…„ 8 μ›” 25 일 ν™”μš”μΌ μ˜€μ „ 5:26 tensorflow-butler [bot] <
[email protected]> μž‘μ„± :

문제 해결에 λ§Œμ‘±ν•˜μ‹­λ‹ˆκΉŒ?
예
https://docs.google.com/forms/d/e/1FAIpQLSfaP12TRhd9xSxjXZjcZFNXPGk4kc1-qMdv3gc6bEP90vY1ew/viewform?entry.85265664=Yes&entry.2137816233=https://github.com/tensorflow/tensorflow/issues/34697
μ•„λ‹ˆ
https://docs.google.com/forms/d/e/1FAIpQLSfaP12TRhd9xSxjXZjcZFNXPGk4kc1-qMdv3gc6bEP90vY1ew/viewform?entry.85265664=No&entry.2137816233=https://github.com/tensorflow/tensorflow/issues/34697

β€”
λŒ“κΈ€μ„ λ‹¬μ•˜ κΈ° λ•Œλ¬Έμ— μˆ˜μ‹  ν•œ κ²ƒμž…λ‹ˆλ‹€.
이 이메일에 직접 λ‹΅μž₯ν•˜κ³  GitHubμ—μ„œ ν™•μΈν•˜μ„Έμš”.
https://github.com/tensorflow/tensorflow/issues/34697#issuecomment-679941192 ,
λ˜λŠ” ꡬ독 μ·¨μ†Œ
https://github.com/notifications/unsubscribe-auth/AANMPP2EF3PRKBYRYHOHY3TSCOGTXANCNFSM4JSZ4QSA
.

μ΄μŠˆκ°€ μ’…κ²° 된 ν›„ WONTFIXμž…λ‹ˆκΉŒ?

λ‚΄ κ²½μš°μ—λŠ” μ½”λ“œκ°€ scikit-learn ν˜Έν™˜ λͺ¨λΈμ„ μ œκ³΅ν•˜λŠ” μ™ΈλΆ€ λ„κ΅¬μ—μ„œ 피클 링이 μˆ˜ν–‰λ˜κΈ° λ•Œλ¬Έμ— λ‹¨μˆœνžˆ model.save() λ₯Ό μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€ (λ‚΄ ν΄λž˜μŠ€λŠ” get_clf λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•¨). λ‚΄ μ½”λ“œκ°€ (거의) Keras ν˜Έν™˜ (tf.keras μ•„λ‹˜)이고 Keras 2.3.1 (TF 1.15.0) 피클이 λ¬Έμ œμ—†μ΄ μž‘λ™ν•˜λ―€λ‘œ 문제λ₯Ό ν•΄κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

당신이 scikit 배울 ENV λ‚΄ Keras λͺ¨λΈμ„ μ‚¬μš©ν•˜κ³ μžν•˜λŠ” 경우 @mimxrt, ν™•μΈν•˜μ‹œκΈ° λ°”λžλ‹ˆλ‹€ SciKeras을 (전체 곡개 : λ‚˜λŠ” μ €μž). Keras 개체λ₯Ό 선택 κ°€λŠ₯ν•˜κ²Œ λ§Œλ“œλŠ” 방법을 μ°Ύκ³  μžˆλ‹€λ©΄ https://github.com/tensorflow/tensorflow/pull/39609 , 특히 https://github.com/tensorflow/tensorflow/pull/39609#issuecommentλ₯Ό 확인

νŽΈμ§‘ : κ³ μ • 링크

μ§€κΈˆμ€ 적극적으둜 μž‘μ—…ν•˜κ³  μžˆμ§€ μ•Šμ§€λ§Œ μ—¬μ „νžˆ λ¬Έμ œμ΄λ―€λ‘œ μž¬κ°œν•©λ‹ˆλ‹€.

λΆ€μ‹€ μƒνƒœλ‘œ μ’…λ£Œλ©λ‹ˆλ‹€. 이 μž‘μ—…μ„ κ³„μ†ν•˜λ €λ©΄ λ‹€μ‹œμ—¬μ‹­μ‹œμ˜€.

문제 해결에 λ§Œμ‘±ν•˜μ‹­λ‹ˆκΉŒ?
예
μ•„λ‹ˆ

이것은 λ‹€μ‹œ 멈좜 κ²ƒμž…λ‹ˆλ‹€.

이 λ¬Έμ œλŠ” 졜근 ν™œλ™μ΄ μ—†μ—ˆκΈ° λ•Œλ¬Έμ— μžλ™μœΌλ‘œ 였래된 κ²ƒμœΌλ‘œ ν‘œμ‹œλ˜μ—ˆμŠ΅λ‹ˆλ‹€. 더 이상 ν™œλ™μ΄ λ°œμƒν•˜μ§€ μ•ŠμœΌλ©΄ νμ‡„λ©λ‹ˆλ‹€. κ°μ‚¬ν•©λ‹ˆλ‹€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰