Lompat ke konten
dokumentasi.id
Commit ce728f6
v1
Star659

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

6

12 Task Downstream dan Jenis Klasifikasi

append_dataset_args adalah satu-satunya tempat di repository ini yang menerjemahkan nilai --dataset menjadi jenis task. Setiap nama dataset yang dikenal masuk ke satu cabang if/elif, lalu cabang tersebut mengisi args['task'], args['num_labels'], args['dataset_class'], args['dataloader_class'], args['forward_fn'], dan args['metrics_fn'] (utils/args_helper.py:83-84). Fungsi itu dipanggil oleh main.py sebelum directory eksperimen dibuat dan sebelum model dimuat, dan dipanggil juga oleh predict.py (main.py:142, predict.py:69). Akibatnya dua belas task downstream berbagi satu jalur kode yang sama; yang berbeda hanyalah kelas dataset, jumlah label, dan fungsi forward yang dipilih cabang tersebut.

Ada tepat tiga nilai args['task'] yang dipakai cabang-cabang itu: sequence_classification, token_classification, dan multi_label_classification. Nilai itu nanti dipakai get_model_class untuk memilih kelas kepala klasifikasi (utils/functions.py:172-177); rincian kelasnya ada di Modul Kepala Klasifikasi.

graph TD
  CLI["--dataset dari argparse"] --> DISP{"append_dataset_args"}
  DISP -->|"sequence_classification"| SEQ["3 dataset · satu label per dokumen"]
  DISP -->|"token_classification"| TOK["7 dataset · satu label per token"]
  DISP -->|"multi_label_classification"| ML["2 dataset · satu label per aspek"]
  SEQ --> EMO["emotion-twitter<br/>NUM_LABELS = 5"]
  SEQ --> ENT["entailment-ui<br/>NUM_LABELS = 2"]
  SEQ --> DOC["doc-sentiment-prosa<br/>NUM_LABELS = 3"]
  TOK --> TERM["term-extraction-airy<br/>NUM_LABELS = 5"]
  TOK --> NERG["ner-grit<br/>NUM_LABELS = 7"]
  TOK --> POSIDN["pos-idn<br/>NUM_LABELS = 41"]
  TOK --> KW["keyword-extraction-prosa<br/>NUM_LABELS = 3"]
  TOK --> QA["qa-factoid-itb<br/>NUM_LABELS = 3"]
  TOK --> NERP["ner-prosa<br/>NUM_LABELS = 11"]
  TOK --> POSP["pos-prosa<br/>NUM_LABELS = 26"]
  ML --> ABSAA["absa-airy<br/>NUM_LABELS = [4, 4, 4, 4, 4, 4, 4, 4, 4, 4]"]
  ML --> ABSAP["absa-prosa<br/>NUM_LABELS = [3, 3, 3, 3, 3, 3]"]
  style DISP fill:#f59e0b,color:#000
  style SEQ fill:#2d7d46,color:#fff
  style TOK fill:#8b5cf6,color:#fff
  style ML fill:#f59e0b,color:#000
%% fig: Pemetaan --dataset ke tiga jenis task
%% desc: append_dataset_args memecah dua belas nama dataset ke tiga nilai task, dan setiap cabang menetapkan kuantitas labelnya sendiri.
Fig. 1: Pemetaan --dataset ke tiga jenis taskappend_dataset_args memecah dua belas nama dataset ke tiga nilai task, dan setiap cabang menetapkan kuantitas labelnya sendiri.

Tiga jenis task dan bentuk labelnya

Ketiga jenis task berbeda pada bentuk label yang dikirim ke fungsi forward, bukan pada model dasarnya. EmotionDetectionDataLoader menyusun label_batch berbentuk (batch_size, 1), satu skalar per dokumen (utils/data_utils.py:427). Loader token-level menyusun seq_label_batch berbentuk (batch_size, max_tgt_len) dan mengisi sisa posisi dengan -100 agar diabaikan saat menghitung loss (utils/data_utils.py:82). Loader ABSA menyusun label_batch berbentuk (batch_size, self.num_aspects), satu vektor label per aspek (utils/data_utils.py:815).

