Tensorflow: Kerasモデルはピクルス可胜ですがtf.kerasモデルはピクルス可胜ではありたせん

䜜成日 2019幎11月29日  Â·  34コメント  Â·  ゜ヌス: tensorflow/tensorflow

システムむンフォメヌション

  • りィンドりズ10
  • Tensorflow 2.0CPU
  • joblib 0.14.0
  • Python 3.7.5
  • Keras 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 

倚分これをモデルに远加できるず思いたすか これがうたくいかない堎合はありたすか

党おのコメント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バスタヌ
  • Python 3.7.6
  • joblib 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

これは、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むンポヌトした埌、アプリの最初に䞀床だけ呌び出すこずができたす。 関数を実行するず、2぀の新しいメ゜ッド__getstate__()ず__setstate__()がtensorflow.keras.models.Modelクラスに远加されるため、曎新されたtf.kerasモデルクラスのメンバヌをpickle化するたびに機胜するはずです-すなわち。 あなた自身のモデル。

これは、ファむルに保存する必芁のない@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 

倚分これをモデルに远加できるず思いたすか これがうたくいかない堎合はありたすか

Sequentialクラスで遞択できない属性が2぀あるようです。 この修正は私にも圹立ちたした

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、ナむトバヌゞョンずのコラボで詊しおみたしたが、問題を再珟するこずができたした。ここで芁点を芋぀けお

kerasモデルは遞択可胜ですが、tf.kerasは遞択可胜ではないため、これに察する代替゜リュヌションは以䞋のコヌドを参照するこず
私はあなたのコラボノヌトブックを芋お、必芁な倉曎を加えたした。以䞋ず同じコヌドをコピヌするだけで、゚ラヌの解決は完了です。

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)

if __name__ == '__ main __'
メむン

@ Edwin-Koh1

@lahsrahtidnapからの提案によるず、私はcolabで詊したしたが、問題は発生しおいたせん。ここで芁点を芋぀けお

皆さんこんにちは、
https://keras.io/の掚奚に埓っお、スタンドアロンのkerasからtensorflow.kerasに切り替えようずしおいたす。
joblib 内郚でpickleを䜿甚で

システムむンフォメヌション

  • Debian 10バスタヌ
  • Python 3.7.6
  • joblib 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

tensorflow.kerasはこれをサポヌトしおいないため、pickleたたはjoblibを䜿甚しおも問題は解決したせん。
したがっお、これに察する代替゜リュヌションは次のずおりです-

あなたのコヌドを考慮しお-
この行を眮き換えたす-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'

これは堎合によっおは機胜したすが、モデルが別の関数の䞀郚ずしおpickle化されおいる堎合は圹に立ちたせん。私の堎合、これはpython multiprocessingラむブラリを䜿甚しおいるずきに発生したす。

@ Edwin-Koh1

これはただ問題ですか
確認しおください。ありがずうございたす。

Kerasシヌケンシャルモデルを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)

@hanzigs
これは玠晎らしい解決策です、ありがずう。 この方法ではオプティマむザヌの状態が保持されないため、このモデルのトレヌニングを継続する堎合にのみ泚意しおください。

@JohannesAck
はい、新しいデヌタに合わせる前にオプティマむザヌでコンパむルする必芁がありたすが、時間はかかりたせんが、

もう1぀の方法では、model.saveをメモリに保存するのは非垞に困難です。

もう1぀の方法は、初期化ずコンパむルを䜿甚しお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'

これは堎合によっおは機胜したすが、モデルが別の関数の䞀郚ずしおpickle化されおいる堎合は圹に立ちたせん。私の堎合、これはpython multiprocessingラむブラリを䜿甚しおいるずきに発生したす。

@JohannesAck 、私は同様の問題があるかもしれないず思いたす。 GPUでKerasモデルをトレヌニングし、KerasAPIを䜿甚しおTensorFlowSavedModel圢匏を䜿甚しお保存し、新しいセッションでリロヌドし、 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/346
番号
https://docs.google.com/forms/d/e/1FAIpQLSfaP12TRhd9xSxjXZjcZFNXPGk4kc1-qMdv3gc6bEP90vY1ew/viewform?entry.85265664=No&entry.2137816233=https://github.com/tensorflow/tensorflow/issues/346

—
あなたがコメントしたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/tensorflow/tensorflow/issues/34697#issuecomment-679941192 、
たたは賌読を解陀する
https://github.com/notifications/unsubscribe-auth/AANMPP2EF3PRKBYRYHOHY3TSCOGTXANCNFSM4JSZ4QSA
。

問題が解決された埌、これはWONTFIXですか

私の堎合、ピクルス化は、コヌドがscikit-learn互換モデルを提䟛するだけの倖郚ツヌルから実行されるため私のクラスはget_clfメ゜ッドを提䟛したす、単玔にmodel.save()䜿甚するこずはできたせん。 私のコヌドはほがKeras互換tf.kerasではないであり、Keras 2.3.1TF 1.15.0のピクルスは問題なく機胜するため、この問題を回避できたした。

@mimxrt scikit-learn環境内でSciKerasを確認しおhttps //github.com/tensorflow/tensorflow/pull/39609、特にhttps://github.com/tensorflow/tensorflow/pull/39609#issuecommentを確認しおください。 -683370566

線集固定リンク

珟圚、積極的に取り組んでいたせんが、ただ問題なので再開したす。

叀くなったずしお閉じたす。 これに぀いおさらに䜜業したい堎合は、再床開いおください。

問題の解決に満足しおいたすか
はい
番号

これは再び倱速したす。

この問題は、最近のアクティビティがないため、自動的に叀いものずしおマヌクされおいたす。 それ以䞊のアクティビティが発生しない堎合は閉じられたす。 ありがずうございたした。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