Tensorflow: рдХреЗрд░рд╕ рдореЙрдбрд▓ рдЕрдЪрд╛рд░-рд╕рдХреНрд╖рдо рд▓реЗрдХрд┐рди tf.keras рдореЙрдбрд▓ рдЕрдЪрд╛рд░-рд╕рдХреНрд╖рдо рдирд╣реАрдВ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 29 рдирд╡ре░ 2019  ┬╖  34рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: tensorflow/tensorflow

рдкреНрд░рдгрд╛рд▓реА рдХреА рдЬрд╛рдирдХрд╛рд░реА

  • рд╡рд┐рдВрдбреЛрдЬ 10
  • Tensorflow 2.0 (CPU)
  • joblib 0.14.0
  • рдЕрдЬрдЧрд░ 3.7.5
  • рдХрд╛рд░реНрд╕ 2.3.1

рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░! рдпрд╣ рдореЗрд░реА рдкрд╣рд▓реА рдкреЛрд╕реНрдЯ рд╣реИ рддреЛ рдХреГрдкрдпрд╛ рдореБрдЭреЗ рдорд╛рдл рдХрд░ рджреЗрдВ рдЕрдЧрд░ рдореИрдВрдиреЗ рдХреБрдЫ рдпрд╛рдж рдХрд┐рдпрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рдореИрдВ рдХрдИ рдПрдирдПрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЛ рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рдХрд░рдиреЗ рдФрд░ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрдиреБрд╡рдВрд╢рд┐рдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдЙрдиреНрд╣реЗрдВ рдорд▓реНрдЯреА-рдХреЛрд░ рд╕реАрдкреАрдпреВ рдкрд░ рд╕рдорд╛рдирд╛рдВрддрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЗрд╕реЗ рд╕рдорд╛рдирд╛рдВрддрд░ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЙрдмрд▓рд┐рдм рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореИрдВ рдЕрдкрдиреЗ tf.keras рдХреЛрдб рдкрд░ рдЕрдЯрдХрд╛ рд╣реБрдЖ рдерд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдкрд┐рдХ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рдерд╛ред рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рдХрдИ рдШрдВрдЯреЛрдВ рдХреЗ рдмрд╛рдж рдореБрдЭреЗ рдЕрдВрдд рдореЗрдВ рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ рдХрд┐ tf.keras рдореЙрдбрд▓ рдкрд┐рдХ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИрдВ, рдЬрдмрдХрд┐ keras рдореЙрдбрд▓ рд╣реИрдВред

рд╡рд░реНрддрдорд╛рди рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВ
рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рдХреЛрдб рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдкрдиреЗ keras рдХреЛ tf.keras рд╕реЗ рдмрджрд▓ рджрд┐рдпрд╛ рд╣реИ, рддреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рд╣реЛрдЧреА:
рдХрд╛рд░реНрдпрдХрд░реНрддрд╛рдУрдВ рдХреЛ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдХреЛ рдЕрдЪрд╛рд░ рдирд╣реАрдВ рдХрд░ рд╕рдХрд╛ред

рдЕрдкреЗрдХреНрд╖рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВ
рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реБрдП, tf.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 рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ k рд╕рдорд░реНрдерди рдХрд╛ рд╕рдорд░реНрдерди рдмрдВрдж рд╣реЛ рдЬрд╛рдПрдЧрд╛ рдФрд░ 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 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

@ рдПрдбрд╡рд┐рди-Koh1

рдХреНрдпрд╛ рдЖрдк рдХреГрдкрдпрд╛ рд░рд╛рдд рдХреЗ рд╕рдВрд╕реНрдХрд░рдг ( !pip install tf-nightly==2.1.0dev20191201 ) рдХреЗ рд╕рд╛рде рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рддреНрд░реБрдЯрд┐ рдЕрднреА рднреА рдмрдиреА рд╣реБрдИ рд╣реИред рдирд╡реАрдирддрдо рд░рд╛рдд рдХреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдкреНрд░рджрд░реНрд╢рди рд╕реБрдзрд╛рд░ рд╣реИрдВред рдзрдиреНрдпрд╡рд╛рдж!

