Document classification is a fundamental task in Natural Language Processing (NLP), where the goal is to categorize texts into predefined classes. With the rise of deep learning, models leveraging attention mechanisms, particularly the Hierarchical Attention Network (HAN), have gained popularity due to their ability to focus on important parts of a document, mimicking human-like reading habits.
In this article, we'll guide you step-by-step to train a document classification model using the Hierarchical Attention Model in PyTorch. This approach effectively processes document structures, considering word sequences and sentence hierarchical information.
Prerequisites
Before we start, ensure you have the following libraries installed:
pip install torch torchtextAdditionally, some familiarity with PyTorch and basic NLP concepts is recommended.
Data Preparation
Let's say we are working with news articles, and each article belongs to categories like Sports, Technology, Politics, etc. You will need data where each document is labeled with its category. For data processing, we can use torchtext for tokenization and batch generation.
from torchtext.datasets import AG_NEWS
from torchtext.data.utils import get_tokenizer
train_iter, test_iter = AG_NEWS(split=('train', 'test'))
tokenizer = get_tokenizer('basic_english')Convert your text into tensors using the vocabularies built from your tokenizer.
Model Structure
The Hierarchical Attention Model consists of several layers: a word encoder, a word-level attention layer, a sentence encoder, and a sentence-level attention layer.
1. Word Encoder
This layer embeds the words using an embedding layer or pre-trained embeddings such as GloVe.
from torch import nn
class WordEncoder(nn.Module):
def __init__(self, vocab_size, embed_size):
super(WordEncoder, self).__init__()
self.embedding = nn.Embedding(vocab_size, embed_size)
def forward(self, x):
return self.embedding(x)2. Word-Level Attention
This layer computes the attention scores and generates word-level context vectors.
class WordAttention(nn.Module):
def __init__(self, hidden_size):
super(WordAttention, self).__init__()
self.attention = nn.Sequential(
nn.Linear(hidden_size, 1),
nn.Softmax(dim=-1)
)
def forward(self, lstm_output):
att_weights = self.attention(lstm_output)
weighted_output = lstm_output * att_weights
return weighted_output.sum(1), att_weights3. Sentence Encoder & Attention
This is structurally similar to the word layers but operates at the sentence level.
Training the Model
With our data and model formats ready, we move on to training. Define a loss function like CrossEntropyLoss for classification tasks and an optimizer like Adam.
from torch.optim import Adam
model = HierarchicalAttentionNetwork(vocab_size, embed_size)
criterion = nn.CrossEntropyLoss()
optimizer = Adam(model.parameters(), lr=0.001)Loop through epochs, passing the data through your model, calculate loss, and update the weights.
for epoch in range(num_epochs):
for batch in train_iter:
# Forward Pass
outputs = model(batch.text)
loss = criterion(outputs, batch.label)
# Backward Pass
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')Evaluation and Conclusion
Evaluate the model using test datasets to gauge its performance. Remember to calculate accuracy, precision, and recall to get a detailed understanding.
# Example evaluation snippet
def evaluate(model, test_loader):
correct = 0
total = 0
with torch.no_grad():
for data in test_loader:
texts, labels = data
outputs = model(texts)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
return 100 * correct / totalWith attention mechanisms taking the NLP field forward, utilizing hierarchical attention for document classification provides an intricate means to capture the nuances of language structure, significantly improving over traditional models.