Dataset
様々なソースを扱うことが可能。
csvファイルからDatasetDictを作成する例
import pandas as pd
from sklearn.model_selection import train_test_split
from datasets import Dataset, DatasetDict, ClassLabel
train_base_df = pd.read_csv("train.csv")
train_df, valid_df = train_test_split(train_all_df, test_size=0.1,
stratify=train_base_df["label"], random_state=SEED)
# reset_indexしないとindexが特徴量として認識される
train_df = train_df.reset_index(drop=True)
valid_df = valid_df.reset_index(drop=True)
dataset_dict = DatasetDict({
"train": Dataset.from_pandas(train_df),
"valid": Dataset.from_pandas(valid_df),
})
# ClassLabelクラスに変換
class_label = ClassLabel(num_classes=2, names=["normal", "hate"])
dataset_dict = dataset_dict.cast_column("label", class_label)
参考
DatasetDictにすればまとめて処理することも可能となる。
ラベル部分はClassLabelにしておくと後々便利である。
トークナイザ処理
dataset_dictに対してmapでtokenizerで処理すればinput_ids(トークン系列)やattention_maskが得られる。
from transformers import AutoTokenizer
model_name = "cl-tohoku/bert-base-japanese-whole-word-masking"
max_length = 77
# トークナイザ
tokenizer = AutoTokenizer.from_pretrained(model_name)
def tokenize(batch):
return tokenizer(batch["text"], padding="max_length", max_length=max_length, truncation=True)
dataset_dict = dataset_dict.map(tokenize, batched=True, batch_size=None)
トークナイザの学習時は注意が必要。
隠れ次元のベクトルを得る方法
Datasetクラスをうまくイテレーションする方法が分からないため、普通にrangeでforを回す。
modelへの入力時にはtensorに変換が必要で、若干煩雑となる。
modelは、AutoModelForSequenceClassificationなどではなく、普通にAutoModelの方で、ヘッドレスなものを使用する。
出力は、pooler_outputから得る。
pooler_outputの他にlast_hidden_stateがあるがその違いは、pooler_outputは、last_hidden_stateの系列先頭を線形層(入出力同じノード)とtanhを通したものである。
また、last_hidden_stateは、複数あるself-attentionの最終層という意味である。(系列の最後という意味ではないので注意)
import torch
from tqdm import tqdm
from transformers import AutoModel
model_name = "cl-tohoku/bert-base-japanese-whole-word-masking"
model = AutoModel.from_pretrained(model_name)
model.eval()
batch_size = 100
vectors = torch.empty((0, 768))
train_ds = dataset_dict["train"]
with torch.no_grad():
for i in tqdm(range(0, len(train_ds), batch_size), ascii=True):
output = model(
torch.tensor(train_ds[i:i+batch_size]['input_ids']),
torch.tensor(train_ds[i:i+batch_size]['attention_mask']),
)
vectors = torch.concat([vectors, output.pooler_output], axis=0)
モデルのconfig確認
以下で確認できる。ヘッド数や層数、隠れ状態数なども確認可能。
model_name = "cl-tohoku/bert-base-japanese-whole-word-masking"
model = AutoModel.from_pretrained(model_name)
model.config
出力は以下
BertConfig {
"_name_or_path": "cl-tohoku/bert-base-japanese-whole-word-masking",
"architectures": [
"BertForMaskedLM"
],
"attention_probs_dropout_prob": 0.1,
"classifier_dropout": null,
"hidden_act": "gelu",
"hidden_dropout_prob": 0.1,
"hidden_size": 768,
"initializer_range": 0.02,
"intermediate_size": 3072,
"layer_norm_eps": 1e-12,
"max_position_embeddings": 512,
"model_type": "bert",
"num_attention_heads": 12,
"num_hidden_layers": 12,
"pad_token_id": 0,
"position_embedding_type": "absolute",
"tokenizer_class": "BertJapaneseTokenizer",
"transformers_version": "4.23.1",
"type_vocab_size": 2,
"use_cache": true,
"vocab_size": 32000
}
EvalPrediction
compute_metricsを自作する場合にわたってくるクラス。
例えば以下のように使用する。
def compute_metrics(pred: EvalPrediction):
labels = pred.label_ids
preds = pred.predictions.argmax(-1)
f1 = f1_score(labels, preds)
recall = recall_score(labels, preds)
precision = precision_score(labels, preds, zero_division=0)
return {"f1_score": f1, "recall": recall, "precision": precision}
# ....
trainer = Trainer(
model=model,
args=training_args,
tokenizer=tokenizer,
train_dataset=dataset_dict["train"],
eval_dataset=dataset_dict["valid"],
compute_metrics=compute_metrics,
)
定義はコードの以下を参照。
SchedulerType
コードの以下でわかる。
class SchedulerType(ExplicitEnum):
LINEAR = "linear"
COSINE = "cosine"
COSINE_WITH_RESTARTS = "cosine_with_restarts"
POLYNOMIAL = "polynomial"
CONSTANT = "constant"
CONSTANT_WITH_WARMUP = "constant_with_warmup"
デフォルトは、"linear"
なので注意が必要。
MTEB
https://huggingface.co/blog/mteb
埋め込むベクトルを生成可能な事前学習モデルを評価するための大規模ベンチマークに使える。
112の言語、8つのタスク、58個のデータセットで評価する。