рд╣рд╛рд▓ рдХреА рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреА рдХрдореА рдХреЗ рдХрд╛рд░рдг рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдмрдВрджред рдХреГрдкрдпрд╛ рдирдИ рдЬрд╛рдирдХрд╛рд░реА рдЙрдкрд▓рдмреНрдз рд╣реЛрдиреЗ рдкрд░ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ, рдФрд░ рд╣рдо рд╕рдорд╕реНрдпрд╛ рдХреЛ рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓ рджреЗрдВрдЧреЗред рдзрдиреНрдпрд╡рд╛рдж!

@ravikyram рдореИрдВ рдЕрднреА рднреА рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдЯреЗрдВрд╕реЛрдлрд╝реНрд▓реЛ рдкрд░ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдБ == 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 рдХреЗ рд╕рд╛рде рдХреЛрд▓рд╛рдм рдкрд░ рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИ рдФрд░ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдкреБрди: рдкреЗрд╢ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдерд╛ред рдХреГрдкрдпрд╛, рдпрд╣рд╛рдВ рдЬрд┐рд╕реНрдЯ рдвреВрдВрдвреЗрдВред рдзрдиреНрдпрд╡рд╛рдж!

@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 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ) рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╣реА рдЕрдкрд╡рд╛рдж рдорд╛рд░ рд░рд╣рд╛ рд╣реВрдБред

рдкреНрд░рдгрд╛рд▓реА рдХреА рдЬрд╛рдирдХрд╛рд░реА:

  • рдбреЗрдмрд┐рдпрди 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

рдпрд╣рд╛рдБ рдПрдХ рдлрд┐рдХреНрд╕ 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 рдореЙрдбрд▓ рд╡рд░реНрдЧ рдХреЗ рдХрд┐рд╕реА рд╕рджрд╕реНрдп рдХреЛ рдЕрдЪрд╛рд░ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЙрд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрд░реНрдерд╛рддред рдЖрдкрдХрд╛ рдЕрдкрдирд╛ рдореЙрдбрд▓

рдпрд╣рд╛рдБ @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)
~                     

рдореИрдВрдиреЗ TF рд╕рдВрд╕реНрдХрд░рдг 2.2, рд░рд╛рдд рдХреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдХреЛрд▓рд╛рдм рдореЗрдВ рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИ рдФрд░ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдкреБрди: рдкреЗрд╢ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдерд╛ред рдХреГрдкрдпрд╛, рдпрд╣рд╛рдВ рдЬрд╛рдЗрдВрдЯ рдЦреЛрдЬреЗрдВ

рдореИрдВрдиреЗ TF рд╕рдВрд╕реНрдХрд░рдг 2.2, рд░рд╛рдд рдХреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдХреЛрд▓рд╛рдм рдореЗрдВ рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИ рдФрд░ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдкреБрди: рдкреЗрд╢ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдерд╛ред рдХреГрдкрдпрд╛, рдпрд╣рд╛рдВ рдЬрд╛рдЗрдВрдЯ рдЦреЛрдЬреЗрдВ

рдХреЗрд░рд╕ рдореЙрдбрд▓ рдкрд┐рдХ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИ рд▓реЗрдХрд┐рди tf.keras рдкрд┐рдХ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХреЗ рд▓рд┐рдП рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕рдорд╛рдзрд╛рди рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдХреЛрдб рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИ
рдореИрдВрдиреЗ рдЖрдкрдХрд╛ рдХреЛрд▓рд╛рдм рдиреЛрдЯрдмреБрдХ рджреЗрдЦрд╛ рдФрд░ рдЖрд╡рд╢реНрдпрдХ рдмрджрд▓рд╛рд╡ рдХрд┐рдП рдмрд╕ рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдХреЛрдб рдХреЛ рдХреЙрдкреА рдХрд░реЗрдВ рдФрд░ рдЖрдкрдХреЛ рддреНрд░реБрдЯрд┐ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ

