NotImplementedError: Слои с аргументами в `__init__` должны переопределять` get_config` - PullRequest
1 голос
/ 03 ноября 2019

Я пытаюсь сохранить свою модель TensorFlow, используя model.save(), однако - я получаю эту ошибку.

Сводка модели представлена ​​здесь: Сводка модели

Код для модели трансформатора:

def transformer(vocab_size, num_layers, units, d_model, num_heads, dropout, name="transformer"):
    inputs = tf.keras.Input(shape=(None,), name="inputs")
    dec_inputs = tf.keras.Input(shape=(None,), name="dec_inputs")

    enc_padding_mask = tf.keras.layers.Lambda(
        create_padding_mask, output_shape=(1, 1, None),
        name='enc_padding_mask')(inputs)
    # mask the future tokens for decoder inputs at the 1st attention block
    look_ahead_mask = tf.keras.layers.Lambda(
        create_look_ahead_mask,
        output_shape=(1, None, None),
        name='look_ahead_mask')(dec_inputs)
    # mask the encoder outputs for the 2nd attention block
    dec_padding_mask = tf.keras.layers.Lambda(
        create_padding_mask, output_shape=(1, 1, None),
        name='dec_padding_mask')(inputs)

    enc_outputs = encoder(
        vocab_size=vocab_size,
        num_layers=num_layers,
        units=units,
        d_model=d_model,
        num_heads=num_heads,
        dropout=dropout,
    )(inputs=[inputs, enc_padding_mask])

    dec_outputs = decoder(
        vocab_size=vocab_size,
        num_layers=num_layers,
        units=units,
        d_model=d_model,
        num_heads=num_heads,
        dropout=dropout,
    )(inputs=[dec_inputs, enc_outputs, look_ahead_mask, dec_padding_mask])

    outputs = tf.keras.layers.Dense(units=vocab_size, name="outputs")(dec_outputs)

    return tf.keras.Model(inputs=[inputs, dec_inputs], outputs=outputs, name=name)

Я не понимаю, почему она выдает эту ошибку, так как модель работает отлично. Буду признателен за любую помощь.

Мой код сохранения для справки:

print("Saving the model.")
saveloc = "C:/tmp/solar.h5"
model.save(saveloc)
print("Model saved to: " + saveloc + " succesfully.")

Ответы [ 2 ]

0 голосов
/ 11 ноября 2019

Это не ошибка, это особенность.

Эта ошибка позволяет вам знать, что TF не может сохранить вашу модель, потому что она не сможет ее загрузить.
В частности, она выигралане сможет восстановить ваши пользовательские Layer классы: encoder и decoder.

Чтобы решить эту проблему, просто переопределяет их метод get_config в соответствии с добавленными вами новыми аргументами.

Конфигурация слоя - это словарь Python (сериализуемый), содержащий конфигурацию слоя. Этот же слой можно восстановить позже (без его обученных весов) из этой конфигурации.


Например, если ваш класс encoder выглядит примерно так:

class encoder(tf.keras.layers.Layer):

    def __init__(
        self,
        vocab_size, num_layers, units, d_model, num_heads, dropout,
        **kwargs,
    ):
        super().__init__(**kwargs)
        self.vocab_size = vocab_size
        self.num_layers = num_layers
        self.units = units
        self.d_model = d_model
        self.num_heads = num_heads
        self.dropout = dropout

    # Other methods etc.

тогда вам нужно только переопределить этот метод:

    def get_config(self):

        config = super().get_config().copy()
        config.update({
            'vocab_size': self.vocab_size,
            'num_layers': self.num_layers,
            'units': self.units,
            'd_model': self.d_model,
            'num_heads': self.num_heads,
            'dropout': self.dropout,
        })
        return config

Когда TF увидит это (для обоих классов), вы сможете сохранить модель.

Потому что теперь, когда модельзагружен, TF сможет восстановить тот же слой из конфигурации.


Layer.from_config * исходный код можетдать лучшее представление о том, как это работает:

@classmethod
def from_config(cls, config):
  return cls(**config)
0 голосов
/ 03 ноября 2019

Кажется, это внутренняя проблема в TensorFlow.

После некоторого поиска в Google, просмотра GitHub и обнаружения относительно похожей проблемы - я пришел к такому выводу.

Исследованные материалы могут бытьнайдено здесь:

"... недавно исправлено в 498e815, но мы еще не добавили его в 2.0 rc ... "

Пока сами TensorFlow не исправят это в своих выпусках, могут быть сохранены только веса, и модель должна быть перекомпилирована в каждом экземпляре.

Сохранение весов:

# Saving model weights.
model.save_weights("C:/tmp/solar-model/solar", save_format = "tf")

# If you want to save it in a zip.
zipdir = "model.zip"
zipreference = zipfile.ZipFile(zipdir, "w")
zipreference.write("C:/tmp/solar-model/checkpoint", compress_type = zipfile.ZIP_DEFLATED)
zipreference.write("C:/tmp/solar-model/solar.data-00000-of-00002", compress_type = zipfile.ZIP_DEFLATED)
zipreference.write("C:/tmp/solar-model/solar.data-00001-of-00002", compress_type = zipfile.ZIP_DEFLATED)
zipreference.write("C:/tmp/solar-model/solar.index", compress_type = zipfile.ZIP_DEFLATED)
zipreference.close()

Загрузка весов впоследствии:

# From the zip saved above.
zipdir = "model.zip"
zipreference = zipfile.ZipFile(zipdir, "r")
zipreference.extractall("C:/tmp/solar-model/")

# Loading model weights.
model.load_weights("C:/tmp/solar-model/solar-model/tmp/solar-model/solar")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...