Lompat ke konten
dokumentasi.id
Commit ce728f6
v1
Star659

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

9

Forward Pass dan Metrik Evaluasi

Setiap batch yang dievaluasi melewati dua fungsi yang dipilih per dataset: forward_fn menjalankan forward pass dan mengembalikan (loss, list_hyp, list_label), sedangkan metrics_fn menerjemahkan dua list itu menjadi dict dengan kunci ACC, F1, REC, dan PRE. Keduanya disuntikkan oleh append_dataset_args ke args['forward_fn'] dan args['metrics_fn'] utils/args_helper.py:84-91, lalu dipanggil berurutan di dalam loop batch main.py:41-71. predict.predict memakai pola yang sama untuk data test predict.py:39-61.

Siklus satu batch: forward pass lalu metrik

main.evaluate memisahkan elemen terakhir batch_data sebagai batch_seq, lalu menyerahkan sisanya sebagai batch_data[:-1] bersama i2w dan device ke forward_fn. Hipotesis dan label dari seluruh batch diakumulasi ke list_hyp dan list_label, dan metrics_fn dipanggil ulang pada setiap iterasi sehingga progress bar menampilkan metrik kumulatif main.py:41-71.

sequenceDiagram
    autonumber
    participant DL as data_loader
    participant EV as evaluate
    participant FF as forward_fn
    participant MD as model
    participant MF as metrics_fn
    participant CE as conll_evaluation
    DL->>EV: batch_data
    EV->>FF: batch_data[:-1], i2w, device
    FF->>MD: subword_batch, attention_mask, token_type_ids, labels
    MD-->>FF: loss, logits
    FF-->>EV: loss, list_hyp, list_label
    EV->>MF: list_hyp, list_label
    alt token_classification
        MF->>CE: list_hyp, list_label
        CE-->>MF: acc, pre, rec, f1, tm_pre, tm_rec, tm_f1
    else sequence_classification atau multi_label_classification
        MF->>MF: f1_score / recall_score / precision_score average=macro
    end
    MF-->>EV: dict ACC, F1, REC, PRE
%% fig: Siklus satu batch dari data_loader sampai dict metrik
%% desc: forward_fn menghasilkan hipotesis dan label per batch, metrics_fn mengubahnya lewat conll_evaluation pada token classification atau sklearn pada klasifikasi sequence.
Fig. 1: Siklus satu batch dari data_loader sampai dict metrikforward_fn menghasilkan hipotesis dan label per batch, metrics_fn mengubahnya lewat conll_evaluation pada token classification atau sklearn pada klasifikasi sequence.

Tiga kontrak forward pass

Ketiga fungsi memakai tanda tangan yang sama, (model, batch_data, i2w, is_test=False, device='cpu', **kwargs), tetapi berbeda pada bentuk batch_data dan bentuk prediksi yang dikembalikan.

Fungsibatch_data yang diterimaPrediksi yang dibentuk
forward_sequence_classification3 elemen (subword_batch, mask_batch, label_batch) atau 4 elemen dengan token_type_batchsatu label per contoh; torch.topk(logits, 1) lalu i2w[hyp[j].item()] dan i2w[label_batch[j][0].item()] utils/forward_fn.py:8-40
forward_word_classification4 elemen dengan subword_to_word_indices_batch, atau 5 elemen dengan token_type_batchlist tag per kata; torch.topk(logits, k=1, dim=-1).squeeze(dim=-1) lalu i2w per posisi utils/forward_fn.py:43-85
forward_sequence_multi_classification3 elemen, atau 4 elemen dengan token_type_batchsatu label per kelas; logits berupa list tensor (bs, num_label) dan setiap logit di-topk sendiri utils/forward_fn.py:88-126

Ketiganya memindahkan tensor ke GPU hanya ketika device == "cuda", mengubah subword_batch menjadi LongTensor, mask_batch menjadi FloatTensor, dan meneruskan token_type_ids=None bila batch tidak memuat token_type_batch utils/forward_fn.py:8-40. Khusus forward_word_classification, subword_to_word_indices_batch dikirim sebagai argumen posisional kedua tepat setelah subword_batch, sebelum keyword attention_mask dan token_type_ids utils/forward_fn.py:43-85.

⚠️ forward_word_classification berhenti dengan break ketika labels[j] == -100, bukan melewati token itu dengan continue. Token setelah posisi berlabel -100 pada baris yang sama ikut terbuang, sehingga label padding wajib berada di ujung sequence utils/forward_fn.py:43-85.

Evaluasi chunk ala CoNLL

Untuk token_classification, list_hyp dan list_label berisi satu list tag per sequence. conll_evaluation memproses keduanya dengan evaluate, menutup chunk di batas kalimat lewat pemanggilan evaluate_fn('O', 'O', ...) setelah setiap sequence, lalu menghitung hitungan akhir utils/conlleval.py:128-149. Chunk sendiri dibuka dan ditutup oleh start_of_chunk serta end_of_chunk yang membaca prefiks tag B, I, E, S, dan O utils/conlleval.py:128-149.

