ã¯ããã«
huggingfaceã®Trainerã¯ã©ã¹ã¯huggingfaceã§æäŸãããã¢ãã«ã®äºååŠç¿ã®ãšãã«äœ¿ããã®ã ãšæã£ãŠãŠãäžæµã¿ã¹ã¯ãåŠç¿ããããšãïŒFine TuningïŒã¯æ®éã«åŠç¿ã®ã³ãŒããå®è£
ããŠããã§ãããäžæµã¿ã¹ã¯ãåŠç¿ããããšããTrainerã¯ã©ã¹ã¯äœ¿ããŠããã¡ããã¡ã䟿å©ã§ããã
ãã Trainerã¯ã©ã¹ã®initãTrainingArgumentsã®åŒæ°ã¯ãããããããããããããããšãã人ã®ããã«ãTrainerã¯ã©ã¹ã®Fine Tuningæã®äœ¿ãæ¹ãå®è£
ãéããŠãŸãšããŠã¿ãããšæããŸãã
ä»åã¯èªç¶èšèªåŠçã®ã¿ã¹ã¯ãšããŠlivedoorãã¥ãŒã¹ã³ãŒãã¹ã®ã¿ã€ãã«æã®ã«ããŽãªãŒåé¡åé¡ãFine Tuningã®äŸé¡ãšããŠæ±ãããšæããŸãããViTã®Fine Tuningãšãã§ãåæ§ããšæããŸãã
åºæ¬çã«ã¯huggingfaceã®Trainerã¯ã©ã¹ã®ãªãã¡ã¬ã³ã¹ãã²ãããèŠãªããå匷ããã®ã§ã詳ããã¯ãªãã¡ã¬ã³ã¹ããåç
§ãã ããã
Trainerã¯ã©ã¹ã䜿ã£ãFineTuningã®å®è£ äŸ
ããŒã¿æºå
livedoorãã¥ãŒã¹ã³ãŒãã¹ãbody, title, categoryã«åããããŒã¿ãã¬ãŒã ãäºåã«çšæããŠãããŸãã
import pandas as pd
import os
df = pd.read_pickle('./input/livedoor_data.pickle')
# ã«ããŽãªãŒã®IDåãä»äžããŠãã
categories = df['category'].unique().tolist()
category2id = {cat: categories.index(cat) for cat in categories}
df['category_id'] = df['category'].map(lambda x: category2id[x])
df.sample(3)
ããŒã¿ãåŠç¿ãæ€èšŒããã¹ãã§åããŸãã
from sklearn.model_selection import train_test_split
train_df, eval_df = train_test_split(df, train_size=0.7)
eval_df, test_df = train_test_split(eval_df, train_size=0.5)
print('train size', train_df.shape)
print('eval size', eval_df.shape)
print('test size', test_df.shape)
# train size (5163, 4)
# eval size (1106, 4)
# test size (1107, 4)
Datasetã¯ã©ã¹ãçšæ
DatasetããããŒã¿ãåãåºããšèŸæžåœ¢åŒã§ã¿ã€ãã«æãšã«ããŽãªãŒã®IDãçŽä»ããããŒã¿ãåãããããªåœ¢åŒã«ããŸããã
from torch.utils.data import Dataset
from tqdm import tqdm
class LivedoorDataset(Dataset):
def __init__(self, df):
self.features = [
{
'title': row.title,
'category_id': row.category_id
} for row in tqdm(df.itertuples(), total=df.shape[0])
]
def __len__(self):
return len(self.features)
def __getitem__(self, idx):
return self.features[idx]
train_dataset = LivedoorDataset(train_df)
eval_dataset = LivedoorDataset(eval_df)
test_dataset = LivedoorDataset(test_df)
train_datsetããããŒã¿ã1ä»¶åãåºããŠäžèº«ã確èªããŠã¿ããšãããªæãã§ãã
train_dataset[0]
# {'title': 'èäœæŽŸã€ã±ã¡ã³ç·åºæŒã§ããã£ãã³ã°ã»ãã€ã¿ã ã®â³ã¹ããªããçµéšâ³ãæ ç»åïŒ', 'category_id': 0}
DataCollatorã®å®çŸ©
-
Trainerã¯ã©ã¹ãDataLoaderãããªããŠDataCollatorãåŒæ°ãšããŠåãåãã®ã§ãDataCollatorã¯ã©ã¹ãèªäœããŸãã - huggingfaceã
DataCollatorã¯ã©ã¹ãããã€ãæäŸããŠãŸãããä»åã¯åçŽãªåŠçããããªãã®ã§ãèªäœã§æžãŸããŠãŸãã
import torch
from transformers import AutoTokenizer
class LivedoorCollator():
def __init__(self, tokenizer, max_length=512):
self.tokenizer = tokenizer
self.max_length = max_length
def __call__(self, examples):
examples = {
'title': list(map(lambda x: x['title'], examples)),
'category_id': list(map(lambda x: x['category_id'], examples))
}
encodings = self.tokenizer(examples['title'],
padding=True,
truncation=True,
max_length=self.max_length,
return_tensors='pt')
encodings['category_id'] = torch.tensor(examples['category_id'])
return encodings
tokenizer = AutoTokenizer.from_pretrained('cl-tohoku/bert-base-japanese-whole-word-masking')
livedoor_collator = LivedoorCollator(tokenizer)
åŸã®åŠçã§ã¯äœ¿ããŸããããDataCollatorã®åãã確èªããããã«ãDataLoaderãäœæããŠã1ä»¶ãããããŒã¿ãåãåºããŠã¿ãŸãã
from torch.utils.data import DataLoader
loader = DataLoader(train_dataset, collate_fn=livedoor_collator, batch_size=8, shuffle=True)
batch = next(iter(loader))
for k,v in batch.items():
print(k, v.shape)
# input_ids torch.Size([8, 41])
# token_type_ids torch.Size([8, 41])
# attention_mask torch.Size([8, 41])
# category_id torch.Size([8])
print(batch)
# {'input_ids': tensor([[ 2, 9680, 10520, 28770, 28865, 450, 52, 53, 512, 9594,
# 5359, 126, 243, 28673, 12, 6, 5359, 40, 16329, 28476,
# 2935, 63, 7388, 104, 6, 331, 28483, 4658, 35, 15288,ã»ã»ã»
# 'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,ã»ã»ã»
# 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ã»ã»ã»
# 'category_id': tensor([0, 8, 8, 2, 1, 7, 0, 2])}
ã¢ãã«ã®å®çŸ©
ããã¹ãã®ç¹åŸŽé倿ã¯åŠç¿æžBERTã«ãŸãããŠãã«ããŽãªãŒåé¡çšã®ãããïŒnn.LinearïŒã1局远å ããã·ã³ãã«ãªã¢ãã«ãå®è£
ããŸãããã¢ãã«å®çŸ©ãå°ãTrainerã¯ã©ã¹çšã«æžãå¿
èŠããããŸãã
Trainerã¯ã©ã¹ã®ãªãã¡ã¬ã³ã¹ã«ãæžããŠããããã«ãTrainerã¯ã©ã¹ã¯huggingfaceã®PreTrainedModelã§åäœãæé©åãããŠãããããªã®ã§ãPreTrainedModelãšåããããªã«ãŒã«ã§åäœããã¢ãã«ãå®è£
ããå¿
èŠããããŸãã
æ®æ®µFineTuningãšããããšãã®ã¢ãã«ã¯nn.Moduleãç¶æ¿ããã¯ã©ã¹ã§å®è£
ããããšæããŸããã以äžã®ã«ãŒã«ãæºãããŠããã°Trainerã¯ã©ã¹ã¯åããŠãããŸãã
- ã¢ãã«ã®æ»ãå€ã¯huggingfaceã®
ModelOutputã®åœ¢åŒã§è¿ãïŒãããã¯tupleã§ãããããã§ãããModelOutputã®ã»ãã䟿å©ã ãšæãã®ã§ãModelOutputã®ã±ãŒã¹ã§èª¬æããŸããïŒ - ã¢ãã«ã®
forwardãæ£è§£ã©ãã«ãåãåããããã«ããŠãã - ã¢ãã«ãæå€±ã®å€ãè¿ã
1. ã¢ãã«ã®æ»ãå€ãModelOutputã«ãã
ModelOutputã¯transformers.modeling_outputs.ModelOutputã䜿ãã°ããã ãã§ããããŒã«[]ãããªããŠ.ã§ãã¢ã¯ã»ã¹ã§ãã䟿å©ãªèŸæžã®ã€ã¡ãŒãžã§ããBERTã®æ»ãå€ã®åBaseModelOutputWithPoolingAndCrossAttentionsãModelOutputãç¶æ¿ããã¯ã©ã¹ã§ããã
ModelOutputã䜿ããšãã¯ãModelOutputã®ãªãã¡ã¬ã³ã¹ã§ããããŠãããã«ãæå€±ã®å€ãlossãã¢ãã«ã®äºæž¬çµæãlogitsãšããååã«æ ŒçŽããŸãã
2. forwardã§æ£è§£ã©ãã«ãåãåããããã«ãã
ä»åèªäœããDataCollatorãæ£è§£ã©ãã«cateogory_idãè¿ãããã«ããŠããã®ã§ãforwardã®åŒæ°ã«ãcateogory_idãå«ããŠããã°è¯ãã§ããïŒTrainerã¯ã©ã¹ã®ããã©ã«ãã§ã¯æ£è§£ã©ãã«ãlabelsãšããååã§æ³å®ããŠããŸãããåŸã«è§£èª¬ããTrainingArgumentsã§æ£è§£ã©ãã«ã®ååãæå®ã§ããŸãããã«ãã¿ã¹ã¯åŠç¿ã®ãããªæ£è§£ã©ãã«ãè€æ°ããã±ãŒã¹ã«ã察å¿ã§ããŸããïŒ
3. ã¢ãã«ãæå€±ãè¿ãããã«ãã
ã€ãŸãã¯ã¢ãã«å
ã§æå€±ãèšç®ããå¿
èŠãããã®ã§ãã¢ãã«ã®initã§æå€±é¢æ°ãæå®ããããã«ããŠããŸããã¢ãã«ã®forwardå
ã§åŒæ°ã§åãåã£ãæ£è§£ã©ãã«category_idïŒãlabelsïŒãšã¢ãã«ã®äºæž¬çµæãåãåã£ãп倱颿°ã§lossãèšç®ããModelOutputã®lossã«æå€±ãæ ŒçŽããŠè¿ããŠããã°OKã§ãã以äžã®å®è£
ã§ã¯FineTuningåŸã«æšè«ã§äœ¿ãããšãæ³å®ããŠãæå€±é¢æ°ãinitã§æå®ããªãã£ãå Žåãlossã¯èšç®ãããNoneãè¿ãããã«ããŠããŸãã
import torch.nn as nn
from transformers import AutoModel
from transformers.modeling_outputs import ModelOutput
class LivedoorNet(nn.Module):
def __init__(self, pretrained_model, num_categories, loss_function=None):
super().__init__()
self.bert = pretrained_model
self.hidden_size = self.bert.config.hidden_size
self.linear = nn.Linear(self.hidden_size, num_categories)
self.loss_function = loss_function
def forward(self,
input_ids,
attention_mask=None,
position_ids=None,
token_type_ids=None,
output_attentions=False,
output_hidden_states=False,
category_id=None):
outputs = self.bert(input_ids,
attention_mask=attention_mask,
position_ids=position_ids,
token_type_ids=token_type_ids,
output_attentions=output_attentions,
output_hidden_states=output_hidden_states)
state = outputs.last_hidden_state[:, 0, :]
state = self.linear(state)
loss=None
if category_id is not None and self.loss_function is not None:
loss = self.loss_function(state, category_id)
attentions=None
if output_attentions:
attentions=outputs.attentions
hidden_states=None
if output_hidden_states:
hidden_states=outputs.hidden_states
return ModelOutput(
logits=state,
loss=loss,
last_hidden_state=outputs.last_hidden_state,
attentions=attentions,
hidden_states=hidden_states
)
loss_fct = nn.CrossEntropyLoss()
pretrained_model = AutoModel.from_pretrained('cl-tohoku/bert-base-japanese-whole-word-masking')
net = LivedoorNet(pretrained_model, len(categories), loss_fct)
compute_metricsãèªäœãã
ãããŸã§ã®å®è£
ã®æºåã§Trainerã¯ã©ã¹ã¯åãããã®ã§ããããã®ãŸãŸã ãšãåŠç¿äžã®æ€èšŒããŒã¿ã«å¯Ÿããã¡ããªã¯ã¹ã®èšç®ãè¡ãããŸãããã¡ããªã¯ã¹ã¯èªäœã§é¢æ°ãçšæããå¿
èŠããããŸããä»åã¯ãã¥ãŒã¹èšäºã®ã«ããŽãªãŒã®åé¡åé¡ãªã®ã§ãè©äŸ¡ææšã«F1ã¹ã³ã¢ã䜿ãããšã«ããŸããåãããŠPrecisionãRecallãèšç®ã§ããããã«ããŸããã
Trainerã¯ã©ã¹ã«æž¡ãcompute_metricsã®åŒæ°ã¯EvalPredictionãæ³å®ããŠããŸããEvalPredictionã«ã€ããŠã¯ãã¡ããåç
§ããŠããã ãããã®ã§ãããèŠã¯EvalPrediction.predictionsã«ã¢ãã«ã®äºæž¬çµæããEvalPrediction.label_idsã«æ£è§£ã©ãã«ãæ ŒçŽãããŠããŸãã
æ»ãå€ã¯èŸæžåœ¢åŒã§è¿ããŠããã°è¯ãã§ãããã®èŸæžã§å®çŸ©ããããŒåïŒprecision, recall, f1ã¯åŸã«eval_ã®æ¥é èŸãä»äžãããŠãã°æ
å ±ã«äœ¿ãããŸããïŒ
from transformers import EvalPrediction
from typing import Dict
from sklearn.metrics import precision_score, recall_score, f1_score
def custom_compute_metrics(res: EvalPrediction) -> Dict:
# res.predictions, res.label_idsã¯numpyã®array
pred = res.predictions.argmax(axis=1)
target = res.label_ids
precision = precision_score(target, pred, average='macro')
recall = recall_score(target, pred, average='macro')
f1 = f1_score(target, pred, average='macro')
return {
'precision': precision,
'recall': recall,
'f1': f1
}
TrainingArgumentsãèšå®ãã
TrainingArgumentsã®åŒæ°ã¯å€§éã«ãã£ãŠãå
šéšç޹ä»ããã®ã¯é£ãã®ã§è©³ããã¯ãªãã¡ã¬ã³ã¹ãåç
§ããŠããã ãããã§ãããããã€ããã䜿ããããªãã®ã玹ä»ããŸãã
-
output_dir: ã¢ãã«ã®ãã§ãã¯ãã€ã³ããåŠç¿åŸã®ãã©ã¡ãŒã¿ãã¡ã€ã«ãšãã®ä¿åå -
evaluation_strategy: ããã©ã«ãã¯stepsãæå®ãããŠãŸããè©äŸ¡ããŒã¿ãã©ã®ã¿ã€ãã³ã°ã§è©äŸ¡ããããæå®ããŸããstepsãæå®ãããšãeval_stepsã§æå®ããã¹ãããæ¯ã«compute_metricsã§æå®ããã¡ããªã¯ã¹ãèšç®ãããŸããä»åã¯epochãæå®ããã®ã§ã1ãšããã¯çµãããã³ã«è©äŸ¡ãããŸãã -
logging_strategy: åŠç¿ã®ãã®ã³ã°ïŒæå€±ã®å€ãšãåŠç¿çã®ç¶æ³ãšãïŒãã©ã®ã¿ã€ãã³ã°ã§å®æœããããæå®ããŸããããã©ã«ãã¯stepsãæå®ãããŠãããlogging_stepsã§æå®ããã¹ãããæ¯ã«ãã®ã³ã°ãããŸããä»åã¯epochãæå®ããã®ã§ã1ãšããã¯çµãããã³ã«ãã®ã³ã°ãããŸãã -
save_strategy: ãã§ãã¯ãã€ã³ãïŒåŠç¿ã®äžéã®ç¶æ³ïŒãã©ã®ã¿ã€ãã³ã°ã§ä¿åããããæå®ããŸããããã©ã«ãã¯ãã¯ãstepsãæå®ãããŠãããsave_stepsã§æå®ããã¹ãããæ¯ã«ãã§ãã¯ãã€ã³ããä¿åãããŸããä»åã¯epochãæå®ããã®ã§ã1ãšããã¯çµãããã³ã«ãã§ãã¯ãã€ã³ããä¿åãããŸãã -
save_total_limit: ãã§ãã¯ãã€ã³ããäœä»¶æ®ããã -
label_names: æ£è§£ã©ãã«ã®ã©ãã«åãé åã§æå®ããŸããæå®ããªããã°Trainerã¯ã©ã¹ã¯æ£è§£ã©ãã«ãlabelsãšããååã§åç §ãã«è¡ããŸãããã«ãã¿ã¹ã¯åŠç¿ã®ãããªæ£è§£ã©ãã«ãè€æ°ããã±ãŒã¹ã§ã察å¿å¯èœã®ããã§ãã -
lr_scheduler_type: åŠç¿çã®ã¹ã±ãžã¥ãŒã«ã®ãã³ãã¬ãŒããæå®ããŸããã©ããªãã³ãã¬ãŒãããããã¯ãã¡ãããåç §ãã ãããSchedulerTypeã®ãœãŒã¹ã³ãŒããèŠããšãã³ãã¬ãŒããšååã®å¯Ÿå¿é¢ä¿ãããããŸããããã©ã«ãã¯linearãæå®ãããŠãããæçµãšããã¯ã«åãã£ãŠç·åœ¢ã«åŠç¿çãæžå°ããŠãããããªã¹ã±ãžã¥ãŒã«ã«ãªã£ãŠããŸãã以äžã®ããã«constantãæå®ããã°åŠç¿çãæžå°ãããããªã¹ã±ãžã¥ãŒã«ã¯èšå®ãããŸããã -
learning_rate: åŠç¿çã§ããããã©ã«ãã¯5e-5ãæå®ãããŠããŸãããã®å€ããã®ãŸãŸäœ¿ãããã®ã§ãä»åã¯æå®ããŠããŸããã -
warmup_ratio/warmup_steps: ïŒä»åã¯æå®ããŠããŸãããïŒããã©ã«ãã§ã¯ãšãã«0ãæå®ãããŠããã®ã§ãã©ãŒã ã¢ããã¯è¡ãããŸãããããããã®ã©ã¡ãããæå®ãããšãæå®ããã¹ããããŸã§ç·åœ¢ã«åŠç¿çãå¢å ããŠãããã©ãŒã ã¢ããã®åŠç¿ãè¡ãããšãã§ããŸãã -
metric_for_best_model: early stoppingãããéã«ã¯å¿ èŠã§ããç°ãªãã¢ãã«ãæ¯èŒãããšãã«æ¯èŒããææšãããŸããcompute_metricsã§å®çŸ©ããã¡ããªã¯ã¹ã®ååãæå®ããŸããä»åã¯F1ã¹ã³ã¢ãäžçªè¯ãã¢ãã«ãä¿åãããã®ã§ãf1ãæå®ããŸããã -
load_best_model_at_end: early stoppingãè¡ããšãã¯Trueãæå®ããå¿ èŠããããŸããåŠç¿äžã«åŸããããã¹ãã¢ãã«ãåŠç¿çµäºåŸã«ããŒããããã©ããã -
per_device_train_batch_size: åŠç¿äžã«1GPUã«å²ãæ¯ãããããµã€ãºãäŸãã°2æã®GPUã䜿ããç°å¢ã§ã¯1ææ¯ã«æå®ããããããµã€ãºãä¹ããŸãã -
per_device_eval_batch_size: è©äŸ¡ããŒã¿ãèšç®ãããšãã«1GPUã«å²ãæ¯ãããããµã€ãº -
num_train_epochs: åŠç¿ã®ãšããã¯æ° -
remove_unused_columns: ããã©ã«ããTrueããããTrueã ãšãTrainerã«ãããããŒã¿ã»ããã®ã«ã©ã ïŒä»åã§ããã°ãtitleãšcategory_idïŒã®ãã¡ã¢ãã«ã®forward颿°ã®åŒæ°ã«ååšããªããã®ã¯èªåã§åé€ãããŸããä»åã®å®è£ æ¹æ³ã¯collatorã¯ã©ã¹ã§tokenizerã«éããŠinput_idsãšããååŸãããã®ã§ãã®ãã©ã¡ãŒã¿ãTrueã ãšcollatorã®__call__颿°å ã§ç©ºã®èŸæžãæž¡ãããŠããŸããŸããdatasetã®æç¹ã§tokenizerã«éããŠtensorãä¿æããŠãããããªã±ãŒã¹ã§ããã°Trueã§è¯ããããããŸããããä»åã¯Falseã«ããŸãã
2023/4/10 远èš
transformersã®ããŒãžã§ã³ã4.27.1ã䜿ã£ãŠãããšãããåŠç¿ãéå§ããã wandb ã«é¢ãã以äžã®ã¡ãã»ãŒãžã衚瀺ãããŸããã
wandb: (1) Create a W&B account
wandb: (2) Use an existing W&B account
wandb: (3) Don't visualize my results
wandb: Enter your choice:
å¥ã« wandb ãšã䜿ã£ãŠãŸããããŒãã£ãŠäººã¯æ¯åããã衚瀺ãããã®ãã£ãšããããšæããŸãããããã¯ä»¥äžã®åŒæ°ã§ "none" ãæå®ããã°åé¿ã§ããŸãã
- 'report_to': çµæããã°æ
å ±ããªãã®ãã©ãããã©ãŒã ã䜿ã£ãŠãŸãšããããæå®ããŸããããã©ã«ãã§
"all"ã«ãªã£ãŠããã§ããããããªãå Žåã¯"none"ãæå®ããã°è¯ãã§ãã
from transformers import TrainingArguments
training_args = TrainingArguments(
output_dir='./output/model',
evaluation_strategy='epoch',
logging_strategy='epoch',
save_strategy='epoch',
save_total_limit=1,
label_names=['category_id'],
lr_scheduler_type='constant',
metric_for_best_model='f1',
load_best_model_at_end=True,
per_device_train_batch_size=64,
per_device_eval_batch_size=64,
num_train_epochs=3,
remove_unused_columns=False,
report_to='none'
)
Trainerã¯ã©ã¹ã®å®çŸ©ãšå®è¡
ãããŸã§å®çŸ©ããŠãããã®ãå
šéšTrainerã¯ã©ã¹ã®initã«æž¡ããŠããã°OKã§ãã
ä»åã¯early stoppingãè¡ã£ãŠããŸããããã®éã¯callbacksã«ä»¥äžã®ããã«EarlyStoppingCallbackãæå®ããŠãããŸãã
Trainerã¯ã©ã¹ã§äœ¿ããcallbacksã®è©³ããæ
å ±ã¯ãªãã¡ã¬ã³ã¹ããåç
§ãã ããã
Trainerã¯ã©ã¹ãå®çŸ©ããã°ãåŸã¯.trainã§åŠç¿ãéå§ã§ããŸããããã®ãšãã«ignore_keys_for_evalã§è©äŸ¡ã«å¿
èŠãªãã¢ãã«ã®æ»ãå€ã®å€æ°åãæå®ããããã«ããŸãããã
from transformers import Trainer
from transformers import EarlyStoppingCallback
trainer = Trainer(
model=net,
tokenizer=tokenizer,
data_collator=livedoor_collator,
compute_metrics=custom_compute_metrics,
args=training_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
callbacks=[EarlyStoppingCallback(early_stopping_patience=3)]
)
trainer.train(ignore_keys_for_eval=['last_hidden_state', 'hidden_states', 'attentions'])
notebookã§å®è¡ããã°ãããªæãã®progress barã衚瀺ãããŸããã

