微调T5不收敛

问题描述 投票:0回答:1

我是 Transformer 和 NLP 领域的新手,在针对我的特定用例微调 T5 时遇到问题。

我想要实现的是,模型接收输入文本,并输出文本中相关信息的 JSON(作为字符串)。

模型可以响应 3 种格式,以下是一些示例: 输入:嘿,你能给约翰一百美元吗? 预期输出:'{"action": "T", "data": {"name": "John", "amount": 100, "currency": "USD"}}'

输入:我想将本杰明·富兰克林添加到我的联系人中。他在花旗银行有一个账户,账户号码为 412389124。 预期输出:'{"action": "A", "data": {"name": "Benjamin Franklin", "account_no": 412389124, "entity": "Citibank", "id_num": null}'

输入:嘿,今晚天气怎么样? 预期输出:'{“accion”:“N”,“datos”:{}}'

我构建了一个 Python 脚本来尽可能随机地生成输入和标签。使用该 python 脚本,我生成了 20000 个数据点(我可以生成更少或更多的数据点)。

使用 T5 作为我的基础模型,我使用 pytorch 的训练器对其进行了训练。

下面是我的代码:

model_name_huggingface = "google/t5-base"

tokenizer = T5Tokenizer.from_pretrained(model_name_huggingface)
model = T5ForConditionalGeneration.from_pretrained(model_name_huggingface)

然后,在我标记我的数据集之后。

batch_size = 16

training_args = Seq2SeqTrainingArguments(
    output_dir="models/chimi-mt5-base",
    evaluation_strategy="steps",
    eval_steps=100,
    logging_strategy="steps",
    logging_steps=100,
    save_strategy="steps",
    save_steps=200,
    # learning_rate=1e-4,
    optim="adafactor",
    learning_rate=5e-4,
    per_device_train_batch_size=batch_size,
    per_device_eval_batch_size=batch_size,
    predict_with_generate=True,
    weight_decay=0.05,
    save_total_limit=3,
    num_train_epochs=2,
    metric_for_best_model="exact_match",
    # greater_is_better=False,
    load_best_model_at_end=True
)
data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=base_model)
cer = evaluate.load("cer", module_type="metric")
exact_match = evaluate.load("exact_match", module_type="metric")
import numpy as np

def compute_metrics(eval_pred):
    predictions, labels = eval_pred
    decoded_preds = tokenizer.batch_decode(predictions, skip_special_tokens=True)

    # Replace -100 in the labels as we can't decode them.
    labels = np.where(labels != -100, labels, tokenizer.pad_token_id)
    decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True)

    result = {}

    # Compute CER
    result["cer"] = cer.compute(predictions=decoded_preds, references=decoded_labels)

    # Compute Exact Match
    exact_match_res = exact_match.compute(predictions=decoded_preds, references=decoded_labels, ignore_case=True)
    result["exact_match"] = exact_match_res["exact_match"]

    return {k: round(v, 4) for k, v in result.items()}
trainer = Seq2SeqTrainer(
    model=base_model,
    args=training_args,
    train_dataset=tokenized_chimi_dataset["train"],
    eval_dataset=tokenized_chimi_dataset["validation"],
    data_collator=data_collator,
    tokenizer=tokenizer,
    compute_metrics=compute_metrics
)
result = trainer.train()

这是我当前用来微调 T5 的代码。

训练损失下降至 0.054,并且从未改善。 验证损失下降了 0.034,并且从未改善。 CER 指标下降至 0.4875,此后再也没有改善。但是,只是想让您知道,在前 100 步之后,它的 CER 已经为 0.583。 精确匹配指标上升到 0.3089,这在第 600 步之后就已经发生了。

通过测试,我发现它以正确的 JSON 格式响应,并且操作正常响应正确。但是,JSON 中的数据通常并不正确。

我可以做些什么来改善这一点? 我在这个问题上纠结了很长时间,不知道该如何继续。如有任何帮助,我们将不胜感激。

提前致谢!

我尝试平衡我的数据集并调整超参数,但它仍然没有导致任何相关的性能提升。

nlp huggingface-transformers
1个回答
0
投票

已经快一年了 - 你解决这个问题了吗?

我发现您的方法可能存在两个问题。

(1) 尝试对随机性建模(?) 你说:

我构建了一个 Python 脚本来尽可能随机地生成输入和标签。

如果我理解正确的话 - 您正在创建完全随机的合成数据。 (这是正确的吗?)那不行。

(2) 尝试输出有效的 JSON 你说

预期输出:

'{"action": "T", "data": {"name": "John", "amount": 100, "currency": "USD"}}'

据我所知,花括号 {} 不在 t5 分词器词汇中。 请参阅:https://github.com/huggingface/transformers/issues/21836

© www.soinside.com 2019 - 2024. All rights reserved.