graph TD
    A["conll_evaluation(hyps_list, labels_list)"] --> B["evaluate: loop token + batas kalimat"]
    B --> C["EvalCounts: correct_chunk, found_correct, found_guessed, correct_tags, token_counter"]
    C --> D["metrics(counts)"]
    D --> E["calculate_metrics: tp, fp, fn, prec, rec, fscore"]
    E --> F["by_type per tipe tag"]
    F --> G["type_macro_pre, type_macro_rec, type_macro_f1"]
    C --> H["acc = correct_tags / token_counter"]
    G --> I["return 7 nilai"]
    H --> I
    I --> J["metrics_fn: ACC, F1=tm_f1, REC=tm_rec, PRE=tm_pre"]
    style A fill:#f59e0b,color:#000
    style B fill:#f59e0b,color:#000
    style C fill:#336791,color:#fff
    style D fill:#8b5cf6,color:#fff
    style E fill:#8b5cf6,color:#fff
    style F fill:#8b5cf6,color:#fff
    style G fill:#2d7d46,color:#fff
    style H fill:#8b5cf6,color:#fff
    style I fill:#8b5cf6,color:#fff
    style J fill:#2d7d46,color:#fff
%% fig: Perhitungan metrik chunk di conlleval
%% desc: Hitungan chunk dan tag dari evaluate diproses calculate_metrics per tipe, lalu tujuh nilai dikembalikan dan dipetakan ke empat kunci metrik.
Fig. 2: Perhitungan metrik chunk di conllevalHitungan chunk dan tag dari evaluate diproses calculate_metrics per tipe, lalu tujuh nilai dikembalikan dan dipetakan ke empat kunci metrik.

calculate_metrics menghitung tp, fp, fn = correct, guessed-correct, total-correct dan mengembalikan prec, rec, fscore dengan nilai 0 bila penyebutnya nol utils/conlleval.py:158-163. Rata-rata per tipe dihitung dengan membagi jumlah tiap tipe dengan len(by_type), bukan rata-rata berbobot utils/conlleval.py:181-203.

Nilai kembalian conll_evaluationSumber perhitunganKunci di metrics_fn
acccorrect_tags / token_counter, tingkat tokenACC
pre, rec, f1overall dari seluruh chunktidak dipakai
tm_prerata-rata prec per tipe tagPRE
tm_recrata-rata rec per tipe tagREC
tm_f1rata-rata fscore per tipe tagF1

Pemetaan tersebut identik pada aspect_extraction_metrics_fn, ner_metrics_fn, pos_tag_metrics_fn, keyword_extraction_metrics_fn, dan qa_factoid_metrics_fn utils/metrics.py:13-20.

⚠️ Pada tugas token_classification, ACC dihitung per token sedangkan F1, REC, dan PRE dihitung per chunk dan dirata-ratakan per tipe tag. Angka F1 karena itu tidak sebanding langsung dengan ACC, dan valid_criterion tetap memakai F1 sebagai acuan pemilihan model utils/conlleval.py:181-203.

Metrik tingkat sequence dan multi-label

emotion_detection_metrics_fn, entailment_metrics_fn, dan document_sentiment_metrics_fn memakai accuracy_score, f1_score, recall_score, dan precision_score dari scikit-learn dengan average='macro' utils/metrics.py:5-11. absa_metrics_fn dan news_categorization_metrics_fn lebih dulu meratakan list bersarang dengan itertools.chain.from_iterable sebelum menghitung empat metrik yang sama utils/metrics.py:74-84 utils/metrics.py:86-96.

Pemetaan forward_fn dan metrics_fn per dataset

--datasettaskforward_fnmetrics_fn
emotion-twittersequence_classificationforward_sequence_classificationemotion_detection_metrics_fn utils/args_helper.py:84-91
absa-airymulti_label_classificationforward_sequence_multi_classificationabsa_metrics_fn utils/args_helper.py:102-109
term-extraction-airytoken_classificationforward_word_classificationaspect_extraction_metrics_fn utils/args_helper.py:120-127
ner-grittoken_classificationforward_word_classificationner_metrics_fn utils/args_helper.py:138-145
pos-idntoken_classificationforward_word_classificationpos_tag_metrics_fn utils/args_helper.py:156-163
entailment-uisequence_classificationforward_sequence_classificationentailment_metrics_fn utils/args_helper.py:174-181
doc-sentiment-prosasequence_classificationforward_sequence_classificationdocument_sentiment_metrics_fn utils/args_helper.py:192-199
keyword-extraction-prosatoken_classificationforward_word_classificationkeyword_extraction_metrics_fn utils/args_helper.py:210-217
qa-factoid-itbtoken_classificationforward_word_classificationqa_factoid_metrics_fn utils/args_helper.py:228-235
ner-prosatoken_classificationforward_word_classificationner_metrics_fn utils/args_helper.py:246-253
pos-prosatoken_classificationforward_word_classificationpos_tag_metrics_fn utils/args_helper.py:264-271
absa-prosamulti_label_classificationforward_sequence_multi_classificationabsa_metrics_fn utils/args_helper.py:282-289

Setiap cabang juga menetapkan args['valid_criterion'] = 'F1' utils/args_helper.py:84-91. news_categorization_metrics_fn didefinisikan dan diimpor, tetapi tidak pernah dipasangkan ke dataset mana pun utils/metrics.py:86-96.

⚠️ Bila --dataset tidak cocok dengan satu pun cabang, append_dataset_args melempar ValueError(f'Unknown dataset name {args["dataset"]}'). Nilai yang terdaftar lebih sempit daripada daftar pada teks bantuan --dataset utils/args_helper.py:282-289, jadi periksa cabang yang benar-benar ada sebelum menjalankan evaluasi.

Dampak ke early stopping

train memanggil evaluate, lalu mengambil val_metrics[valid_criterion] sebagai val_metric; model disimpan sebagai best_model hanya bila nilai itu melampaui best_val_metric sebelumnya main.py:116-121. Karena valid_criterion selalu 'F1' utils/args_helper.py:84-91, kualitas model pada tugas chunk sepenuhnya ditentukan oleh tm_f1, bukan acc maupun overall.fscore.