์์ฐ์ด ์ถ๋ก ์ชฝ์ ์ฐ๊ตฌํ๋ฉด์, ์งํ์ค์ธ ์คํ์ด ๋งํ์ ์ ๊น ํ๊ธฐ์ํฌ๊ฒธ ์์ฐ์ด ๋ํ๋ฅผ ์ฐพ์๋ดค์๋ค.
์บ๊ธ์์ ์งํ์ค์ธ XNLI ๋ํ, ํ๊ตญ DACON์์ ์งํํ๋ ํ์ ๋ถ๋ฅ ๋ํ ๋๊ฐ์ง๋ฅผ ์ฐพ์์ ์ด๋ฅผ ์งํํด ๋ณด์๋ค.
์ผ๋จ ์ด ๋ํ๋ฅผ ์ฐพ์์ ๋น์์ ๋ง๊ฐ์ด D-1์ด๋ผ ๋ค๋ฅธ ๊ธฐ๋ฒ์ ์ฌ์ฉํ์ง๋ ๋ชปํ๊ณ , ๋น ๋ฅด๊ฒ ์ ์ถํ๊ธฐ ์ํ ๋ฒ ์ด์ค๋ชจ๋ธ๋ง ์ฌ์ฉํ์ฌ ๋ํ์ ์ฐธ๊ฐํ์๋ค.
๋ํ ์ฐธ์ฌ ์ธ์์ 549๋ช ์ ๋์๊ณ , 1๋ฑ์ ์ ์๋ 0.71312 ์๋ค.
๊ทธ๋ฆฌ๊ณ ํ๋ฃจ ํฌ์ํด์ ์ ์ถํ ๋ด ์ ์๋ 0.68888๋ก, 1๋ฑ๊ณผ์ ์ ํ๋ ์ฐจ์ด๊ฐ 0.02432(์ฝ 2.4%) ์ฐจ์ด์๋ค.
๋ฒ ์ด์ง ๋ํ์ธ๋ฐ ํ10๋ ๋ชปํด์ ํํ๊ฐ ์ค๊ธด ํ์ง๋ง, ๊ทธ๋๋ ๋น ๋ฅด๊ฒ ์ ์ถํ ์ ์๋ค๋ ๊ฑฐ์ ์์๋ฅผ ๋์๋ค.
์ฒ์์๋ ์ผ๋จ ํ๊ตญ์ด ์ปค์คํ ํ ํฌ๋์ด์ ๋ฅผ ๋ง๋ค์ด์ ์ฌ์ฉํ๊ธฐ๋ก ํ์์ผ๋, ์คํจํด๋ฒ๋ ค์ 3์๊ฐ์ ๋ ๋ ธ๋ค.
class tokenizer_class() :
def csv_to_text(self) :
data = pd.read_csv("dataset/train.csv")
train_pair = [(row[1], row[2]) for _, row in data.iterrows() if type(row[1]) == str] # nan ์ ๊ฑฐ
# ๋ฌธ์ฅ ๋ฐ ๋ผ๋ฒจ ๋ฐ์ดํฐ ์ถ์ถ
train_data = [pair[0] for pair in train_pair]
train_label = [pair[1] for pair in train_pair]
print('๋ฌธ์ฅ: %s' %(train_data[:3]))
print('๋ผ๋ฒจ: %s' %(train_label[:3]))
# subword ํ์ต์ ์ํด ๋ฌธ์ฅ๋ง ๋ฐ๋ก ์ ์ฅ
with open('train_tokenizer.txt', 'w', encoding='utf-8') as f:
for line in train_data:
f.write(line+'\n')
# subword ํ์ต์ ์ํด ๋ฌธ์ฅ๋ง ๋ฐ๋ก ์ ์ฅ
with open('train_tokenizer.txt', 'r', encoding='utf-8') as f:
test_tokenizer = f.read().split('\n')
print(test_tokenizer[:3])
num_word_list = [len(sentence.split()) for sentence in test_tokenizer]
print('\n์ฝํผ์ค ํ๊ท /์ด ๋จ์ด ๊ฐฏ์ : %.1f / %d' % (sum(num_word_list)/len(num_word_list), sum(num_word_list)))
return test_tokenizer
์ผ๋จ ๋ฐ์ดํฐ ์ ์์ ๋ฌธ์ฅ์ ๋ฝ๊ณ ๋ผ๋ฒจ์ ๋งค๊ธด ๋ค์์,
๊ฐ ๋ฌธ์ฅ์ ํ๊ท ๊ธธ์ด๋ฅผ ํ์ธํด๋ณด๊ณ , ์ด ๋จ์ด๊ฐ ๋ช๊ฐ ์๋์ง ํ์ธํ์๋ค.
๋ชจ๋ธ์ ๊ฒฐ์ ํ๊ณ ๋ชจ๋ธ์์ ์ฌ์ฉ๋ ๋ฐ์ดํฐ์ ์๋ธ์๋๋ถ๋ฆฌ ์๊ณ ๋ฆฌ์ฆ์ ๋ฐ๋ผ ์ฑํํ์ฌ์ผํ๋ค.
๊ทธ ๋ค๋ก Mecab์ ์ด์ฉํ์ฌ ํ ํฐํ๋ฅผ ์งํํ๋ ค ํ์๋๋ฐ,
Mecab์ ์๋์ฐ์์ ์๋์ผ๋ก ์ค์น๊ฐ ์๋์, ๋ฐ๋ก ์ค์ ํด์ฃผ์ด์ผ ํ๋ ๊ฒ์ด ๋ง๊ณ , ์ด ํ๊ฒฝ์ ๋ง๋๋๋ฐ์ ์๊ฐ๋ ์ข ๊ฑธ๋ฆด ๋ฏ ํด์ Okt ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ํ ํฐํ๋ฅผ ์งํํ์๋ค.
def Okt(self, data):
tokenizer = Okt()
print('Okt check :', tokenizer.morphs('์ด๋ฆด๋๋ณด๊ณ ์ง๊ธ๋ค์๋ด๋ ์ฌ๋ฐ์ด์ใ
ใ
'))
for_generation = False
# 1: '์ด๋ฆด๋' -> '์ด๋ฆด, ##๋
if for_generation:
total_morph = []
for sentence in data:
# ๋ฌธ์ฅ๋จ์ Okt ์ ์ฉ
morph_sentence = []
count = 0
for token_okt in tokenizer.morphs(sentence):
token_okt_save = token_okt
if count > 0:
token_okt_save = "##" + token_okt_save # ์์ ##๋ฅผ ๋ถ์น๋ค
morph_sentence.append(token_okt_save)
else:
morph_sentence.append(token_okt_save)
count += 1
total_morph.append(morph_sentence)
else:
# 2: '์ด๋ฆด๋' -> '์ด๋ฆด, ๋'
total_morph = []
for sentence in data:
morph_sentence = tokenizer.morphs(sentence)
total_morph.append(morph_sentence)
print(total_morph[:3])
print(len(total_morph))
# ex) 1 line: '์ด๋ฆด ๋ ๋ณด ๊ณ ์ง๊ธ ๋ค์ ๋ด๋ ์ฌ๋ฐ ์ด์ ใ
ใ
'
with open('after_okt.txt', 'w', encoding='utf-8') as f:
for line in total_morph:
f.write(' '.join(line) + '\n')
with open('after_okt.txt', 'r', encoding='utf-8') as f:
test_tokenizer = f.read().split('\n')
return test_tokenizer
def train_tokenizer(self, tokenizer) :
corpus_file = ['after_okt.txt'] # data path
vocab_size = 32000
limit_alphabet = 6000 #merge ์ํ ์ initial tokens์ด ์ ์ง๋๋ ์ซ์ ์ ํ
# output_path = 'hugging_%d' % (vocab_size)
min_frequency = 2 # nํ ์ด์ ๋ฑ์ฅํ pair๋ง merge ์ํ
# Then train it!
tokenizer.train(files=corpus_file,
vocab_size=vocab_size,
min_frequency=min_frequency, # ๋จ์ด์ ์ต์ ๋ฐ์ ๋น๋, 5
limit_alphabet=limit_alphabet, # ByteLevelBPETokenizer ํ์ต์์ ์ฃผ์์ฒ๋ฆฌ ํ์
show_progress=True,
special_tokens=["<s>", "</s>", "<unk>", "<pad>", "<mask>"])
print('train complete')
sentence = '๋๋ ์ค๋ ์์นจ๋ฐฅ์ ๋จน์๋ค.'
output = tokenizer.encode(sentence)
print(sentence)
print(output)
# save tokenizer
hf_model_path = 'liky_tokenizer'
if not os.path.isdir(hf_model_path):
os.mkdir(hf_model_path)
tokenizer.save_model(hf_model_path)
return tokenizer
๊ทผ๋ฐ ์ด ํ ํฌ๋์ด์ ๋ฅผ ๋ง๋ค์๋๋ฐ ์ ๋๋ก ์๋ง๋ค์ด์ก๋ค.
์ปค์คํ ํ ํฌ๋์ด์ ์ ์์ ์๊ฐ ์ ๋ณด๋ฅํ๊ณ ๋์ค์ Mecab ํ๊ฒฝ์ ๋ค์ ๊ตฌ์ฑํด์ ๋ฐ๋ก ํ๊ธฐ๋กํ์๋ค.
์ผ๋จ ํ๊น ํ์ด์ค์ ์ฌ๋ผ์จ ํ๊ตญ์ด ํ ํฌ๋์ด์ ๋ฅผ ์ฌ์ฉํด์ ๋ฌธ์ ๋ฅผ ํ์ด๋ณด์๋ค.
from transformers import AlbertForSequenceClassification, AlbertConfig, AlbertTokenizer
from transformers import RobertaConfig, RobertaForSequenceClassification, RobertaTokenizer, DataCollatorWithPadding
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from sklearn.metrics import confusion_matrix
from sklearn.metrics import precision_score, recall_score, f1_score, accuracy_score, classification_report
from datasets import load_dataset, DatasetDict
from torch import nn
from torch.optim import Adam
from tqdm import tqdm
import torch
import matplotlib.pyplot as plt
from torch.utils.data import DataLoader
from transformers import AutoModelForSequenceClassification, AutoTokenizer
def train(train_dataloader,val_dataloader):
model = AutoModelForSequenceClassification.from_pretrained("klue/roberta-large", num_labels=6)
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
print(device)
len_train_data = 22500
len_val_data = 2500
model.to(device)
optimizer = Adam(model.parameters(), lr=1e-5)
top_val_loss = 100
top_val_accuracy = 0
train_loss_list =[]
val_loss_list = []
train_acc_list = []
val_acc_list = []
for epoch in range(20):
model.train()
total_acc_train = 0
total_loss_train = 0
now_data_len = 0
train_dataloader = tqdm(train_dataloader, desc='Loading train dataset')
for i, batch in enumerate(train_dataloader):
optimizer.zero_grad()
batch = {k: v.to(device) for k, v in batch.items()}
output = model(input_ids=batch["input_ids"],
token_type_ids=batch['token_type_ids'],
attention_mask=batch['attention_mask'],
labels=batch['labels'])
#batch_loss = lossfunction(output.logits, batch['labels'])
output.loss.backward()
optimizer.step()
predict = torch.argmax(output.logits, dim=-1)
total_loss_train = total_loss_train + output.loss.item()
acc = (predict == batch['labels']).sum().item()
total_acc_train += acc
now_data_len += len(batch['labels'])
train_dataloader.set_description("Loss %.04f Acc %.04f | step %d Epoch %d" % (output.loss, total_acc_train / now_data_len, i,epoch))
total_acc_val = 0
total_loss_val = 0
with torch.no_grad():
model.eval()
for batch in tqdm(val_dataloader):
batch = {k: v.to(device) for k, v in batch.items()}
output = model(**batch)
predict = torch.argmax(output.logits, dim=-1)
acc = (predict == batch['labels']).sum().item()
#batch_loss = lossfunction(output.logits, batch['labels'])
total_loss_val += output.loss.item()
total_acc_val += acc
print()
print(f'Epochs: {epoch + 1} \n'
f'| Train Loss: {total_loss_train / len_train_data: .3f} \n'
f'| Train Accuracy: {total_acc_train / len_train_data: .3f} \n'
f'| Val Loss: {total_loss_val /len_val_data: .3f} \n'
f'| Val Accuracy: {total_acc_val / len_val_data: .3f}')
train_acc_list.append(total_acc_train / len_train_data)
train_loss_list.append(total_loss_train / len_train_data)
val_acc_list.append(total_acc_val / len_val_data)
val_loss_list.append(total_loss_val /len_val_data)
# if total_loss_val > top_val_loss and total_acc_val < top_val_accuracy :
#
# break
# if total_loss_val < top_val_loss:
# top_val_loss = total_loss_val
# if total_acc_val > top_val_accuracy:
# top_val_accuracy = total_acc_val
model_path = "./model" + str(epoch) + ".pth"
model.save_pretrained(model_path)
return model, train_acc_list, train_loss_list, val_acc_list, val_loss_list
def data() :
data = pd.read_csv("./dataset/train.csv")
data['target'].unique() # 1,2,4,5 ๋ง ์์.
raw_train = load_dataset('csv', data_files='./dataset/train.csv')
raw_test = load_dataset('csv', data_files='./dataset/test.csv')
train, valid = raw_train['train'].train_test_split(test_size=0.1).values()
review_dataset = DatasetDict({'train': train, 'valid': valid, 'test': raw_test['train']})
def tokenize_function(example):
return tokenizer(example["reviews"], truncation=True)
tokenized_datasets = review_dataset.map(tokenize_function, batched=True)
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
tokenized_datasets = tokenized_datasets.remove_columns(["id", "reviews"])
tokenized_datasets['train'] = tokenized_datasets['train'].rename_column("target", "labels")
tokenized_datasets['valid'] = tokenized_datasets['valid'].rename_column("target", "labels")
tokenized_datasets.set_format("torch")
train_dataloader = DataLoader(tokenized_datasets["train"], shuffle=True, batch_size=8, collate_fn=data_collator)
val_dataloader = DataLoader(tokenized_datasets["valid"], shuffle=True, batch_size=8, collate_fn=data_collator)
test_dataloader = DataLoader(tokenized_datasets["test"], shuffle=False, batch_size=8, collate_fn=data_collator)
return train_dataloader, val_dataloader, test_dataloader
def final_test(model, test_dataloader):
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
model.to(device)
prediction_list = []
label_list = []
model.eval()
with torch.no_grad():
for batch in tqdm(test_dataloader):
outputs = model(**batch.to(device))
logits = outputs.logits
predictions = torch.argmax(logits, dim=-1)
prediction_list.extend(predictions.cpu().tolist())
submission = pd.read_csv("dataset/sample_submission.csv")
submission["target"] = prediction_list
submission.to_csv("submission.csv",index=False)
return prediction_list
def confusion(prediction_list) :
# ํผ๋ํ๋ ฌ
my_data = []
y_pred_list = []
for data in prediction_list :
for data2 in data :
my_data.append(data2.item())
for data in label_list :
for data2 in data :
y_pred_list.append(data2.item())
confusion_matrix(my_data, y_pred_list)
confusion_mx = pd.DataFrame(confusion_matrix(y_pred_list, my_data))
ax =sns.heatmap(confusion_mx, annot=True, fmt='g')
plt.title('confusion', fontsize=20)
plt.show()
print(f"precision : {precision_score(my_data, y_pred_list, average='macro')}")
print(f"recall : {recall_score(my_data, y_pred_list, average='macro')}")
print(f"f1 score : {f1_score(my_data, y_pred_list, average='macro')}")
print(f"accuracy : {accuracy_score(my_data, y_pred_list)}")
f1_score_detail= classification_report(my_data, y_pred_list, digits=3)
print(f1_score_detail)
def result_graph(train_acc_list, train_loss_list, val_acc_list, val_loss_list):
epochs = [x for x in range(len(train_loss_list))]
print(epochs)
plt.plot(epochs, train_loss_list, 'r', label='Training loss')
epochs = [x for x in range(len(val_loss_list))]
plt.plot(epochs, val_loss_list, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
epochs = [x for x in range(len(train_acc_list))]
plt.plot(epochs, train_acc_list, 'r', label='Training Accuracy')
epochs = [x for x in range(len(val_acc_list))]
plt.plot(epochs, val_acc_list, 'b', label='Validation Accuracy')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()
if __name__ == "__main__":
tokenizer = AutoTokenizer.from_pretrained("klue/roberta-large")
train_dataloader, val_dataloader, test_dataloader = data()
model, train_acc_list, train_loss_list, val_acc_list, val_loss_list = train(train_dataloader, val_dataloader)
result_graph(train_acc_list, train_loss_list, val_acc_list, val_loss_list)
predict_list, label_list = final_test(model, test_dataloader)
submission = pd.read_csv("dataset/sample_submission.csv")
submission["target"] = predict_list
submission.to_csv("submission.csv",index=False)
#%% ์ ์ฅ๋ ๋ชจ๋ธ ์ฌ์ฉํด์ ๋ค์ ํ
์คํธ
model = AutoModelForSequenceClassification.from_pretrained("model19.pth")
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
model.to(device)
prediction_list = []
label_list = []
model.eval()
with torch.no_grad():
for batch in tqdm(test_dataloader):
outputs = model(**batch.to(device))
logits = outputs.logits
predictions = torch.argmax(logits, dim=-1)
prediction_list.extend(predictions.cpu().tolist())
submission = pd.read_csv("dataset/sample_submission.csv")
submission["target"] = prediction_list
submission.to_csv("submission3.csv",index=False)
ํ๊น ํ์ด์ค์ ์ฌ๋ผ์จ "klue/roberta-large"๋ฅผ ์ฌ์ฉํ์ฌ ํ ํฌ๋์ด์ ์ ๋ชจ๋ธ์ ๊ฐ์ง๊ณ ์์ ํ์ต์ ์งํํ์๋ค.
์ฒ์์ ํ์ต ์กฐ๊ธฐ ์ข ๋ฃ ์๊ณ ๋ฆฌ์ฆ์ ์์ฑํ์ฌ ๋ชจ๋ธ์ ํ์ต์ํค๋ ค๋ค๊ฐ, ์ ์ถ ๊ธฐํ ์๊ฐ๋ด์ ๋ค์ ์คํ์ ์งํํ๊ธฐ์ ์ด๋ ค์์ด ์์ ๊ฒ ๊ฐ์์ Epoch๋งํผ ์ญ ํ์ต์ํค๊ณ ๊ฐ๊ฐ์ ํ์ต ๋ชจ๋ธ๋ค์ ์ ์ฅํ์๋ค.
๊ทธ๋ฐ ๋ค์ Validation loss์ accuracy๊ฐ ๊ฐ์ฅ ๋์ ๋ชจ๋ธ์ ๋ถ๋ฌ์์ Test ๋ฐ์ดํฐ์ ์ Prediction ํ์๋ค.
์ฝ๋๋ฅผ ์ค๊ฐ์ค๊ฐ์ ๋ณด๊ณ ์ง์ฐ๊ณ ์ฃผ์์ฒ๋ฆฌํ๊ณ ํด์ ๊ผฌ์ด๊ธด ํ๋๋ฐ, ์ ์ฒด ์ฝ๋์ด๋ค.
๊ฐ๋จํ๊ฒ ์ ์ฒ๋ฆฌํ๊ณ , ํ ํฐํ ์ํจ ๋ค์์ Roberta ๋ชจ๋ธ์์ ๋ถ๋ฅ๋ฅผ ์ํ ์ธต์ ์นํ ๋ค์์, loss๊ฐ ๊ตฌํ๋ฉด์ ํ์ต์ ์งํํ๋ค. num_label์ด 6์ธ ์ด์ ๋, ๋ฐ์ดํฐ์ ์ ์๋ ๋ผ๋ฒจ๊ฐ์ ์ถ๋ ฅํด๋ณด๋ 1,2,4,5 ์ ๋ง ์์ด์ 6์ผ๋ก ์ค์ ํด์ ํ์ตํ์๋ค.
์ด๋ฐ์์ผ๋ก ํ์ต ๊ณผ์ ์ ๋ณด๋ฉด์, ์ํฌํฌ๊ฐ ๋๋ ๋ ๋ง๋ค ์๋์ ๊ฐ์ด ํ๋ฅผ ์ถ๋ ฅํ์๋ค.
์๋๋ ๊ทธ๋ํ๋ก ๋์์ ๊ทธ๊ฑฐ๋ณด๊ณ ์ต์ข ๋ชจ๋ธ์ ์ฑํํ๋๋ฐ, ๊ทธ๋ํ๋ฅผ ์ ์ฅ ์ํด์ ๋ ๋ผ๊ฐ๋ค.
์ด์จ๋ ๊ทธ๊ฑธ ๊ธฐ๋ฐ์ผ๋ก ์คํํ ๊ฒฐ๊ณผ ์ ์ถํ๋
์ด๋ฐ์์ผ๋ก ๋์์ ์ ์ถํ๊ณ ๋ฆฌ๋๋ณด๋์ ์ฌ๋ผ๊ฐ๋ค.
์ ์ถ๊ณผ ๋์์ ๋ํ๊ฐ ๋๋๊ฐ์ ์ฌ๋๋ค์ด ์ฝ๋ ๊ณต์ ๋ฅผ ์์ํ์๋ค.
1๋ฑ์ฝ๋๋ถํฐ ๋ณด๋๋ฐ Voting ์๊ณ ๋ฆฌ์ฆ๋ถํฐ ์ฃ๋ค ์์๋ธํด์ ํ๊ณ , ๋ฐ์ดํฐ์ ๋ ๋ถ์ ๋นก์ธ๊ฒ ํด์ ๋ง์ ๋์์ด ๋์๋ค.
๋ํ๋ฅผ ํตํด ๋๋์
1. ๋ ์ฐ๋ ๊ธฐ๋ค. ์์ฐ์ด ํ๋ค๋ฉด์ top3๋ ๋ฌด์จ top10๋ ๋ชปํ๋
2. ๊ทธ๋๋ ํ๋ฃจ๋ง์ ์ฝ๋ ์์ฑํด์ ์ ์ถํ ์ ๋๋ ๋๋๊ตฌ๋
3. ์ ํ๋ 3%์ฌ๋ฆด๋ ค๊ณ ์ฌ๋๋ค์ ์ฌ๋ฌ ๊ธฐ๋ฒ๋ค์ ์ถ๊ฐํด์ ์คํํ๊ตฌ๋.
4. ํ์ฝ๋ ๋ณด๋ฉด์, ์ฐ๊ตฌํ๋๋ฐ์ ์์ด๋์ด๋ ์ป๊ณ ๋์์ด ๋์๋ค.
4-1 ex. ํธ๋์คํฌ๋จธ ๋ชจ๋ธ์ ๋ง์ง๋ง ๋ ์ด์ด์ self explaining์ ์ํ ์ธต์ ์ถ๊ฐํ์ฌ ๊ฐ ๊ฐ์ด์ feature๊ฐ์ ๋ฝ๊ณ ,,,,, k-fold๋ฅผ ์ด์ฉํด์ ํ์ต์ ์งํํ๋๋ฐ.... ๋ชจ๋ธ์ ensembleํด์ ํ๊ฑฐ๊ณ ... voting ์๊ณ ๋ฆฌ์ฆ์ ์ถ๊ฐํ์ฌ ์คํ์ ์งํํ๋ฉด ์ฑ๋ฅํฅ์์ด ... ๋ฑ๋ฑ
์๋๋ ์ถ๊ฐ์ ์ธ ์ฝ๋
k_folds = 5
data_size = len(df)
fold_size = data_size // k_folds
for fold in range(k_folds):
print(f"Training on Fold {fold + 1}")
val_start_idx = fold * fold_size
val_end_idx = min((fold + 1) * fold_size, data_size) #์ธ๋ฑ์ค์ด๊ณผ๋ฐฉ์ง
val_data = df.iloc[val_start_idx:val_end_idx].reset_index(drop=True)
train_data = pd.concat([df.iloc[:val_start_idx], df.iloc[val_end_idx:]]).reset_index(drop=True)
if acc_top < accuracy_score(prediction_list, label_list):
if os.path.exists(f"{acc_top:.5f}.pth"):
os.remove(f"{acc_top:.5f}.pth")
acc_top = accuracy_score(prediction_list, label_list)
torch.save(model.state_dict(),
f"{accuracy_score(prediction_list, label_list):.5f}.pth")