При попытке сгенерировать текст с использованием GPT-2 пользовательская функция потери обращается к PAD_TOKEN_ID.

Во время обучения пользовательская функция потерь пытается получить доступ к PAD_TOKEN_ID, что приводит к следующей ошибке.50257 — это PAD_TOKEN_ID и размер словаря GPT-2.

      InvalidArgumentError: {{function_node __wrapped__SparseSoftmaxCrossEntropyWithLogits_device_/job:localhost/replica:0/task:0/device:CPU:0}} Received a label value of 50257 which is outside the valid range of [0, 50257).  Label values: 389 1976 1437 264 649 24867 1762 503 5633 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 50257 5025...

Чтобы удалить это, я попробовал замаскировать метки и логиты. Метки перед маскированием имеют форму (1260), а после маскировки - (132). Логиты до маскировки имеют форму (1260, 50257), а после маскировки — (63323820,), что составляет (1260 * 63323820,). Код, который я использую для маскировки логитов, выглядит следующим образом:

      shift_logits = logits[..., :-1, :]
shift_logits = tf.reshape(shift_logits, [-1, shift_logits.shape[-1]])
mask_logits = tf.math.logical_not(tf.math.equal(shift_logits, pad_token_id))
mask_logits = tf.cast(mask_logits, dtype=tf.float32)
shift_logits_masked = tf.boolean_mask(shift_logits,mask_logits)

Таким образом, существует основная проблема, когда осуществляется доступ к значению метки 50257, и при попытке удалить его путем маскировки логитов и меток они терпят неудачу из-за разных форм. Однако это, вероятно, глупый вопрос, поскольку у меня заканчиваются идеи, поэтому было бы очень полезно, если бы кто-нибудь посмотрел.

Я пробовал замаскировать как метки, так и логиты, но, как упоминалось выше, размер меток равен (1260) и логитов (1260,50257), поэтому всякий раз, когда я пытаюсь применить tf.boolean_mask, происходит сбой с ошибкой несоответствия формы. Я ожидаю рассчитать потери, как указано ниже:

      loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction=tf.keras.losses.Reduction.NONE)
loss = loss_fn(shift_labels_masked, shift_logits_masked)

поскольку это генерация текста в моем цикле обучения, я передаю метки как input_ids, как показано ниже:

      for epoch in range(num_epochs):
  for batch in train_ds:
    input_ids = batch["input_ids"]
    with tf.GradientTape() as tape:
      outputs = model(input_ids)
      loss = loss_fn(outputs,labels=batch["input_ids"],pad_token_id=tokenizer.pad_token_id)
      loss = tf.reduce_mean(loss)
    gradients = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))
    #if optimizer.iterations % 100 == 0:
    print("Epoch {} Batch {} Loss {:.4f}".format(epoch + 1, optimizer.iterations.numpy(), loss.numpy()))

0 ответов

Другие вопросы по тегам