Моя модель трансформатора не работает должным образом. Потеря обучения / валидации увеличивается - PullRequest
0 голосов
/ 26 апреля 2020

Я построил свою собственную модель Transformer в pytorch на основе «Внимание - все, что вам нужно» для выполнения задачи машинного перевода. Но, к сожалению, это не работает хорошо, потому что потеря поезда не уменьшается должным образом, а потеря проверки даже увеличивается. Кроме того, балл BLEU, который я использовал для оценки производительности модели, остается равным 0, что я не вижу причины. Я публикую эту топику c для получения совета по программированию трансформатора. Я не знаю, какая часть моего кода неверна, поэтому я думаю, что должен знать общую идею Transformer.

По моему мнению, сама модель не является проблемой, так как я ссылался на учебник блога по реализации Трансформаторы. Поэтому я думаю, что проблема заключается в предварительной обработке данных или процедуре обучения. Я подготовил набор данных на английском / французском языке, токенизировал его с помощью SentencePiece и предварительно обработал данные с помощью следующих форм.

ex) (En) tok1 tok2 tok3 tok4 => (Fr) tokA tokB tok C tokD
src_input: tok1 tok2 tok4 pad pad
tar_input: sos tokA tokB tok C tokD pad
tar_output: tokA tokB tok C tokD eos pad

Если мы говорим, что максимальная длина равна 6, тогда мы должны добавить отступы, как указано выше. И я хочу знать, что это правильный метод. Я поставил src_input в кодировщик и tar_input в декодер в качестве целевого ввода. Затем, после получения окончательного результата в форме (batch_size, max_len, target_vocab_size), я поместил этот слой LogSoftmax и рассчитал NllLoss с помощью tar_output.

Это коды предварительной обработки данных.

def add_padding(tokenized_text):
    if len(tokenized_text) < seq_len:
        left = seq_len - len(tokenized_text)
        padding = [pad_id] * left
        tokenized_text += padding

    return tokenized_text


def process_src(text_list):
    print("Tokenizing & Padding src data...")
    tokenized_list = []
    for text in tqdm(text_list):
        tokenized = src_sp.EncodeAsIds(text.strip())
        tokenized_list.append(add_padding(tokenized))

    print(f"The shape of src data: {np.shape(tokenized_list)}")
    return tokenized_list


def process_tar(text_list):
    print("Tokenizing & Padding tar data...")
    input_list = []
    output_list = []
    for text in tqdm(text_list):
        tokenized = tar_sp.EncodeAsIds(text.strip())
        input_tokenized = [sos_id] + tokenized
        output_tokenized = tokenized + [eos_id]
        input_list.append(add_padding(input_tokenized))
        output_list.append(add_padding(output_tokenized))

    print(f"The shape of tar(input) data: {np.shape(input_list)}")
    print(f"The shape of tar(output) data: {np.shape(output_list)}")
    return input_list, output_list

И это для обучения.

output = self.model(src_input, tar_input, encoder_mask, masked_attn_mask, attn_mask) # (B, L, vocab_size)

self.optim.zero_grad()
loss = self.criterion(output.view(-1, sp_vocab_size), tar_output.view(batch_size * seq_len))

loss.backward()
self.optim.step()

Пожалуйста, укажите, если я ошибаюсь.

Большое спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...