graph LR
  SEQ2["sequence_classification"] --> S1["label_batch (batch_size, 1)"]
  TOK2["token_classification"] --> T1["seq_label_batch (batch_size, max_tgt_len)"]
  T1 --> T2["posisi kosong diisi -100"]
  ML2["multi_label_classification"] --> M1["label_batch (batch_size, num_aspects)"]
  M1 --> M2["num_aspects diambil dari dataset.NUM_ASPECTS"]
  style SEQ2 fill:#2d7d46,color:#fff
  style TOK2 fill:#8b5cf6,color:#fff
  style ML2 fill:#f59e0b,color:#000
  style T2 fill:#dc2626,color:#fff
%% fig: Bentuk label per jenis task
%% desc: Jenis task menentukan bentuk tensor label yang masuk ke forward function, dari skalar per dokumen sampai vektor per aspek.
Fig. 2: Bentuk label per jenis taskJenis task menentukan bentuk tensor label yang masuk ke forward function, dari skalar per dokumen sampai vektor per aspek.

Task sequence_classification memakai forward_sequence_classification dan satu label per dokumen. Task token_classification memakai forward_word_classification dan label per kata, dengan subword_to_word_indices memetakan subword kembali ke kata. Task multi_label_classification memakai forward_sequence_multi_classification, yang menerima logits berupa list tensor dan mengembalikan satu prediksi untuk setiap kelas; komentar pada berkas itu menyebut list<tensor(bs, num_label)> (utils/forward_fn.py:108-117). Penjelasan alur forward selengkapnya ada di Forward Pass dan Metrik Evaluasi.

Setiap cabang juga menetapkan args['valid_criterion'] = 'F1', sehingga pemilihan model terbaik selalu memakai F1 tanpa memandang jenis task (utils/args_helper.py:91). Yang berbeda per dataset adalah metrics_fn: ner_metrics_fn dipakai dua dataset NER, pos_tag_metrics_fn dipakai dua dataset POS, dan absa_metrics_fn dipakai dua dataset ABSA.

Dua belas dataset dan kelas pendukungnya

--datasettaskdataset_classNUM_LABELSforward_fnmetrics_fnword_tokenizer_classRujukan
emotion-twittersequence_classificationEmotionDetectionDataset5forward_sequence_classificationemotion_detection_metrics_fnTweetTokenizerutils/args_helper.py:84-101
absa-airymulti_label_classificationAspectBasedSentimentAnalysisAiryDataset[4, 4, 4, 4, 4, 4, 4, 4, 4, 4]forward_sequence_multi_classificationabsa_metrics_fnTweetTokenizerutils/args_helper.py:102-119
term-extraction-airytoken_classificationAspectExtractionDataset5forward_word_classificationaspect_extraction_metrics_fnTweetTokenizerutils/args_helper.py:120-137
ner-grittoken_classificationNerGritDataset7forward_word_classificationner_metrics_fnTweetTokenizerutils/args_helper.py:138-155
pos-idntoken_classificationPosTagIdnDataset41forward_word_classificationpos_tag_metrics_fnTweetTokenizerutils/args_helper.py:156-173
entailment-uisequence_classificationEntailmentDataset2forward_sequence_classificationentailment_metrics_fnTweetTokenizerutils/args_helper.py:174-191
doc-sentiment-prosasequence_classificationDocumentSentimentDataset3forward_sequence_classificationdocument_sentiment_metrics_fnTweetTokenizerutils/args_helper.py:192-209
keyword-extraction-prosatoken_classificationKeywordExtractionDataset3forward_word_classificationkeyword_extraction_metrics_fnWordSplitTokenizerutils/args_helper.py:210-227
qa-factoid-itbtoken_classificationQAFactoidDataset3forward_word_classificationqa_factoid_metrics_fnTweetTokenizerutils/args_helper.py:228-245
ner-prosatoken_classificationNerProsaDataset11forward_word_classificationner_metrics_fnTweetTokenizerutils/args_helper.py:246-263
pos-prosatoken_classificationPosTagProsaDataset26forward_word_classificationpos_tag_metrics_fnTweetTokenizerutils/args_helper.py:264-281
absa-prosamulti_label_classificationAspectBasedSentimentAnalysisProsaDataset[3, 3, 3, 3, 3, 3]forward_sequence_multi_classificationabsa_metrics_fnTweetTokenizerutils/args_helper.py:282-299

