Python OutOfMemoryError

Python

1ソースコード 2```# 基本的なライブラリ3import numpy as np 4import pandas as pd 5import matplotlib.pyplot as plt 6import seaborn as sns 7 8# 列をすべて表示9pd.set_option('display.max_columns', None)10 11# データセットの読み込み12df=pd.read_csv('wrime-ver2.tsv', delimiter='\t')13 14# データセットの中身15df.head()16 17# データの振り分け18df['Train/Dev/Test'].value_counts()19 20# labelの値を調整21df["Avg. Readers_Sentiment"]=df["Avg. Readers_Sentiment"]+222 23# データセットを分ける24# label=感情極性(-2:強いネガティブ、-1:ネガティブ、0:ニュートラル、1:ポジティブ、2:強いポジティブ)25target=["Sentence","Avg. Readers_Sentiment"]26train_df=df[df['Train/Dev/Test']=='train']27train_df=train_df[target]28train_df=train_df.rename(columns={target[0]:'text',target[1]: 'label'})29validation_df=df[df['Train/Dev/Test']=='dev']30validation_df=validation_df[target]31validation_df=validation_df.rename(columns={target[0]:'text',target[1]: 'label'})32test_df=df[df['Train/Dev/Test']=='test']33test_df=test_df[target]34test_df=test_df.rename(columns={target[0]:'text',target[1]: 'label'})35train_df.head()36 37def head_tail_tokenize(text, tokenizer, max_length):38 tokens = tokenizer.tokenize(text)39 head_tokens = tokens[:max_length // 2] # 先頭からmax_length // 2個のトークンを取得40 tail_tokens = tokens[-(max_length - len(head_tokens)):] # 最後尾から残りのトークンを取得41 tokens = [tokenizer.cls_token] + head_tokens + [tokenizer.sep_token] + tail_tokens + [tokenizer.sep_token]42 43 input_ids = tokenizer.convert_tokens_to_ids(tokens)44 attention_mask = [1] * len(input_ids)45 46 # パディング47 padding_length = max_length - len(input_ids)48 input_ids += [tokenizer.pad_token_id] * padding_length 49 attention_mask += [0] * padding_length 50 51 return input_ids, attention_mask 52 53# 感情極性54# label=感情極性(0:強いネガティブ、1:ネガティブ、2:ニュートラル、3:ポジティブ、4:強いポジティブ)55train_df['label'].value_counts()56 57!pip install transformers 58!pip install datasets 59 60# DatasetDict型に変換する(参考:https://dev.classmethod.jp/articles/huggingface-usage-dataset/)61# "Hugging Face"で使われているデータ型と同じにするため62import datasets 63from datasets import Dataset 64 65train_dataset = Dataset.from_dict(train_df)66validation_dataset = Dataset.from_dict(validation_df)67test_dataset = Dataset.from_dict(test_df)68dataset = datasets.DatasetDict({"train":train_dataset,"validation":validation_dataset,"test":test_dataset})69dataset 70 71 72# ClassLabelクラスに変換73from datasets import ClassLabel 74class_label = ClassLabel(num_classes=5, names=['high_negative', 'negative', 'nutral', 'positive', 'high_positive'])75dataset = dataset.cast_column("label", class_label)76dataset['train'].features 77 78# トークナイザを呼び出す79from transformers import AutoTokenizer 80model_ckpt = "cl-tohoku/bert-base-japanese-whole-word-masking" # 東北大のBERTを使う81tokenizer = AutoTokenizer.from_pretrained(model_ckpt)82 83# テキストデータのHead-Tailを適用84train_df['input_ids'], train_df['attention_mask'] = zip(*train_df['text'].apply(lambda x: head_tail_tokenize(x, tokenizer, tokenizer.model_max_length)))85validation_df['input_ids'], validation_df['attention_mask'] = zip(*validation_df['text'].apply(lambda x: head_tail_tokenize(x, tokenizer, tokenizer.model_max_length)))86test_df['input_ids'], test_df['attention_mask'] = zip(*test_df['text'].apply(lambda x: head_tail_tokenize(x, tokenizer, tokenizer.model_max_length)))87 88# モデルが対応する最大コンテキストサイズ89tokenizer.model_max_length 90 91# padding="max_length": バッチサイズが最大になるようにpaddingする処理92# 参考: https://moneyforward-dev.jp/entry/2021/10/05/transformers-tokenizer/93# truncation=True: 後段のモデルが対応する最大コンテキストサイズ以上を切り捨てる94def tokenize(batch):95 return tokenizer(batch["text"], truncation=True, max_length=tokenizer.model_max_length, padding="max_length")96 97# トークン化をデータセット全体に適用する98dataset_encoded = dataset.map(tokenize, batched=True, batch_size=None)99dataset_encoded 100 101sample_encoded = dataset_encoded["train"][2]102pd.DataFrame(103 [sample_encoded["input_ids"]104 , sample_encoded["attention_mask"]105 , tokenizer.convert_ids_to_tokens(sample_encoded["input_ids"])],106 ['input_ids', 'attention_mask', "tokens"]107).T 108 109import torch 110from transformers import AutoModelForSequenceClassification 111 112device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # デバイスを指定113num_labels = 5114 115# BERTのモデルを定義116model_ckpt = "cl-tohoku/bert-base-japanese-whole-word-masking" # 東北大のBERTを使う117model = AutoModelForSequenceClassification.from_pretrained(model_ckpt, num_labels=num_labels).to(device)118 119# 学習用のパラメータを設定120from transformers import TrainingArguments 121 122batch_size = 5123logging_steps = len(dataset_encoded["train"]) // batch_size 124model_name = "text-classification-bert_part1"125 126training_args = TrainingArguments(127 output_dir=model_name,128 num_train_epochs=2,129 learning_rate=2e-5,130 per_device_train_batch_size=batch_size,131 per_device_eval_batch_size=batch_size,132 weight_decay=0.01,133 evaluation_strategy="epoch",134 disable_tqdm=False,135 logging_steps=logging_steps,136 push_to_hub=False,137 log_level="error"138)139 140# 評価指標の定義141from sklearn.metrics import accuracy_score, f1_score 142 143def compute_metrics(pred):144 labels = pred.label_ids 145 preds = pred.predictions.argmax(-1)146 f1 = f1_score(labels, preds, average="weighted")147 acc = accuracy_score(labels, preds)148 return {"accuracy": acc, "f1": f1}149 150# BERTのファインチューニングを行う151from transformers import Trainer 152 153trainer = Trainer(154 model=model,155 args=training_args,156 compute_metrics=compute_metrics,157 train_dataset=dataset_encoded["train"],158 eval_dataset=dataset_encoded["validation"],159 tokenizer=tokenizer 160)161trainer.train()162 163# 学習済みモデルで推論する164preds_output = trainer.predict(dataset_encoded["validation"])165 166# 評価167y_preds = np.argmax(preds_output.predictions, axis=1)168y_valid = np.array(dataset_encoded["validation"]["label"])169score = accuracy_score(y_preds, y_valid)170print('正解率:{0:.4f}'.format(score))171score = f1_score(y_preds, y_valid, average='macro')172print('F値:{0:.4f}'.format(score))173 174# 混同行列で可視化175from sklearn.metrics import ConfusionMatrixDisplay, confusion_matrix 176 177y_preds = np.argmax(preds_output.predictions, axis=1)178y_valid = np.array(dataset_encoded["validation"]["label"])179labels = dataset_encoded["train"].features["label"].names 180 181def plot_confusion_matrix(y_preds, y_true, labels):182 cm = confusion_matrix(y_true, y_preds, normalize="true")183 fig, ax = plt.subplots(figsize=(6, 6))184 disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=labels)185 disp.plot(cmap="Blues", values_format=".2f", ax=ax, colorbar=False)186 plt.title("Normalized confusion matrix")187 plt.show()188 189plot_confusion_matrix(y_preds, y_valid, labels)190 191# ラベル情報の設定192id2label = {}193for i in range(dataset["train"].features["label"].num_classes):194 id2label[i] = dataset["train"].features["label"].int2str(i)195 196label2id = {}197for i in range(dataset["train"].features["label"].num_classes):198 label2id[dataset["train"].features["label"].int2str(i)] = i 199 200trainer.model.config.id2label = id2label 201trainer.model.config.label2id = label2id 202 203# モデルを保存する204trainer.save_model("model/text-classification-bert-part1")205 206# モデルをロードして推論207new_tokenizer = AutoTokenizer\ 208 .from_pretrained("model/text-classification-bert-part1")209 210new_model = (AutoModelForSequenceClassification 211 .from_pretrained("model/text-classification-bert-part1")212 .to(device))213 214# サンプルテキストで推論215inputs = new_tokenizer(dataset['train']['text'][0], return_tensors="pt")216 217new_model.eval()218 219with torch.no_grad():220 outputs = new_model(221 inputs["input_ids"].to(device),222 inputs["attention_mask"].to(device),223 )224outputs.logits 225 226# ロジットを推論ラベルに変換227y_preds = np.argmax(outputs.logits.to('cpu').detach().numpy().copy(), axis=1)228def id2label(x):229 return new_model.config.id2label[x]230y_dash = [id2label(x) for x in y_preds]231y_dash 232 233dataset['train']['label'][0]234 235### 試したこと236 237バッチサイズを小さくしたりはしたのですが、エラーは直らないままです。 238 239### 補足情報(FW/ツールのバージョンなど)240 241ここにより詳細な情報を記載してください。

コメントを投稿

0 コメント