Имя переменной определяет успех или неудачу Keras load_model (проблема уровня лямбда) - PullRequest
0 голосов
/ 06 августа 2020

Рассмотрим следующий безобидный фрагмент кода:

K=10    # include to cause error; leave out or use N=10 and load_model succeeds!
model = tf.keras.models.load_model( 'model.h5' )

Чтобы уточнить комментарий: если код выполняется как есть, создается следующая трассировка ошибки. Если я использую N (или X или C et c) вместо K, модель загружается нормально. Если K определяется после строки load_model(), модель также загружается нормально. Но как есть, я получаю:

Traceback (most recent call last):
  File "D:\Alchemy\Software\Test\Deep Learning\models\tf\loadspec.py", line 80, in <module>
    model = tf.keras.models.load_model( 'model.h5' )
  File "D:\Alchemy\Software\Test\Deep Learning\models\tf2.2\lib\site-packages\tensorflow\python\keras\saving\save.py", line 184, in load_model
    return hdf5_format.load_model_from_hdf5(filepath, custom_objects, compile)
  File "D:\Alchemy\Software\Test\Deep Learning\models\tf2.2\lib\site-packages\tensorflow\python\keras\saving\hdf5_format.py", line 177, in load_model_from_hdf5
    model = model_config_lib.model_from_config(model_config,
  File "D:\Alchemy\Software\Test\Deep Learning\models\tf2.2\lib\site-packages\tensorflow\python\keras\saving\model_config.py", line 55, in model_from_config
    return deserialize(config, custom_objects=custom_objects)
  File "D:\Alchemy\Software\Test\Deep Learning\models\tf2.2\lib\site-packages\tensorflow\python\keras\layers\serialization.py", line 105, in deserialize
    return deserialize_keras_object(
  File "D:\Alchemy\Software\Test\Deep Learning\models\tf2.2\lib\site-packages\tensorflow\python\keras\utils\generic_utils.py", line 369, in deserialize_keras_object
    return cls.from_config(
  File "D:\Alchemy\Software\Test\Deep Learning\models\tf2.2\lib\site-packages\tensorflow\python\keras\engine\sequential.py", line 399, in from_config
    model.add(layer)
  File "D:\Alchemy\Software\Test\Deep Learning\models\tf2.2\lib\site-packages\tensorflow\python\training\tracking\base.py", line 456, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "D:\Alchemy\Software\Test\Deep Learning\models\tf2.2\lib\site-packages\tensorflow\python\keras\engine\sequential.py", line 213, in add
    output_tensor = layer(self.outputs[0])
  File "D:\Alchemy\Software\Test\Deep Learning\models\tf2.2\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 922, in __call__
    outputs = call_fn(cast_inputs, *args, **kwargs)
  File "D:\Alchemy\Software\Test\Deep Learning\models\tf2.2\lib\site-packages\tensorflow\python\keras\layers\core.py", line 1191, in call
    if K.is_sparse(inputs):
AttributeError: 'int' object has no attribute 'is_sparse'

Я знаю слишком мало python, чтобы разобраться в этом ... но похоже, что K как-то так плохо охарактеризован, что K I использованный в моем коде на верхнем уровне путается с каким-то другим K глубоко в core.py Кераса. Звучит очень плохо. Но также похоже, что root проблема находится в отдельном модуле, который сохраняет файл model.h5.

В этом отдельном модуле K определяется / используется следующим образом:

# train_labels are integers in range 0-??? - convert to one-hot...
train_labels = tf.keras.utils.to_categorical(train_labels)
K = len(train_labels[ 0 ])
...
model = Sequential()
# Hidden Dense layer + Lambda layer to implement Leaky ReLU ommitted...
model.add(Dense(K, activation='softmax', name='Output'))

Это кажется очень разумным - определить количество выходов из данных. Но тогда как это переменное количество выходов приводит к модели, которая, кажется, (и на каком-то уровне сохраняет) успешно ... но приводит к проблеме ниже по потоку, если я использую K? Это проблема с использованием Keras ... или ядра Keras?

Последующее открытие: это как-то связано со слоем Lambda(), реализующим мой Leaky ReLU. Вот три варианта пропущенного кода скрытого слоя выше, только первый из них работает без проблем ... но делает это, жертвуя желаемым неплотным характером активации ReLU:

    model.add(Dense(10, activation='relu', name='Hidden'))    # only this saves without any problems
    -= OR =-
    model.add(Dense(10, name='Hidden'))
    model.add(Lambda(lambda x: tf.keras.activations.relu(x, alpha=0.01), name='LeakyReLU'))
    -= OR =-
    model.add(Dense(10, name='Hidden'))
    lrelu = lambda x: tf.keras.activations.relu(x, alpha=0.01)
    model.add(Lambda(lrelu, name='LeakyReLU'))
...