Obtention de TypeError: impossible de sélectionner les objets _thread.RLock

Oct 13 2020

Lisez un certain nombre de questions similaires, la plupart d'entre elles ont mentionné que vous ne devriez pas essayer de sérialiser un objet non sérialisable. Je ne suis pas en mesure de comprendre le problème. Je suis capable d'enregistrer le modèle en tant que fichier .h5 mais cela ne sert pas le but de ce que j'essaie de faire. Veuillez aider!

    def image_generator(train_data_dir, test_data_dir):
        train_datagen = ImageDataGenerator(rescale=1/255,
                                          rotation_range = 30,  
                                          zoom_range = 0.2, 
                                          width_shift_range=0.1,  
                                          height_shift_range=0.1,
                                          validation_split = 0.15)
      
        test_datagen = ImageDataGenerator(rescale=1/255)
        
        train_generator = train_datagen.flow_from_directory(train_data_dir,
                                      target_size = (160,160),
                                      batch_size = 32,
                                      class_mode = 'categorical',
                                      subset='training')
        
        val_generator = train_datagen.flow_from_directory(train_data_dir,
                                      target_size = (160,160),
                                      batch_size = 32,
                                      class_mode = 'categorical',
                                      subset = 'validation')
        
        test_generator = test_datagen.flow_from_directory(test_data_dir,
                                     target_size=(160,160),
                                     batch_size = 32,
                                     class_mode = 'categorical')
        return train_generator, val_generator, test_generator
    
    def model_output_for_TL (pre_trained_model, last_output):    
        x = Flatten()(last_output)
        
        # Dense hidden layer
        x = Dense(512, activation='relu')(x)
        x = Dropout(0.2)(x)
        
        # Output neuron. 
        x = Dense(2, activation='softmax')(x)
        
        model = Model(pre_trained_model.input, x)
        
        return model
    
    train_generator, validation_generator, test_generator = image_generator(train_dir,test_dir)
    
    pre_trained_model = InceptionV3(input_shape = (160, 160, 3), 
                                    include_top = False, 
                                    weights = 'imagenet')
    for layer in pre_trained_model.layers:
      layer.trainable = False
    last_layer = pre_trained_model.get_layer('mixed5')
    last_output = last_layer.output
    model_TL = model_output_for_TL(pre_trained_model, last_output)
    
    model_TL.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
    
    history_TL = model_TL.fit(
          train_generator,
          steps_per_epoch=10,  
          epochs=10,
          verbose=1,
          validation_data = validation_generator)
    
    pickle.dump(model_TL,open('img_model.pkl','wb'))

Réponses

2 TFer2 Oct 14 2020 at 01:13

J'ai pu reproduire votre problème dans TF 2.3.0 à l'aide de Google Colab

import pickle
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='adam', loss='categorical_crossentropy', metrics=['accuracy'])

with open('model.pkl', 'wb') as f:
    pickle.dump(model, f)

Production:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-afb2bf58a891> in <module>()
      8 
      9 with open('model.pkl', 'wb') as f:
---> 10     pickle.dump(model, f)

TypeError: can't pickle _thread.RLock objects

@adriangb, correctif proposé pour ce problème dans github pour plus de détails, veuillez vous référer à ceci

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='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# Save
with open('model.pkl', 'wb') as f:
    pickle.dump(model, f)