Tujuh dari dua belas task adalah token_classification, tiga sequence_classification, dan dua multi_label_classification. Sebagian kelas dipakai bersama antar dataset: ner-grit dan ner-prosa sama-sama memakai NerDataLoader, pos-idn dan pos-prosa sama-sama memakai PosTagDataLoader, sedangkan absa-airy dan absa-prosa sama-sama memakai AspectBasedSentimentAnalysisDataLoader (utils/args_helper.py:138-155, utils/args_helper.py:246-263, utils/args_helper.py:282-299). Satu-satunya task yang memakai WordSplitTokenizer adalah keyword-extraction-prosa; sisanya memakai TweetTokenizer (utils/args_helper.py:227, utils/args_helper.py:101). Struktur path train_set_path dan kawan-kawan yang diisi cabang yang sama dibahas di Struktur Berkas Dataset dan Submission, sedangkan pembentukan batch-nya di Data Utils dan Dataloader.

Label set per jenis task

Label set didefinisikan sebagai konstanta kelas pada masing-masing dataset_class, dan main.py memakai args['dataset_class'].LABEL2INDEX serta INDEX2LABEL sebagai w2i dan i2w saat mendekode prediksi (main.py:156).

sequence_classification

DatasetKunci LABEL2INDEXJumlahRujukan
emotion-twittersadness, anger, love, fear, happy5utils/data_utils.py:389-393
entailment-uiNotEntail, Entail_or_Paraphrase2utils/data_utils.py:443-447
doc-sentiment-prosapositive, neutral, negative3utils/data_utils.py:504-508

token_classification

DatasetKunci LABEL2INDEXJumlahRujukan
term-extraction-airyI-SENTIMENT, O, I-ASPECT, B-SENTIMENT, B-ASPECT5utils/data_utils.py:12-16
ner-gritI-PERSON, B-ORGANISATION, I-ORGANISATION, B-PLACE, I-PLACE, O, B-PERSON7utils/data_utils.py:101-105
ner-prosaI-PPL, B-EVT, B-PLC, I-IND, B-IND, B-FNB, I-EVT, B-PPL, I-PLC, O, I-FNB11utils/data_utils.py:156-160
pos-idntag B-/I- dari B-PR, B-CD, I-PR, sampai B-X41utils/data_utils.py:245-249
pos-prosatag B- dari B-PPO, B-KUA, B-ADV, sampai B-VBE26utils/data_utils.py:300-304
keyword-extraction-prosaO, B, I3utils/data_utils.py:559-563
qa-factoid-itbO, B, I3utils/data_utils.py:649-653

multi_label_classification

DatasetKunci LABEL2INDEXAspekRujukan
absa-airyneg, neut, pos, neg_pos10 aspek: ac, air_panas, bau, general, kebersihan, linen, service, sunrise_meal, tv, wifiutils/data_utils.py:744-750
absa-prosanegative, neutral, positive6 aspek: fuel, machine, others, part, price, serviceutils/data_utils.py:772-778

⚠️ NUM_LABELS tidak selalu berupa bilangan bulat. Pada dua dataset ABSA nilainya berupa list, satu entri per aspek. get_model_class menanganinya dengan config.num_labels = max(args['num_labels']) dan menyimpan daftar aslinya di config.num_labels_list (utils/functions.py:262-266). Memperlakukan args['num_labels'] sebagai int akan salah untuk absa-airy dan absa-prosa.

Di luar dua belas: news-category-prosa

--dataset memiliki nilai default emotion-twitter, dan teks bantuannya menyebut daftar nama dataset yang tidak sepenuhnya cocok dengan cabang yang benar-benar ada: teks itu memuat news-category-prosa tetapi tidak memuat absa-prosa (utils/args_helper.py:37). NewsCategorizationDataset memang diimpor dan didefinisikan dengan NUM_LABELS = 16 (utils/args_helper.py:8, utils/data_utils.py:832-836), namun tidak ada cabang elif untuk nama dataset itu.

⚠️ Menjalankan --dataset news-category-prosa akan berhenti di raise ValueError(f'Unknown dataset name ...') karena rantai if/elif selesai tanpa cabang yang cocok (utils/args_helper.py:300-301). run_all_tasks.sh juga hanya menjalankan dua belas nama yang punya cabang (run_all_tasks.sh:1-12).