Evaluate 文件

使用評估器

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

使用評估器

Evaluator 類允許對模型、資料集和指標三元組進行評估。這些模型被封裝在一個管道中,負責處理所有預處理和後處理。開箱即用的 Evaluator 支援已支援任務的 transformers 管道,但也可以傳遞自定義管道,如 使用 evaluator 與自定義管道 部分所示。

目前支援的任務有:

要在單次呼叫中執行一個包含多個任務的 Evaluator,請使用 EvaluationSuite,它對一組 SubTask 進行評估。

每個任務對資料集格式和管道輸出都有自己的要求,請確保為您的自定義用例檢查這些要求。讓我們看一些例子,瞭解如何使用評估器同時評估單個或多個模型、資料集和指標。

文字分類

文字分類評估器可用於評估文字模型在分類資料集(如 IMDb)上的表現。除了模型、資料和指標輸入外,它還接受以下可選輸入:

  • input_column="text":此引數用於指定包含管道資料的列。
  • label_column="label":此引數用於指定包含用於評估的標籤的列。
  • label_mapping=None:標籤對映將管道輸出中的標籤與評估所需的標籤對齊。例如,label_column 中的標籤可能是整數(0/1),而管道可能產生標籤名稱,如 "positive"/"negative"。透過這個字典,管道輸出被對映到標籤。

預設情況下,計算 "accuracy" 指標。

評估 Hub 上的模型

有多種方法可以將模型傳遞給評估器:您可以傳遞 Hub 上模型的名稱,可以載入一個 transformers 模型並將其傳遞給評估器,或者可以傳遞一個已初始化的 transformers.Pipeline。此外,您還可以傳遞任何行為類似於該任務的 pipeline 呼叫的可呼叫函式,無論使用何種框架。

因此,以下任何一種方式都可行:

from datasets import load_dataset
from evaluate import evaluator
from transformers import AutoModelForSequenceClassification, pipeline

data = load_dataset("imdb", split="test").shuffle(seed=42).select(range(1000))
task_evaluator = evaluator("text-classification")

# 1. Pass a model name or path
eval_results = task_evaluator.compute(
    model_or_pipeline="lvwerra/distilbert-imdb",
    data=data,
    label_mapping={"NEGATIVE": 0, "POSITIVE": 1}
)

# 2. Pass an instantiated model
model = AutoModelForSequenceClassification.from_pretrained("lvwerra/distilbert-imdb")

eval_results = task_evaluator.compute(
    model_or_pipeline=model,
    data=data,
    label_mapping={"NEGATIVE": 0, "POSITIVE": 1}
)

# 3. Pass an instantiated pipeline
pipe = pipeline("text-classification", model="lvwerra/distilbert-imdb")

eval_results = task_evaluator.compute(
    model_or_pipeline=pipe,
    data=data,
    label_mapping={"NEGATIVE": 0, "POSITIVE": 1}
)
print(eval_results)

如果不指定裝置,模型推理的預設裝置將是機器上的第一個 GPU(如果有),否則為 CPU。如果您想使用特定裝置,可以向 compute 傳遞 device,其中 -1 將使用 GPU,而正整數(從 0 開始)將使用相應的 CUDA 裝置。

結果將如下所示:

{
    'accuracy': 0.918,
    'latency_in_seconds': 0.013,
    'samples_per_second': 78.887,
    'total_time_in_seconds': 12.676
}

請注意,評估結果不僅包括所請求的指標,還包括透過管道獲得預測所需的時間資訊。

時間效能可以為模型推理速度提供有用的指示,但應謹慎對待:它們包括管道中進行的所有處理。這可能包括分詞、後處理等,這些過程可能因模型而異。此外,它很大程度上取決於您執行評估的硬體,您或許可以透過最佳化批次大小等來提高效能。

評估多個指標

透過 combine() 函式,可以將多個指標捆綁到一個行為類似於單個指標的物件中。我們可以利用這一點同時使用評估器評估多個指標。

import evaluate

eval_results = task_evaluator.compute(
    model_or_pipeline="lvwerra/distilbert-imdb",
    data=data,
    metric=evaluate.combine(["accuracy", "recall", "precision", "f1"]),
    label_mapping={"NEGATIVE": 0, "POSITIVE": 1}
)
print(eval_results)

結果將如下所示:

{
    'accuracy': 0.918,
    'f1': 0.916,
    'precision': 0.9147,
    'recall': 0.9187,
    'latency_in_seconds': 0.013,
    'samples_per_second': 78.887,
    'total_time_in_seconds': 12.676
}

接下來,讓我們看看分詞分類。

分詞分類

使用分詞分類評估器,可以評估用於 NER 或 POS 標註等任務的模型。它具有以下特定引數:

  • input_column="text":此引數用於指定包含管道資料的列。
  • label_column="label":此引數用於指定包含用於評估的標籤的列。
  • label_mapping=None:標籤對映將管道輸出中的標籤與評估所需的標籤對齊。例如,label_column 中的標籤可能是整數(0/1),而管道可能產生標籤名稱,如 "positive"/"negative"。透過這個字典,管道輸出被對映到標籤。
  • join_by=" ":雖然大多數資料集已經分詞,但管道期望輸入為字串。因此,在傳遞給管道之前需要將分詞連線起來。預設情況下,它們用空格連線。

讓我們看看如何使用評估器對多個模型進行基準測試。

對多個模型進行基準測試

這是一個示例,展示瞭如何藉助 evaluator 在幾行程式碼內比較多個模型,它抽象了預處理、推理、後處理和指標計算等過程。