tf рдХреЗ рд░реВрдк рдореЗрдВ рдЖрдпрд╛рдд рд╕реНрдкрд░реНрд╢рд░реЗрдЦрд╛

def рдореБрдЦреНрдп ():
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__ == '__main__':
рдореБрдЦреНрдп()

@ рдПрдбрд╡рд┐рди-Koh1

@Lahshthtnnap рдХреЗ рд╕реБрдЭрд╛рд╡ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдореИрдВрдиреЗ рдпрд╣рд╛рдБ рдЬреЗрдВрдЯ рдвреВрдВрдвреЗ

рд╣реЗрд▓реЛ рд╕рдм рд▓реЛрдЧ,
рдореИрдВ рд╕реНрдЯреИрдВрдбрдЕрд▓реЛрди keras рд╕реЗ tensorflow.keras рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢ рдХреЗ рдЕрдиреБрд╕рд╛рд░ https://keras.io/ рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ
рдореИрдВ joblib рд╕рд╛рде # 34697 (рдЯрд┐рдкреНрдкрдгреА) рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╣реА рдЕрдкрд╡рд╛рдж рдХреЛ рдорд╛рд░ рд░рд╣рд╛ рд╣реВрдВ (рдЬреЛ рд╣реБрдб рдХреЗ рдиреАрдЪреЗ pickle рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ)ред

рдкреНрд░рдгрд╛рд▓реА рдХреА рдЬрд╛рдирдХрд╛рд░реА:

  • рдбреЗрдмрд┐рдпрди 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

рдЕрдЪрд╛рд░ рдпрд╛ рдЬреЙрдмрд▓реАрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЖрдкрдХреА рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рдирд╣реАрдВ рд╣реЛрдЧреА рдХреНрдпреЛрдВрдХрд┐ рдЯреЗрдВрд╕рд░рдлрд╝реНрд▓реЛ.рдХреЗрд░рд╕ рдЗрд╕рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
рддреЛ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╡реИрдХрд▓реНрдкрд┐рдХ рдЙрдкрд╛рдп рд╣реИ: -

рдЕрдкрдиреЗ рдХреЛрдб рдкрд░ рд╡рд┐рдЪрд╛рд░: -
рдЗрд╕ рдкрдВрдХреНрддрд┐ рдХреЛ рдмрджрд▓реЗрдВ: - joblib.dump (рдореЙрдбрд▓, 'model.pkl')
рд╕рд╛рде рдореЗрдВ: -
рдореЙрдбрд▓ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП: -
-----> model.save ('new_model.h5')
рдФрд░ рдпрджрд┐ рдЖрдк рдЗрд╕ рдореЙрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рд▓реЛрдб рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ: -
-----> new_model = tf.keras.models.load_model ('new_model.h5')

рдЕрдкрдиреЗ рдХреЛрдб рдкрд░ рд╡рд┐рдЪрд╛рд░: -
рдЗрд╕ рдкрдВрдХреНрддрд┐ рдХреЛ рдмрджрд▓реЗрдВ: - joblib.dump (рдореЙрдбрд▓, 'model.pkl')
рд╕рд╛рде рдореЗрдВ: -
рдореЙрдбрд▓ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП: -
-----> model.save ('new_model.h5')
рдФрд░ рдпрджрд┐ рдЖрдк рдЗрд╕ рдореЙрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рд▓реЛрдб рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ: -
-----> new_model = tf.keras.models.load_model ('new_model.h5')

рдпрд╣ рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рддрдм рдорджрдж рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдЬрдм рдХрд┐рд╕реА рдореЙрдбрд▓ рдХреЛ рджреВрд╕рд░реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЪреБрдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рдЕрдЬрдЧрд░ multiprocessing рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рд╣реЛрддрд╛ рд╣реИред

@ рдПрдбрд╡рд┐рди-Koh1

