首页 文章

Keras Lambda层和变量:“TypeError:无法pickle _thread.lock对象”

提问于
浏览
3

使用lambda图层和共享变量时,我无法保存keras模型 . 这是一个提供此错误的最小代码:

# General imports.
import numpy as np

# Keras for deep learning.
from keras.layers.core import Dense,Lambda
from keras.layers import Input
from keras.models import Model
import keras.backend as K

n_inputs = 20
n_instances = 100

def preprocess(X,minimum,span):
    output = (X - minimum)/span
    return output

inputs = Input(shape=(n_inputs,),name='input_tensor')
maximum = K.max(inputs)
minimum = K.min(inputs)
span = maximum - minimum

x = Lambda(preprocess,arguments={'minimum':minimum,'span':span})(inputs)
x = Dense(units=100,activation='elu')(x)
outputs = Dense(units=n_inputs,activation='elu')(x)

model = Model(inputs=inputs,outputs=outputs)
model.compile(optimizer='adam', loss='mse')

x = np.array([np.random.randn(20) for i in range(n_instances)])
y = np.array([np.random.randn(20) for i in range(n_instances)])

model.fit(x,y,epochs=10)
model.save('test.h5')       # This line doesn't work.

这是我得到的完整错误:

Traceback (most recent call last):
  File "C:\Dropbox\HELMo_Gramme\M2\Stage\Programmation\Filter\sanstitre0.py", line 35, in <module>
    model.save('test.h5')       # This line doesn't work.
  File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\topology.py", line 2580, in save
    save_model(self, filepath, overwrite, include_optimizer)
  File "C:\ProgramData\Anaconda3\lib\site-packages\keras\models.py", line 111, in save_model
    'config': model.get_config()
  File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\topology.py", line 2421, in get_config
    return copy.deepcopy(config)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 215, in _deepcopy_list
    append(deepcopy(a, memo))
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 180, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 280, in _reconstruct
    state = deepcopy(state, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 180, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 280, in _reconstruct
    state = deepcopy(state, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 180, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 280, in _reconstruct
    state = deepcopy(state, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 169, in deepcopy
    rv = reductor(4)
TypeError: can't pickle _thread.lock objects

该模型可以训练并可用于预测,该问题仅在保存时出现 . 我已经看到使用lambda图层的人有类似的错误(例如this link),但我认为我的问题略有不同(大多数时候它使用的是seq2seq.py我不使用) . 但它似乎仍然与深拷贝相关联 .

如果我删除lambda图层或外部变量,它的工作原理 . 我可能正在做一些我不应该对变量做的事情,但我不知道如何正确地做到这一点 . 我需要它们超出预处理函数的范围,因为我在后处理函数中使用那些相同的变量 .

我知道模型中的预处理不是最有效的,但我有理由这样做,性能不是这个数据集的问题 .

更新

我忘了澄清我希望能够在另一个Lambda层中重用 maximumminimumspan ,这就是为什么它们被定义在 preprocess 范围之外的原因 .

更新2

maxim的解决方案确实有所帮助,但它仍然无法在我的实际代码中使用 . 不同之处在于我实际上在一个函数中创建了我的模型并返回它,并以某种方式返回相同类型的错误 .

示例代码:

# General imports.
import numpy as np

# Keras for deep learning.
from keras.layers.core import Dense,Lambda
from keras.layers import Input
from keras.models import Model
import keras.backend as K

n_inputs = 101
n_instances = 100

def create_model(n_inputs):

    def preprocess(X):
        maximum = K.max(inputs)
        minimum = K.min(inputs)
        span = maximum - minimum
        output = (X - minimum)/span
        return output

    def postprocess(X):
        maximum = K.max(inputs)
        minimum = K.min(inputs)
        span = maximum - minimum
        output = X*span + minimum
        return output

    inputs = Input(shape=(n_inputs,),name='input_tensor')

    x = Lambda(preprocess)(inputs)
    x = Dense(units=100,activation='elu')(x)
    outputs = Dense(units=n_inputs,activation='elu')(x)
    outputs = Lambda(postprocess)(outputs)

    model = Model(inputs=inputs,outputs=outputs)
    model.compile(optimizer='adam', loss='mse')
    return model

x = np.array([np.random.randn(n_inputs) for i in range(n_instances)])
y = np.array([np.random.randn(n_inputs) for i in range(n_instances)])

model = create_model(n_inputs)
model.fit(x,y,epochs=10)
model.save('test.h5')       # This line doesn't work.

错误:

Traceback (most recent call last):
  File "C:\Dropbox\HELMo_Gramme\M2\Stage\Programmation\Filter\sanstitre0.py", line 46, in <module>
    model.save('test.h5')       # This line doesn't work.
  File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\topology.py", line 2580, in save
    save_model(self, filepath, overwrite, include_optimizer)
  File "C:\ProgramData\Anaconda3\lib\site-packages\keras\models.py", line 111, in save_model
    'config': model.get_config()
  File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\topology.py", line 2421, in get_config
    return copy.deepcopy(config)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 215, in _deepcopy_list
    append(deepcopy(a, memo))
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 220, in _deepcopy_tuple
    y = [deepcopy(a, memo) for a in x]
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 220, in <listcomp>
    y = [deepcopy(a, memo) for a in x]
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 220, in _deepcopy_tuple
    y = [deepcopy(a, memo) for a in x]
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 220, in <listcomp>
    y = [deepcopy(a, memo) for a in x]
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 180, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 280, in _reconstruct
    state = deepcopy(state, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 180, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 280, in _reconstruct
    state = deepcopy(state, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 180, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 280, in _reconstruct
    state = deepcopy(state, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\ProgramData\Anaconda3\lib\copy.py", line 169, in deepcopy
    rv = reductor(4)
TypeError: can't pickle _thread.lock objects

need 在函数中创建我的模型,因为我正在优化超参数,因此我使用不同的参数集迭代不同的模型(我可能在循环中做它但它不是那么好) .

1 回答

  • 1

    问题出在lambda参数: minimumspan . 它们是从输入推断出来的,但是当你像这样定义lambda层时:

    x = Lambda(preprocess,arguments={'minimum':minimum,'span':span})(inputs)
    

    ......它们被认为是需要序列化的独立参数(作为lambda的上下文) . 这会导致错误,因为它们都是张量流张量,而不是静态值或numpy数组 .

    将您的代码更改为:

    # `preprocess` encapsulates all intermediate values in itself.
    def preprocess(X):
      maximum = K.max(X)
      minimum = K.min(X)
      span = maximum - minimum
      output = (X - minimum) / span
      return output
    
    inputs = Input(shape=(n_inputs,), name='input_tensor')
    x = Lambda(preprocess)(inputs)
    

相关问题