import pandas as pd
from datasets import load_dataset
from evaluate import evaluator
from transformers import pipeline

models = [
    "xlm-roberta-large-finetuned-conll03-english",
    "dbmdz/bert-large-cased-finetuned-conll03-english",
    "elastic/distilbert-base-uncased-finetuned-conll03-english",
    "dbmdz/electra-large-discriminator-finetuned-conll03-english",
    "gunghio/distilbert-base-multilingual-cased-finetuned-conll2003-ner",
    "philschmid/distilroberta-base-ner-conll2003",
    "Jorgeutd/albert-base-v2-finetuned-ner",
]

data = load_dataset("conll2003", split="validation").shuffle().select(range(1000))
task_evaluator = evaluator("token-classification")

results = []
for model in models:
    results.append(
        task_evaluator.compute(
            model_or_pipeline=model, data=data, metric="seqeval"
            )
        )

df = pd.DataFrame(results, index=models)
df[["overall_f1", "overall_accuracy", "total_time_in_seconds", "samples_per_second", "latency_in_seconds"]]

結果是一個如下所示的表格:

模型 overall_f1 overall_accuracy total_time_in_seconds samples_per_second latency_in_seconds
Jorgeutd/albert-base-v2-finetuned-ner 0.941 0.989 4.515 221.468 0.005
dbmdz/bert-large-cased-finetuned-conll03-english 0.962 0.881 11.648 85.850 0.012
dbmdz/electra-large-discriminator-finetuned-conll03-english 0.965 0.881 11.456 87.292 0.011
elastic/distilbert-base-uncased-finetuned-conll03-english 0.940 0.989 2.318 431.378 0.002
gunghio/distilbert-base-multilingual-cased-finetuned-conll2003-ner 0.947 0.991 2.376 420.873 0.002
philschmid/distilroberta-base-ner-conll2003 0.961 0.994 2.436 410.579 0.002
xlm-roberta-large-finetuned-conll03-english 0.969 0.882 11.996 83.359 0.012

視覺化結果

您可以將上述 results 列表輸入到 plot_radar() 函式中,以視覺化其效能的不同方面,並根據與您的用例相關的指標選擇最適合的模型。

import evaluate
from evaluate.visualization import radar_plot

>>> plot = radar_plot(data=results, model_names=models, invert_range=["latency_in_seconds"])
>>> plot.show()

對於值越小越好的指標(例如秒級延遲),請不要忘記指定 invert_range

如果您想將圖表儲存在本地,可以使用 plot.savefig() 函式,並帶有 bbox_inches='tight' 選項,以確保影像的任何部分都不會被裁剪掉。

問答

使用問答評估器,可以評估 QA 模型,而無需擔心這些模型所需的複雜預處理和後處理。它具有以下特定引數:

  • question_column="question":資料集中包含問題的列的名稱。
  • context_column="context":包含上下文的列的名稱。
  • id_column="id":包含問答對標識欄位的列的名稱。
  • label_column="answers":包含答案的列的名稱。
  • squad_v2_format=None:資料集是否遵循 squad_v2 資料集格式,其中問題可能在上下文中沒有答案。如果未提供此引數,將自動推斷格式。

讓我們看看如何評估 QA 模型並同時計算置信區間。

置信區間

每個評估器都提供了使用自助法計算置信區間的選項。只需傳遞 strategy="bootstrap" 並使用 n_resamples 設定重取樣次數即可。

from datasets import load_dataset
from evaluate import evaluator

task_evaluator = evaluator("question-answering")

data = load_dataset("squad", split="validation[:1000]")
eval_results = task_evaluator.compute(
    model_or_pipeline="distilbert-base-uncased-distilled-squad",
    data=data,
    metric="squad",
    strategy="bootstrap",
    n_resamples=30
)

結果包括置信區間和誤差估計,如下所示:

{
    'exact_match':
    {
        'confidence_interval': (79.67, 84.54),
        'score': 82.30,
        'standard_error': 1.28
    },
    'f1':
    {
        'confidence_interval': (85.30, 88.88),
        'score': 87.23,
        'standard_error': 0.97
    },
    'latency_in_seconds': 0.0085,
    'samples_per_second': 117.31,
    'total_time_in_seconds': 8.52
 }

影像分類

透過影像分類評估器,我們可以評估任何影像分類器。它使用與文字分類器相同的關鍵字引數:

  • input_column="image":包含 PIL ImageFile 格式影像的列的名稱。
  • label_column="label":包含標籤的列的名稱。
  • label_mapping=None:我們希望將管道中模型定義的類標籤對映為與 label_column 中定義的值一致的值。

讓我們看看如何在大型資料集上評估影像分類模型。

處理大型資料集

評估器可以在大型資料集上使用!下面是一個示例,展示瞭如何在 ImageNet-1k 資料集上進行影像分類。請注意,此示例需要下載約 150 GB 的資料。

data = load_dataset("imagenet-1k", split="validation", token=True)

pipe = pipeline(
    task="image-classification",
    model="facebook/deit-small-distilled-patch16-224"
)

task_evaluator = evaluator("image-classification")
eval_results = task_evaluator.compute(
    model_or_pipeline=pipe,
    data=data,
    metric="accuracy",
    label_mapping=pipe.model.config.label2id
)

由於我們使用 datasets 來儲存資料,我們利用了一種稱為記憶體對映的技術。這意味著資料集永遠不會完全載入到記憶體中,從而節省了大量 RAM。執行上述程式碼僅使用約 1.5 GB 的 RAM,而驗證集的大小超過 30 GB。

< > 在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.