рдХреНрдпрд╛ рдпрд╣ рдЕрднреА рднреА рдПрдХ рдореБрджреНрджрд╛ рд╣реИ?
рдХреГрдкрдпрд╛, рдкреБрд╖реНрдЯрд┐ рдХрд░реЗрдВред рдзрдиреНрдпрд╡рд╛рдж!

рдХреНрдпрд╛ рдмрд╛рдЗрдЯрд┐рдпреЛ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рдХреЗрд░рд╕ рд╕реЗрдХреНрд╢рдирд▓ рдореЙрдбрд▓ рдХреЛ рдбрдВрдк рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ

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

рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдЖрдкрдХреЛ рдЖрдзрд╛рд░ 64 рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдореЗрд░реЗ рд▓рд┐рдП рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕рдм рдХреБрдЫ-рдЗрди-рдореЗрдореЛрд░реА, рдХреЛрдИ рдЯрдЪ рдбрд┐рд╕реНрдХ рдирд╣реАрдВ рд╣реИ

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)

@hanzigs
рдпрд╣ рдПрдХ рдЕрдЪреНрдЫрд╛ рд╕рдорд╛рдзрд╛рди рд╣реИ, рдзрдиреНрдпрд╡рд╛рджред рдпрджрд┐ рдЖрдк рдЗрд╕ рдореЙрдбрд▓ рдХрд╛ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рддреЗ рд╣реИрдВ рддреЛ рдХреЗрд╡рд▓ рд╕рд╛рд╡рдзрд╛рди рд░рд╣реЗрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╡рд┐рдзрд┐ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝рд░ рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдирд╣реАрдВ рдХрд░рддреА рд╣реИред

@JohannesAck
рд╣рд╛рдВ, рд╣рдореЗрдВ рдирдП рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдлрд┐рдЯ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝рд░ рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рди рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЬреЛ рдХрд┐ рд╕рдордп рд▓реЗрдиреЗ рд╡рд╛рд▓рд╛ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП,

рджреВрд╕рд░реЗ рддрд░реАрдХреЗ рд╕реЗ рдореЙрдбрд▓.рд╕реНрд╡реЗ рдЗрди-рдореЗрдореЛрд░реА рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рдирд╛ рдмрд╣реБрдд рдХрдард┐рди рд╣реИред

рдПрдХ рдФрд░ рддрд░реАрдХрд╛ рд╣реИ рдХрд┐ рд╣рдо get_config () рдФрд░ from_config () рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рд╕рд╛рде рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ рдирдП рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рдлрд┐рдЯ рд╣реЛрдирд╛ рд╣реЛрдЧрд╛ред

@ рдПрдбрд╡рд┐рди-Koh1

рдЗрд╕ рдореБрджреНрджреЗ рдкрд░ рдХреЛрдИ рдЕрджреНрдпрддрди рдХреГрдкрдпрд╛ред рдзрдиреНрдпрд╡рд╛рдж!

рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдмрд╛рд╕реА рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ рд╣рд╛рд▓ рдХреА рдЧрддрд┐рд╡рд┐рдзрд┐ рдирд╣реАрдВ рдереАред рдЖрдЧреЗ рдХреЛрдИ рдЧрддрд┐рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реЛрдиреЗ рдкрд░ рдЗрд╕реЗ рдмрдВрдж рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдзрдиреНрдпрд╡рд╛рджред

рдЕрдкрдиреЗ рдХреЛрдб рдкрд░ рд╡рд┐рдЪрд╛рд░: -
рдЗрд╕ рдкрдВрдХреНрддрд┐ рдХреЛ рдмрджрд▓реЗрдВ: - joblib.dump (рдореЙрдбрд▓, 'model.pkl')
рд╕рд╛рде рдореЗрдВ: -
рдореЙрдбрд▓ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП: -
-----> model.save ('new_model.h5')
рдФрд░ рдпрджрд┐ рдЖрдк рдЗрд╕ рдореЙрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рд▓реЛрдб рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ: -
-----> new_model = tf.keras.models.load_model ('new_model.h5')

