Pendahuluan
BERT adalah model bahasa terlatih populer yang telah menunjukkan kesuksesan besar dalam tugas pemrosesan bahasa alami (NLP) seperti analisis sentimen, klasifikasi teks, dan menjawab pertanyaan. Namun, BERT hanya menerima teks sebagai input dan tidak dapat menggabungkan jenis data lain seperti data numerik dan kategorikal.
Keterbatasan ini dapat diatasi dengan menggabungkan data tabular ke dalam model BERT. Dengan cara ini, kita dapat menggunakan kemampuan pemrosesan bahasa yang kuat dari BERT bersama dengan data tabular untuk membuat model yang lebih kuat dan akurat.
Artikel ini akan menunjukkan bagaimana menggabungkan data tabular ke dalam model BERT dan melatihnya menggunakan Hugging Face Trainer.
Menggabungkan Data Tabular dengan Model BERT
Berikut adalah kode PyTorch langkah demi langkah untuk membuat model BERT kustom yang dapat menggabungkan data tabular (data numerik dan kategorikal) dan melatihnya menggunakan Hugging Face Trainer.
Langkah 1: Menyiapkan Data
Langkah pertama adalah menyiapkan data. Kita dapat menggunakan pandas untuk memuat data dari file CSV dan membaginya menjadi set pelatihan dan validasi. Kita akan menggunakan contoh file CSV sederhana yang berisi data numerik dan kategorikal:
import pandas as pd
from sklearn.model_selection import train_test_split
df = pd.read_csv('data.csv')
train_df, val_df = train_test_split(df, test_size=0.2, random_state=42)
Setelah kita memiliki data training dan validasi, kita perlu mengonversinya menjadi dataset PyTorch menggunakan kelas Dataset
. Kita akan membuat dataset kustom yang mewarisi kelas Dataset dan mengimplementasikan metode __len__
dan __getitem__
:
import torch
from torch.utils.data import Dataset
class CustomDataset(Dataset):
def __init__(self, data, tokenizer, max_length):
self.data = data
self.tokenizer = tokenizer
self.max_length = max_length
def __len__(self):
return len(self.data)
def __getitem__(self, index):
row = self.data.iloc[index]
text = row['text']
label = row['label']
numerical_data = torch.tensor(row[['num1', 'num2']].values, dtype=torch.float)
categorical_data = torch.tensor(row['cat'].values, dtype=torch.long)
encoding = self.tokenizer(text, padding='max_length', truncation=True, max_length=self.max_length, return_tensors='pt')
return {
'input_ids': encoding['input_ids'][0],
'attention_mask': encoding['attention_mask'][0],
'token_type_ids': encoding['token_type_ids'][0],
'numerical_data': numerical_data,
'categorical_data': categorical_data,
'label': torch.tensor(label, dtype=torch.long)
}
Dalam contoh ini, kita memuat setiap baris dari frame data dan mengekstrak teks, label, data numerik (num1 dan num2), dan data kategori (cat). Kemudian kita menggunakan tokenizer untuk mengodekan teks dan mengembalikan kamus yang berisi input ID, attention mask, token type ID, data numerik, data kategori, dan label.
Langkah 2: Tentukan Model
Langkah selanjutnya adalah menentukan model. Kita akan menggunakan model Hugging Face BertForSequenceClassification
sebagai dasar dan menambahkan dua layer input tambahan untuk data numerik dan kategori:
from transformers import BertForSequenceClassification, BertConfig
import torch.nn as nn
class CustomModel(nn.Module):
def __init__(self, num_numerical_features, num_categorical_features, num_labels):
super().__init__()
config = BertConfig.from_pretrained('bert-base-uncased')
self.bert = BertForSequenceClassification(config)
self.numerical_layer = nn.Linear(num_numerical_features, 64)
self.categorical_layer = nn.Embedding(num_categorical_features, 16)
self.classifier = nn.Linear(768+64+16, num_labels)
def forward(self, input_ids, attention_mask, token_type_ids, numerical_data, categorical_data):
bert_output = self.bert(input_ids=input_ids, attention_mask=attention_mask, token_type_ids=token_type_ids).last_hidden_state[:, 0]
numerical_output = self.numerical_layer(numerical_data)
categorical_output = self.categorical_layer(categorical_data).mean(dim=1)
x = torch.cat((bert_output, numerical_output, categorical_output), dim=1)
logits = self.classifier(x)
return logits
Pada contoh ini, kita mendefinisikan model kustom yang mewarisi dari kelas PyTorch nn.Module
. Model ini memiliki tiga layer: layer BERT, layer numerik yang menerima data numerik dan mengeluarkan vektor 64-dimensi, dan layer kategorikal yang menerima data kategorikal dan mengeluarkan vektor 16-dimensi. Kemudian, kita menggabungkan keluaran dari layer-layer ini dengan keluaran BERT dan melewatinya melalui sebuah layer linear untuk mendapatkan logits.
Langkah 3: Melatih Model
Langkah terakhir adalah melatih model menggunakan Hugging Face Trainer. Kita akan menggunakan optimizer AdamW dan fungsi kerugian cross-entropy. Kita juga akan mendefinisikan metrik kustom yang menghitung akurasi:
from transformers import BertTokenizer
from sklearn.metrics import accuracy_score
from transformers import AdamW
from transformers import get_scheduler
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
train_dataset = CustomDataset(train_df, tokenizer, max_length=128)
val_dataset = CustomDataset(val_df, tokenizer, max_length=128)
device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
model = CustomModel(num_numerical_features=2, num_categorical_features=4, num_labels=2).to(device)
optimizer = AdamW(model.parameters(), lr=5e-5)
scheduler = get_scheduler("linear", optimizer, num_warmup_steps=0, num_training_steps=len(train_dataset)*5)
def compute_accuracy(pred):
labels = pred.label_ids
preds = pred.predictions.argmax(-1)
return accuracy_score(labels, preds)
from transformers import Trainer, TrainingArguments
training_args = TrainingArguments(
output_dir='./results',
num_train_epochs=5,
per_device_train_batch_size=16,
per_device_eval_batch_size=64,
warmup_steps=500,
weight_decay=0.01,
logging_dir='./logs',
logging_steps=10,
evaluation_strategy='epoch',
save_strategy='epoch',
learning_rate=5e-5,
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=val_dataset,
compute_metrics=compute_accuracy,
optimizer=optimizer,
scheduler=scheduler,
)
trainer.train()
Pada contoh ini, pertama-tama kita membuat tokenizer dan dataset, dan memindahkan model ke GPU jika tersedia. Kemudian kita membuat optimizer, scheduler, dan metrik kustom. Akhirnya, kita membuat objek Trainer
dan memanggil metode train
.
Referensi