Tensorflow 2.0: как я могу сохранить структуру для модели подклассного трансформатора? - PullRequest
0 голосов
/ 19 февраля 2020

В python 3.6 я построил модель трансформатора для проблемы НЛП, как показано ниже. Это тот же код из (Справочник -> https://www.tensorflow.org/tutorials/text/transformer)

class Transformer(tf.keras.Model):
    def __init__(self, num_layers, d_model, num_heads, dff, input_vocab_size,
             target_vocab_size, rate=0.1):
        super(Transformer, self).__init__()

        self.encoder = Encoder(num_layers, d_model, num_heads, dff,
                           input_vocab_size, rate)

        self.decoder = Decoder(num_layers, d_model, num_heads, dff,
                           target_vocab_size, rate)

        self.final_layer = tf.keras.layers.Dense(target_vocab_size)

    def call(self, inp, tar, training, enc_padding_mask, look_ahead_mask, dec_padding_mask):
        enc_output = self.encoder(inp, training, enc_padding_mask)  # (batch_size, inp_seq_len, d_model)

        # dec_output.shape == (batch_size, tar_seq_len, d_model)
        dec_output, attention_weights = self.decoder(
            tar, enc_output, training, look_ahead_mask, dec_padding_mask)

        final_output = self.final_layer(dec_output)  # (batch_size, tar_seq_len, target_vocab_size)

        return final_output, attention_weights   

if __name__=='__main__':
    transformer = Transformer(num_layers, d_model, num_heads, dff,
                          input_vocab_size, target_vocab_size, dropout_rate)
    def train_step(inp, tar):
        tar_inp = tar[:, :-1]
        tar_real = tar[:, 1:]
        enc_padding_mask, combined_mask, dec_padding_mask = create_masks(inp, tar_inp)
        with tf.GradientTape() as tape:
            predictions, _ = transformer(inp, tar_inp,
                                     True,
                                     enc_padding_mask,
                                     combined_mask,
                                     dec_padding_mask)
            loss = loss_function(tar_real, predictions)

        gradients = tape.gradient(loss, transformer.trainable_variables)
        optimizer.apply_gradients(zip(gradients, transformer.trainable_variables))

        train_loss(loss)
        train_accuracy(tar_real, predictions)

    #Start Training!!
    for inp, tar in get_batches(encode_input, decode_input, BATCH_SIZE):
        train_step(processed_inp, processed_tar)

После обучения я мог использовать функцию «save_weights» для сохранения весов модели, а затем загрузить веса с использованием «load_weights» после определения класса модели.

!!! Задача !!!:

  1. Я хочу сохранить не только веса, но и структуру модели, поэтому позже мне не нужно определять класс модели для загрузки веса. (В целях загрузки сохраненного метафайла в c ++, поэтому мне не нужно снова писать все классы преобразователя в c ++.)

!!! То, что я пробовал !!!:

  1. transformer.save ("transformer_model") или transformer.save ("transformer_model.h5", save_format = "h5") -> не работает, выдавая ошибку: "Не работает для подклассных моделей "

  2. transformer.save_weight (" transformer_model ", save_format =" h5 ") -> хотя файлы сохраняются в формате HDF5, кажется, что это не сохранило структуру, но только вес модели.

  3. пытался обучить модель старому способу использования "session ()" (метод определения графа), а не вышеописанного метода выполнения. -> Возможно, возможно, но чувствовал, что неуместно использовать метод версии tenorflow 1.0 для модели версии 2.0.

Это единственный способ сделать это возможным, записав всю модель трансформатора в последовательном модель? Я также не уверен, возможно ли сделать модель преобразователя последовательной моделью, потому что код содержит такие вещи, как

def get_angles(pos, i, d_model):
angle_rates = 1 / np.power(10000, (2 * (i // 2)) / float(d_model))
return pos * angle_rates

, поэтому я думаю, что его нельзя написать простым способом, как показано ниже, но есть несколько дополнительных функций. для расчета, как описано выше, функции get_angles.

class MyModel(Model):
def __init__(self):
   super(MyModel, self).__init__()
   self.conv1 = Conv2D(32, 3, activation='relu')
   self.flatten = Flatten()
   self.d1 = Dense(128, activation='relu')
   self.d2 = Dense(10)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...