рдпрд╣ рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рддрдм рдорджрдж рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдЬрдм рдХрд┐рд╕реА рдореЙрдбрд▓ рдХреЛ рджреВрд╕рд░реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЪреБрдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рдЕрдЬрдЧрд░ multiprocessing рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рд╣реЛрддрд╛ рд╣реИред

@JohannesAck , рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рдорд╛рди рдореБрджреНрджрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдореИрдВ GPU рдкрд░ рдПрдХ Keras рдореЙрдбрд▓ рдХреЛ рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рдХрд░рддрд╛ рд╣реВрдВ, рдЗрд╕реЗ Keras API рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ TensorFlow SavedModel рдкреНрд░рд╛рд░реВрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рд╣реЗрдЬрддрд╛ рд╣реВрдВ, рдЗрд╕реЗ рдирдП рд╕рддреНрд░ рдореЗрдВ рдЕрдирд▓реЛрдб рдХрд░рддрд╛ рд╣реВрдВ, multiprocessing рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдФрд░ starmap рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдХрдИ CPU рдкрд░ рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгрд┐рдпрд╛рдВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реВрдВред TypeError: can't pickle _thread.RLock objects ) рдорд┐рд▓рддреА рд╣реИред рдпрджрд┐ рдореИрдВ рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рд░ рдЕрдкрдиреЗ рдкреВрд░реНрд╡рд╛рдиреБрдорд╛рди рдХрд╛рд░реНрдп рдХреЗ рднреАрддрд░ рдореЙрдбрд▓ рдХреЛ рд▓реЛрдб рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрдВрдд рдореЗрдВ рдЗрд╕реЗ рд╣рдЯрд╛рддрд╛ рд╣реВрдВ рддреЛ рдпрд╣ рдХреБрдЫ рдкреВрд░реНрд╡рд╛рдиреБрдорд╛рдиреЛрдВ рдХреЗ рдмрд╛рдж рд▓рдЯрдХрд╛ рд╣реБрдЖ рд╣реИред рдХреНрдпрд╛ рдЖрдкрдХреЛ рдкрддрд╛ рд╣реИ рдХрд┐ рдпрд╣рд╛рдВ рдХреНрдпрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ?

рдмрд╛рд╕реА рдХреЗ рд░реВрдк рдореЗрдВ рдмрдВрджред рдХреГрдкрдпрд╛ рдкреБрдирдГ рдЦреЛрд▓реЗрдВ рдпрджрд┐ рдЖрдк рдЗрд╕ рдкрд░ рдЖрдЧреЗ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдХреНрдпрд╛ рдЖрдк рдЕрдкрдиреЗ рдореБрджреНрджреЗ рдХреЗ рд╕рдорд╛рдзрд╛рди рд╕реЗ рд╕рдВрддреБрд╖реНрдЯ рд╣реИрдВ?
рд╣рд╛рдБ
рдирд╣реАрдВ

рдЬрд╣рд╛рдБ рддрдХ рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдпрд╣ рдмрд╛рд╕реА рдирд╣реАрдВ рд╣реИред

рдЯреАрдпреВ рдкрд░, 25 рдЕрдЧрд╕реНрдд, 2020, 5:26 рдкреВрд░реНрд╡рд╛рд╣реНрди рдЯреЗрдВрд╕рд░рдлрд╝реНрд▓реЛ-рдмрдЯрд▓рд░ [рдмреЙрдЯ] <
рд╕реВрдЪрдирд╛рдПрдВ@github.com> рдиреЗ рд▓рд┐рдЦрд╛:

рдХреНрдпрд╛ рдЖрдк рдЕрдкрдиреЗ рдореБрджреНрджреЗ рдХреЗ рд╕рдорд╛рдзрд╛рди рд╕реЗ рд╕рдВрддреБрд╖реНрдЯ рд╣реИрдВ?
рд╣рд╛рдБ
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 рд╣реИ?

рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдореИрдВ рдХреЗрд╡рд▓ model.save() рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЕрдЪрд╛рд░ рдХрд┐рд╕реА рдмрд╛рд╣рд░реА рдЙрдкрдХрд░рдг рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдореЗрд░рд╛ рдХреЛрдб рдХреЗрд╡рд▓ рдПрдХ рд╕реНрдХрд┐рдЯрд┐рдЯ-рд▓рд░реНрди рд╕рдВрдЧрдд рдореЙрдбрд▓ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ (рдореЗрд░реА рдХрдХреНрд╖рд╛ get_clf рд╡рд┐рдзрд┐ рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИ)ред рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЗ рдЗрд░реНрдж-рдЧрд┐рд░реНрдж рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рдерд╛ рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░рд╛ рдХреЛрдб (рд▓рдЧрднрдЧ) рдХреЗрд░реЗрд╕-рд╕рдВрдЧрдд (tf.keras) рдирд╣реАрдВ рдерд╛, рдФрд░ рдХреЗрд░рд╕ 2.3.1 (TF 1.15.0) рдмрд┐рдирд╛ рдХрд┐рд╕реА рдореБрджреНрджреЗ рдХреЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

@ рдорд┐рдХреНрд╕рдПрдХреНрд╕рд░реНрдЯ рдпрджрд┐ рдЖрдк рдПрдХ рд╕реНрдХреЛрд░-рд▓рд░реНрди рдПрдирд╡ рдХреЗ рднреАрддрд░ рдХреЗрд░рд╕ рдореЙрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рд╛рдЗрдВрдХреЗрд░рд╕ (рдкреВрд░реНрдг рдкреНрд░рдХрдЯреАрдХрд░рдг: рдореИрдВ рд▓реЗрдЦрдХ рд╣реВрдВ) рджреЗрдЦреЗрдВред рдпрджрд┐ рдЖрдк рдХреЗрд╡рд▓ рдХреЗрд░ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд▓рд╛рдЗрд╕реЗрдмрд▓ рдмрдирд╛рдиреЗ рдХреА рд░рд╛рд╣ рджреЗрдЦ рд░рд╣реЗ рд╣реИрдВ, рддреЛ https://github.com/tensorflow/tensorflow/pull/39609 рдФрд░ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ https://github.com/tensorflow/tensorflow/null/39609#issuecomment рдкрд░ рдЬрд╛рдБрдЪ

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдирд┐рд╢реНрдЪрд┐рдд рд▓рд┐рдВрдХ

рд╣рдо рдЕрднреА рдЗрд╕ рдкрд░ рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓рдирд╛ рдЕрднреА рднреА рдПрдХ рдореБрджреНрджрд╛ рд╣реИред

рдмрд╛рд╕реА рдХреЗ рд░реВрдк рдореЗрдВ рдмрдВрджред рдХреГрдкрдпрд╛ рдкреБрдирдГ рдЦреЛрд▓реЗрдВ рдпрджрд┐ рдЖрдк рдЗрд╕ рдкрд░ рдЖрдЧреЗ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдХреНрдпрд╛ рдЖрдк рдЕрдкрдиреЗ рдореБрджреНрджреЗ рдХреЗ рд╕рдорд╛рдзрд╛рди рд╕реЗ рд╕рдВрддреБрд╖реНрдЯ рд╣реИрдВ?
рд╣рд╛рдБ
рдирд╣реАрдВ

рдпрд╣ рдлрд┐рд░ рд╕реЗ рдардк рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдмрд╛рд╕реА рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ рд╣рд╛рд▓ рдХреА рдЧрддрд┐рд╡рд┐рдзрд┐ рдирд╣реАрдВ рдереАред рдЖрдЧреЗ рдХреЛрдИ рдЧрддрд┐рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реЛрдиреЗ рдкрд░ рдЗрд╕реЗ рдмрдВрдж рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдзрдиреНрдпрд╡рд╛рджред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

jacobma-create picture jacobma-create  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

aerointern16 picture aerointern16  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

fobus42 picture fobus42  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

ilblackdragon picture ilblackdragon  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

nicholaslocascio picture nicholaslocascio  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