ãã§ãã¯ãã€ã³ãããåŠç¿ãåéãã
TrainingArgumentsã®åŒæ°ã«ãã§ãã¯ãã€ã³ãããåŠç¿ãåéãããšãã«æå®ããresume_from_checkpointããããŸãããTrainingArgumentsã§ãããæå®ããŠããã§ãã¯ãã€ã³ãããåŠç¿ãåéãããŸããã
詳ããã¯ãªãã¡ã¬ã³ã¹ãåç
§ããã ãããã§ããããã§ãã¯ãã€ã³ãããåŠç¿ãåéããããšãã¯ãTrainerã¯ã©ã¹ã®.trainã¡ãœããã«å¯ŸããŠãresume_from_checkpointãæå®ããå¿
èŠããããŸããTrueãæå®ããã°TrainingArgumentsã®output_dirã§æå®ãããã£ã¬ã¯ããªã®äžã«ããæåŸã®ãã§ãã¯ãã€ã³ãããåŠç¿ãåéãããŸãããã§ãã¯ãã€ã³ãã®ãã£ã¬ã¯ããªã®ãã¹ãæå®ããŠãã£ããããããšãã§ããŸãã
# ãã§ãã¯ãã€ã³ãããåŠç¿ãåéããããšããš
trainer.train(ignore_keys_for_eval=['last_hidden_state', 'hidden_states', 'attentions'],
resume_from_checkpoint=True)
ã¢ãã«ã®ä¿å
åŠç¿åŸã®ã¢ãã«ã®ä¿åã¯.save_modelã§ä¿åã§ããŸãããäžã®ããã°ã¬ã¹ããŒã®ãããªåãšããã¯ã®æå€±ã®æšç§»ã§ãã£ãããè©äŸ¡ããŒã¿ã®ã¡ããªã¯ã¹ã®æ
å ±ã¯.save_stateã§ä¿åã§ããŸãã.save_stateãå®è¡ãããšãTrainingArgumentsã®output_dirã§æå®ãããã©ã«ãã«trainer_state.jsonãšãããã¡ã€ã«ãä¿åãããŸãã
trainer.save_state()
trainer.save_model()
ãã¹ãããŒã¿ã®äºæž¬
ãã¹ãããŒã¿ã«å¯Ÿããäºæž¬ã¯.predictã§è¡ããŸããæåã«é¿ããšããtest_datasetãæå®ãããã¹ãã«å¿
èŠãªãã¢ãã«ã®æ»ãå€ã®å€æ°åãignore_keysã«æå®ããŸãã
.predictã®æ»ãå€ã®.predictionsã«ã¢ãã«ã®æšè«çµæãæ ŒçŽãããŠããŸãã
æåŸã«äºæž¬çµæãsklearnã®classification_reportã§è¡šç€ºããŠã¿ãŸããããã£ã3ãšããã¯ã§ããããæãã«åŠç¿ã§ããŠãæãã§ããã
pred_result = trainer.predict(test_dataset, ignore_keys=['loss', 'last_hidden_state', 'hidden_states', 'attentions'])
test_df['predict'] = pred_result.predictions.argmax(axis=1).tolist()
from sklearn.metrics import classification_report
print(classification_report(test_df['category_id'], test_df['predict'], target_names=categories))
# precision recall f1-score support
#
# movie-enter 0.85 0.90 0.87 136
# it-life-hack 0.87 0.86 0.87 103
# kaden-channel 0.96 0.93 0.94 136
# topic-news 0.87 0.88 0.88 112
#livedoor-homme 0.73 0.80 0.76 82
# peachy 0.81 0.72 0.76 127
# sports-watch 0.96 0.87 0.91 130
#dokujo-tsushin 0.83 0.90 0.86 145
# smax 0.96 0.97 0.96 136
#
# accuracy 0.87 1107
# macro avg 0.87 0.87 0.87 1107
# weighted avg 0.88 0.87 0.87 1107
ãããã«
äžã§èŠãããã«Fine Tuningæã®åŠç¿ã«é¢ããå®è£
ã¯TrainingArgumentsãæå®ããŠTrainerã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã«å¯ŸããŠ.trainã§çµããã§ããããã ãã§ãåŠç¿ãè©äŸ¡ããŒã¿ã®ãã®ã³ã°ãåŠç¿çã®ã¹ã±ãžã¥ãŒã©ãŒãEarly Stoppingãªã©ã®ãèªåã§å®è£
ãããšãªã£ãããããã倧å€ã¯å®è£
ããã£é£ã°ãããšãã§ããŸãããã¡ããTrainerã¯ã©ã¹ã®ä»çµã¿ãå
éšã§ã©ã®ãããªèšç®ãè¡ãããŠãããã¯ãªãã¡ã¬ã³ã¹ãçèªããŠçè§£ããŠããå¿
èŠã¯ãããŸãããä»å玹ä»ããå
容ã§å°ãã¯Trainerã¯ã©ã¹ã§ã©ããªããšãã§ããã®ãã®é°å²æ°ã¯ã€ãããã®ã§ã¯ãªãããšæããŸãã
Trainerã¯ã©ã¹ã®äŸ¿å©ããç¥ã£ãŠããŸã£ãã®ã§ãããèªåã§ããããåŠç¿ã³ãŒãã®å®è£
ãªããŠããããªã...
ããã
