how to build own transformer model from tabular data with pyTorch The target column of tabular dataset is category type The feature columns of tabular dataset were numerical or text type I want to out
Here is a sample code for building a transformer model from tabular data with PyTorch:
import torch
import torch.nn as nn
import torch.optim as optim
import torchtext
from torchtext.datasets import TabularDataset
from torchtext.data import Field, LabelField, BucketIterator
# Define the fields for the tabular dataset
text_field = Field(sequential=True, use_vocab=True, tokenize='spacy', lower=True)
numeric_field = Field(sequential=False, use_vocab=False)
label_field = LabelField()
# Load the tabular dataset
train_data, valid_data, test_data = TabularDataset.splits(
path='data',
train='train.csv',
validation='valid.csv',
test='test.csv',
format='csv',
fields=[('text', text_field), ('numeric', numeric_field), ('label', label_field)]
)
# Build the vocabulary
text_field.build_vocab(train_data, max_size=10000, vectors='glove.6B.100d', unk_init=torch.Tensor.normal_)
label_field.build_vocab(train_data)
# Set the device
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# Define the transformer model
class TransformerModel(nn.Module):
def __init__(self, num_classes, d_model, nhead, num_layers, dropout):
super().__init__()
self.transformer_encoder = nn.TransformerEncoder(
nn.TransformerEncoderLayer(d_model=d_model, nhead=nhead, dropout=dropout),
num_layers=num_layers
)
self.fc = nn.Linear(d_model, num_classes)
def forward(self, text, numeric):
src_padding_mask = (text == text_field.vocab.stoi[text_field.pad_token]).transpose(0, 1)
src_key_padding_mask = (text == text_field.vocab.stoi[text_field.pad_token]).transpose(0, 1)
src = torch.cat((text, numeric.unsqueeze(0).repeat(text.size(0), 1, 1)), dim=2)
src = src.transpose(0, 1)
output = self.transformer_encoder(src, src_key_padding_mask=src_key_padding_mask, src_padding_mask=src_padding_mask)
output = output.mean(dim=0)
output = self.fc(output)
return output
# Initialize the model
model = TransformerModel(num_classes=len(label_field.vocab), d_model=128, nhead=8, num_layers=3, dropout=0.1).to(device)
# Define the loss function and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=1e-4)
# Define the batch iterator
train_iter, valid_iter, test_iter = BucketIterator.splits(
datasets=(train_data, valid_data, test_data),
batch_sizes=(32, 32, 32),
sort_key=lambda x: len(x.text),
sort_within_batch=True,
device=device
)
# Define the training function
def train(model, iterator, optimizer, criterion):
epoch_loss = 0
epoch_acc = 0
model.train()
for batch in iterator:
optimizer.zero_grad()
text = batch.text
numeric = batch.numeric
label = batch.label
output = model(text, numeric)
loss = criterion(output, label)
acc = (output.argmax(dim=1) == label).float().mean()
loss.backward()
optimizer.step()
epoch_loss += loss.item()
epoch_acc += acc.item()
return epoch_loss / len(iterator), epoch_acc / len(iterator)
# Define the evaluation function
def evaluate(model, iterator, criterion):
epoch_loss = 0
epoch_acc = 0
model.eval()
with torch.no_grad():
for batch in iterator:
text = batch.text
numeric = batch.numeric
label = batch.label
output = model(text, numeric)
loss = criterion(output, label)
acc = (output.argmax(dim=1) == label).float().mean()
epoch_loss += loss.item()
epoch_acc += acc.item()
return epoch_loss / len(iterator), epoch_acc / len(iterator)
# Train the model
best_valid_loss = float('inf')
for epoch in range(10):
train_loss, train_acc = train(model, train_iter, optimizer, criterion)
valid_loss, valid_acc = evaluate(model, valid_iter, criterion)
if valid_loss < best_valid_loss:
best_valid_loss = valid_loss
torch.save(model.state_dict(), 'model.pt')
print(f'Epoch: {epoch+1}')
print(f'Train Loss: {train_loss:.3f} | Train Acc: {train_acc*100:.2f}%')
print(f'Valid Loss: {valid_loss:.3f} | Valid Acc: {valid_acc*100:.2f}%')
# Evaluate the model on the test set
model.load_state_dict(torch.load('model.pt'))
test_loss, test_acc = evaluate(model, test_iter, criterion)
print(f'Test Loss: {test_loss:.3f} | Test Acc: {test_acc*100:.2f}%')
# Make predictions on new data
def predict(model, text, numeric):
model.eval()
with torch.no_grad():
text = torch.tensor(text).unsqueeze(1).to(device)
numeric = torch.tensor(numeric).unsqueeze(0).repeat(text.size(0), 1).to(device)
output = model(text, numeric)
probabilities = nn.functional.softmax(output, dim=1)
_, predicted_label = torch.max(output.data, 1)
return predicted_label.item(), probabilities[0][predicted_label].item()
# Example usage
text = ['this is an example text']
numeric = [1, 2, 3, 4]
predicted_label, probability = predict(model, text, numeric)
print(f'Predicted Label: {label_field.vocab.itos[predicted_label]} | Probability: {probability:.2f}')
``
原文地址: https://www.cveoy.top/t/topic/d3Ii 著作权归作者所有。请勿转载和采集!