В 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» после определения класса модели.
!!! Задача !!!:
- Я хочу сохранить не только веса, но и структуру модели, поэтому позже мне не нужно определять класс модели для загрузки веса. (В целях загрузки сохраненного метафайла в c ++, поэтому мне не нужно снова писать все классы преобразователя в c ++.)
!!! То, что я пробовал !!!:
transformer.save ("transformer_model") или transformer.save ("transformer_model.h5", save_format = "h5") -> не работает, выдавая ошибку: "Не работает для подклассных моделей "
transformer.save_weight (" transformer_model ", save_format =" h5 ") -> хотя файлы сохраняются в формате HDF5, кажется, что это не сохранило структуру, но только вес модели.
пытался обучить модель старому способу использования "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)