어노테이션 데이터로 모델 학습하기
여러 어노테이터의 레이블을 학습 목표로 통합하고, 라운드 사이에 홀드아웃 test 분할을 고정하고, 각 모델이 본 것을 기록하고, 첫 실행의 규모를 정합니다.
어노테이션 데이터로 모델을 학습시키려면 각 항목의 레이블을 하나의 목표 또는 어노테이터들의 투표 분포로 통합하고, 라운드 사이에 고정되는 규칙으로 항목을 train, 검증, test 분할에 배정하고, 검증 분할이 체크포인트를 골랐다면 test 점수를 보고합니다. Potato의 모델 학습은 연구 자체의 어노테이션에서 각 단계를 실행하고 모든 실행이 어떤 항목으로 학습했는지 기록합니다.
v2.14.0의 새 기능
어노테이션 데이터는 트레이너가 읽는 형태로 도착하는 일이 드뭅니다. 겹치는 어노테이션이 있는 연구는 항목당 레이블이 여럿이고, 그 레이블은 자주 엇갈립니다. 진행 중인 연구는 매일 레이블이 늘고, 재학습 라운드마다 이전 라운드보다 많은 항목을 봅니다. 트레이너에게는 항목당 하나의 목표와 점수를 매길 고정된 항목 집합이 필요하며, 아래의 결정이 둘을 만들어 냅니다. 아래 각 절은 그 결정을 내리는 Potato 설정을 알려 줍니다. Training 페이지 자체는 모델 학습 개요와 첫 모델을 학습시키는 튜토리얼을 참고하십시오. 자기 코드에서 학습하려면 머신러닝을 위한 어노테이션 내보내기가 내보내기 형식을 다루며, 내보낸 파일에도 같은 결정이 적용됩니다.
여러 어노테이터를 하나의 레이블로 통합하기
통합은 한 항목에 여러 어노테이터가 단 레이블을 모델이 학습하는 하나의 레이블로 바꿉니다. 가장 단순한 방법은 다수결입니다. 다수결은 모든 어노테이터의 답을 한 번씩 세어 가장 흔한 답을 유지합니다. Dawid and Skene (1979)은 기댓값 최대화로 각 어노테이터의 혼동 행렬을 추정하고 각 표에 어노테이터의 추정된 신뢰도로 가중치를 줍니다. 그러면 부주의한 어노테이터가 신중한 어노테이터보다 결과를 덜 흔듭니다. 크라우드 레이블 통합하기는 두 방법과 Dawid-Skene에 기반한 모델을 비교합니다.
Potato의 학습 실행은 model_training.aggregation으로 레이블을 통합합니다. 기본값 consensus는 프로젝트에 어노테이터가 둘 이상이면 Dawid-Skene을 실행하고 추정이 실패하면 다수결로 돌아갑니다. 다른 값인 majority는 다수결만 실행합니다. 두 방법 모두 스키마에 대한 어노테이터의 답 전체를 한 표로 취급합니다. 따라서 multiselect 답 두 개는 둘이 같은 레이블 집합에 체크했을 때만 같은 표로 셉니다.
실행의 consensus 설정과 합의 내보내기는 서로 다른 기능입니다. 합의 내보내기는 모든 어노테이터에게 한 표를 주고, 모든 항목의 모든 답에 대해 개수와 비율을 보고하며, 각 항목을 retired나 needs_review로 표시합니다. 항목마다 어노테이터가 어디서 갈리는지 보려면 학습 전에 내보내기를 읽으십시오. MACE는 같은 표에서 각 어노테이터의 역량 점수를 추정합니다.
불일치에서 배우기
공격성이나 감정 같은 주관적 과제에서는 어노테이터마다 항목을 다르게 읽기 때문에 의견이 갈릴 수 있고, 투표로 정한 레이블 하나는 그 갈림을 버립니다. Uma et al. (2021)은 통합된 레이블 하나가 아니라 불일치 자체로 학습하는 방법을 조사합니다. 이 방법의 한 계열은 소프트 레이블로 학습합니다. 소프트 레이블은 각 레이블을 고른 어노테이터의 비율로 만든 레이블 위의 확률 분포입니다.
hf-text-classification은 soft_targets: true 파라미터를 받습니다. 이 파라미터를 설정하면 둘 이상의 어노테이터가 레이블을 단 항목은 그 분포에 대한 교차 엔트로피로 어노테이터들의 갈림을 향해 학습합니다. 세 어노테이터 중 둘이 positive라고 했다면 목표는 positive 0.67, negative 0.33입니다. multiselect 스키마에서는 각 레이블이 그 레이블에 체크한 어노테이터의 비율을 향해 학습합니다. 어노테이터가 한 명인 항목은 전처럼 그 어노테이터의 레이블로 학습합니다. 그러면 모델은 사람들이 갈린 곳에서 확신하지 못하게 되며, 각 예측에는 모델의 probabilities가 들어 있습니다. 표가 갈린 홀드아웃 항목에서 실행은 세 가지 지표를 더 보고합니다.
| 지표 | 지표가 측정하는 것 |
|---|---|
soft_jsd | 모델의 분포와 어노테이터들의 갈림 사이의 Jensen-Shannon 발산, 0에서 1까지의 비트 단위 |
soft_cross_entropy | 모델의 분포 아래에서 어노테이터들의 갈림의 교차 엔트로피 |
ece | 투표로 정한 레이블에 대한 최상위 레이블의 기대 보정 오차, 신뢰도 구간 10개 기준 |
소프트 레이블 스키마에서는 각 어노테이터가 슬라이더로 분포를 줍니다. hf-text-classification은 soft_label 스키마를 항상 어노테이터들의 평균 분포를 향해 학습하며, 사전 레이블은 슬라이더를 예측된 분포로 설정합니다. 소프트 목표에는 항목당 레이블이 둘 이상 필요합니다. 그래서 불일치로 학습하려는 연구는 처음부터 겹치는 레이블을 모으며, 겹침 설정은 어노테이터는 몇 명이 필요할까?가 다룹니다. 불일치는 잡음이 아니라 신호다는 갈림을 데이터에 남겨야 하는 이유를 설명합니다.
Train, 검증, test 분할
학습, 검증, test 분할은 서로 다른 세 가지 일을 합니다. 학습 분할은 모델의 가중치를 맞춥니다. 검증 분할은 후보 모델 중에서, 예를 들어 학습을 멈출 에폭을 고릅니다. test 분할은 보지 못한 데이터에서의 성능을 추정하며 이 두 선택에는 관여하지 않습니다. 검증으로 체크포인트를 고르는 것은 검증에 맞추는 한 형태입니다. 가장 좋은 검증 점수로 유지한 체크포인트의 검증 점수는 위로 치우치며, 선택이 참고하지 않은 항목에서 나온 것은 test 점수뿐입니다.
Potato 실행은 기본적으로 레이블이 달린 항목을 70/15/15로 나눕니다(splits). 각 항목의 분할은 항목 ID의 시드가 있는 해시에서 나옵니다(split_seed). 따라서 한 실행에서 홀드아웃된 항목은 split_seed와 splits가 그대로인 한 다음 실행에서도 홀드아웃됩니다. 둘 중 하나를 바꾸면 홀드아웃 항목이 학습으로 옮겨질 수 있고, 그 뒤의 모든 점수는 부분적으로 암기를 측정하게 됩니다. 둘 다 연구 시작 때 한 번만 설정하십시오.
hf-text-classification 같은 파인튜닝 트레이너는 검증에서 가장 높은 점수를 낸 에폭의 체크포인트를 유지합니다. 그런 실행의 대표 점수는 test에서 나옵니다. sklearn-text, setfit, rdkit-property, 결정 모델 트레이너, 추론 브리지는 검증에서 아무것도 고르지 않으며, 그 트레이너의 실행은 검증에 항목이 있을 때마다 대표 점수를 검증에서 가져옵니다. 실행 표의 Held-out score 열 툴팁은 각 숫자 뒤의 분할과 지표를 알려 줍니다. 레이블은 있는데 예측이 없는 항목은 틀린 것으로 계산됩니다. 트레이너는 어려운 항목을 건너뛰어 점수를 올릴 수 없으며, <split>_coverage는 예측을 받은 항목의 비율을 보고합니다.
수정된 항목과 고정된 항목
해시가 어느 분할에 배정했든, 두 종류의 항목은 이후 모든 실행의 train 분할로 갑니다. 첫 번째는 모델 검토에서 검토자가 수정한 항목이고, 두 번째는 카탈로그 페이지에서 슬라이스 옆의 Train on these로 누군가 고정한 항목입니다. 수정은 모델이 가장 못한 항목에서 나오므로, 검증이나 test에 수정된 항목이 있으면 모델 자신의 실수 표본으로 모델에 점수를 매기게 됩니다. 홀드아웃 항목을 학습으로 옮긴 실행은 그 개수와 함께 경고를 로그에 남기며, 그 실행의 홀드아웃 점수는 이전 실행의 점수와 직접 비교할 수 없습니다. 이전 실행이 홀드아웃한 수정된 항목으로 학습한 실행도 경고를 남기는데, 이전 실행의 검증 또는 test 항목이나 그 항목에서 저장한 데이터셋에 대한 점수에 새 모델이 학습한 항목이 포함되기 때문입니다. 수정된 항목과 고정된 항목은 항상 학습한다가 규칙을 알려 줍니다.
각 모델이 학습한 것 기록하기
두 실행을 비교하려면 각 실행이 어떤 항목으로 학습하고 점수를 매겼는지 알아야 합니다. 모든 Potato 실행은 <output_annotation_dir>/training/runs/<run_id>/bundle/ 아래에 train.jsonl, val.jsonl, test.jsonl, labels.json, manifest.json이 든 번들을 씁니다. 매니페스트에는 분할 시드, 통합 방법, 각 분할의 항목 수, 학습으로 강제 이동된 항목 수, 분할 파일의 SHA-256 다이제스트가 기록됩니다. 번들의 어떤 것도 Potato를 다시 참조하지 않으며, Potato 밖의 스크립트가 번들을 통합된 레이블과 분할의 독립된 사본으로 읽을 수 있습니다.
프로젝트 데이터베이스 project.sqlite에는 실행당 한 행이 있는 장부가 있습니다. 각 행에는 트레이너, 파라미터, 분할 크기, 분할 시드, 홀드아웃 지표, 번들 다이제스트가 기록됩니다. 두 번째 테이블은 실행마다 각 항목이 어느 분할에 있었는지 기록합니다. 되쓰기는 그 테이블을 읽고, 장부에 남아 있는 어떤 실행이라도 학습한 항목에는 사전 레이블을 붙이지 않습니다(retain_runs는 기본적으로 끝난 실행 다섯 개를 유지합니다). 모델은 새 데이터에 대해 아무것도 알려 주지 않는 이유로 자기가 학습한 항목에 자신감을 보입니다.
이후 모델을 정확히 같은 항목으로 비교하려면, 실행 페이지의 Keep this split as a dataset이 실행의 검증, test, train 항목을 합의된 사람 레이블과 함께 데이터셋의 한 버전으로 저장합니다. 저장된 버전은 이후에 바뀌지 않습니다. 저장된 각 버전에는 분할 하나가 들어 있으며 이전 버전에 더하지 않고 처음부터 시작합니다. 실행 2의 검증 항목을 실행 1의 것 위에 저장하면 실행 2가 학습한 항목이 포함될 것이기 때문입니다. 저장된 입력에는 사전 레이블 필드가 빠져 있으므로 저장된 버전에 대한 평가에서는 모델의 답을 읽을 수 없습니다. 저장하려면 datasets.enabled: true가 필요합니다. 모델이나 데이터셋이 프로젝트를 떠날 때는 데이터셋과 모델 문서화하기가 데이터시트와 모델 카드를 다룹니다.
첫 모델에 필요한 데이터 양
Potato의 각 트레이너는 train 분할에 min_instances개 미만의 항목이 있으면 학습을 거부합니다. 아래 기본값은 실행이 시작되는 개수입니다.
| 트레이너 | min_instances 기본값 | 비고 |
|---|---|---|
setfit | 8 | 프로젝트 초반을 위해 만들어졌으며 레이블당 항목 8개 정도에서 시작합니다 |
sklearn-text | 10 | 학습 항목 50개부터만 신뢰도를 보정합니다 |
hf-audio-tagger | 10 | |
hf-text-classification, hf-token-classification, hf-image-classification | 20 | |
llm-sft, llm-dpo | 20 |
하한은 train 분할만 셉니다. 기본 70/15/15 분할에서 sklearn-text 실행은 항목 약 15개에 레이블이 달리면 시작됩니다. Potato 저장소의 모델 학습 예제는 측정된 한 지점을 알려 줍니다. 예제의 합성 상품 리뷰 160개 중 120개에 한 번씩 레이블을 달았을 때, sklearn-text 실행 한 번이 검증에서 macro-F1 0.84를 기록하고 사전 레이블 80개를 게시했습니다. 이 수치는 합성 레이블 두 개짜리 과제 하나에서 나온 것이며, 자기 과제에서는 자기 실행의 홀드아웃 점수가 읽어야 할 숫자입니다.
sklearn-text로 시작하십시오. 이 트레이너는 일반 설치 외에 필요한 것이 없고 GPU도 필요 없습니다. 레이블이 들어올 때마다 재학습하고 split_seed를 그대로 둔 채 실행마다 홀드아웃 점수를 지켜보십시오. 사전 레이블은 어노테이터를 고착시킵니다. 홀드아웃 점수가 모델의 답을 보여 줄 만해질 때까지 writeback.schemas를 비워 두십시오. 모델 지원 레이블링은 어노테이터가 사전 레이블을 보면 무엇이 달라지는지를, 검토와 무심코 승인을 구분하는 방법은 어노테이터가 여전히 항목을 읽는지 확인하는 방법을 다룹니다.
각 결정을 설정하는 설정 파일
아래 설정은 레이블이 둘인 감성 스키마로 학습합니다. model_training 아래의 각 키는 위의 결정 하나씩을 설정합니다.
annotation_task_name: "Review sentiment"
task_dir: "."
data_files:
- "data/reviews.json"
item_properties:
id_key: "id"
text_key: "text"
output_annotation_dir: "annotation_output"
annotation_schemes:
- annotation_type: "radio"
name: "sentiment"
description: "Is this review positive or negative?"
labels: ["positive", "negative"]
model_training:
enabled: true
aggregation: consensus
split_seed: 0
splits: {train: 0.7, val: 0.15, test: 0.15}
trainer_params:
hf-text-classification:
soft_targets: trueaggregation: consensus는 겹치는 레이블을 Dawid-Skene으로 통합합니다. split_seed와 splits는 연구 기간 내내 바뀌지 않아야 하므로 기본값으로 명시했습니다. soft_targets: true는 프로젝트의 모든 hf-text-classification 실행이 투표 분포로 학습하게 합니다. 그 트레이너에는 pip install "potato-annotation[train-text]"가 필요하며, sklearn-text는 같은 설정에서 추가 설치 없이 실행됩니다. writeback 블록이 없으면 어노테이터에게 사전 레이블이 보이지 않습니다. 설정으로 서버를 다시 시작하고, /admin/training을 열고, 트레이너와 sentiment 스키마를 고른 뒤, Train now를 클릭하십시오. 모델 학습 설정 레퍼런스는 모든 키를 나열하고, 루프 안의 모델 튜토리얼은 되쓰기와 자동 재학습을 더합니다.
더 읽어보기
- 모델 학습 개요
- 첫 모델 학습하기
- 모델 지원 레이블링
- 머신러닝을 위한 어노테이션 내보내기
- 크라우드 레이블 통합하기
- 어노테이터 간 일치도
- GitHub의 모델 학습 레퍼런스에는 모든 스키마 유형의 홀드아웃 지표가 있습니다
참고문헌
- Dawid, A. P., and Skene, A. M. (1979). Maximum Likelihood Estimation of Observer Error-Rates Using the EM Algorithm. Applied Statistics, 28(1), 20. doi.org/10.2307/2346806
- Uma, A. N., Fornaciari, T., Hovy, D., Paun, S., Plank, B., and Poesio, M. (2021). Learning from Disagreement: A Survey. Journal of Artificial Intelligence Research, 72, 1385–1470. doi.org/10.1613/jair.1.12752