0528_deep_hw / trainer_utils.py
yb1n's picture
Upload folder using huggingface_hub
845426e verified
Raw
History Blame Contribute Delete
4.36 kB
import inspect
import json
import re
from pathlib import Path
import numpy as np
from datasets import load_dataset, load_from_disk
from transformers import AutoTokenizer, Trainer, TrainingArguments
LABELS = {
"id2label": {0: "negative", 1: "positive"},
"label2id": {"negative": 0, "positive": 1},
}
def make_training_arguments(**kwargs):
params = inspect.signature(TrainingArguments.__init__).parameters
if "eval_strategy" in params and "evaluation_strategy" in kwargs:
kwargs["eval_strategy"] = kwargs.pop("evaluation_strategy")
if "evaluation_strategy" in params and "eval_strategy" in kwargs:
kwargs["evaluation_strategy"] = kwargs.pop("eval_strategy")
return TrainingArguments(**kwargs)
def make_trainer(tokenizer, **kwargs):
try:
return Trainer(processing_class=tokenizer, **kwargs)
except TypeError:
return Trainer(tokenizer=tokenizer, **kwargs)
def compute_binary_metrics(eval_pred):
logits, labels = eval_pred
preds = np.argmax(logits, axis=-1)
tp = int(((preds == 1) & (labels == 1)).sum())
fp = int(((preds == 1) & (labels == 0)).sum())
fn = int(((preds == 0) & (labels == 1)).sum())
accuracy = float((preds == labels).mean())
precision = tp / (tp + fp) if tp + fp else 0.0
recall = tp / (tp + fn) if tp + fn else 0.0
f1 = 2 * precision * recall / (precision + recall) if precision + recall else 0.0
return {
"accuracy": accuracy,
"precision": precision,
"recall": recall,
"f1": f1,
}
def load_or_prepare_imdb(
checkpoint="bert-base-uncased",
data_dir="./data/imdb_tokenized",
max_length=512,
padding="max_length",
max_train_samples=None,
max_eval_samples=None,
):
data_dir = Path(data_dir)
if max_train_samples is not None or max_eval_samples is not None:
train_tag = "all" if max_train_samples is None else str(max_train_samples)
eval_tag = "all" if max_eval_samples is None else str(max_eval_samples)
data_dir = data_dir / f"sample_train_{train_tag}_eval_{eval_tag}"
train_path = data_dir / "train"
eval_path = data_dir / "test"
tokenizer_path = data_dir / "tokenizer"
if train_path.exists() and eval_path.exists() and tokenizer_path.exists():
return (
load_from_disk(str(train_path)),
load_from_disk(str(eval_path)),
AutoTokenizer.from_pretrained(str(tokenizer_path)),
)
raw = load_dataset("imdb")
train_ds = raw["train"]
eval_ds = raw["test"]
if max_train_samples is not None:
train_ds = train_ds.select(range(max_train_samples))
if max_eval_samples is not None:
eval_ds = eval_ds.select(range(max_eval_samples))
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
def preprocess(examples):
return tokenizer(
examples["text"],
truncation=True,
padding=padding,
max_length=max_length,
)
train_ds = train_ds.map(preprocess, batched=True)
eval_ds = eval_ds.map(preprocess, batched=True)
train_ds = train_ds.remove_columns(["text"]).rename_column("label", "labels")
eval_ds = eval_ds.remove_columns(["text"]).rename_column("label", "labels")
data_dir.mkdir(parents=True, exist_ok=True)
train_ds.save_to_disk(str(train_path))
eval_ds.save_to_disk(str(eval_path))
tokenizer.save_pretrained(str(tokenizer_path))
return train_ds, eval_ds, tokenizer
def get_best_checkpoint(output_dir):
state_path = Path(output_dir) / "trainer_state.json"
if not state_path.exists():
return None, None
state = json.loads(state_path.read_text(encoding="utf-8"))
best_checkpoint = state.get("best_model_checkpoint")
if best_checkpoint is None:
return None, None
match = re.search(r"checkpoint-(\d+)", best_checkpoint)
best_step = int(match.group(1)) if match else None
return best_checkpoint, best_step
def find_backbone(model):
if hasattr(model, "backbone"):
return model.backbone
if hasattr(model, "base_model"):
return model.base_model
raise AttributeError("backbone or base_model was not found")
def set_backbone_trainable(model, trainable):
backbone = find_backbone(model)
for param in backbone.parameters():
param.requires_grad = trainable