Bắt lỗi TypeError: không thể chọn đối tượng _thread.RLock

Oct 13 2020

Đọc một số câu hỏi tương tự, hầu hết trong số họ đề cập rằng bạn không nên cố gắng tuần tự hóa một đối tượng không thể biến hóa. Tôi không thể hiểu vấn đề. Tôi có thể lưu mô hình dưới dạng tệp .h5 nhưng điều đó không phục vụ mục đích của những gì tôi đang cố gắng thực hiện. Hãy giúp tôi!

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

Trả lời

2 TFer2 Oct 14 2020 at 01:13

Tôi đã có thể tái tạo sự cố của bạn trong TF 2.3.0 bằng 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)

Đầu ra:

---------------------------------------------------------------------------
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, đề xuất sửa lỗi nóng cho vấn đề này trong github để biết thêm chi tiết, vui lòng tham khảo phần này

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)