Неделя 9: Трансформеры и механизм внимания
1. Теоретическая часть
1.1. Архитектура трансформеров
Трансформеры — революционная архитектура (Vaswani et al., 2017), основанная на механизме внимания без рекуррентных связей.
Ключевые компоненты
Компонент
Назначение
Self-Attention
Вычисление взаимного влияния элементов последовательности
Multi-Head Attention
Параллельные механизмы внимания для разных представлений
Positional Encoding
Учет порядка элементов в последовательности
Feed Forward Networks
Поэлементные преобразования
Формула внимания
Attention(𝑄,𝐾,𝑉)=softmax(𝑄𝐾𝑇𝑑𝑘)𝑉Attention(Q,K,V)=softmax(dkQKT)V
1.2. Преимущества трансформеров
Параллелизация вычислений (в отличие от RNN)
Учет длинных зависимостей
Высокая адаптивность (BERT, GPT, ViT)
1.3. Применение трансформеров
Обработка естественного языка (перевод, классификация)
Компьютерное зрение (Vision Transformers)
Генерация данных
2.1. Реализация Self-Attention
python
Copy
import torch
import torch.nn as nn
import math
class SelfAttention(nn.Module):
def __init__(self, embed_size, heads):
super(SelfAttention, self).__init__()
self.embed_size = embed_size
self.heads = heads
self.head_dim = embed_size // heads
assert self.head_dim * heads == embed_size, "Embed size needs to be divisible by heads"
self.values = nn.Linear(self.head_dim, self.head_dim, bias=False)
self.keys = nn.Linear(self.head_dim, self.head_dim, bias=False)
self.queries = nn.Linear(self.head_dim, self.head_dim, bias=False)
self.fc_out = nn.Linear(heads * self.head_dim, embed_size)
def forward(self, values, keys, queries, mask):
N = queries.shape[0]
value_len, key_len, query_len = values.shape[1], keys.shape[1], queries.shape[1]
# Split embedding into self.heads pieces
values = values.reshape(N, value_len, self.heads, self.head_dim)
keys = keys.reshape(N, key_len, self.heads, self.head_dim)
queries = queries.reshape(N, query_len, self.heads, self.head_dim)
energy = torch.einsum("nqhd,nkhd->nhqk", [queries, keys])
if mask is not None:
energy = energy.masked_fill(mask == 0, float("-1e20"))
attention = torch.softmax(energy / (self.embed_size ** (0.5)), dim=3)
out = torch.einsum("nhql,nlhd->nqhd", [attention, values]).reshape(
N, query_len, self.heads * self.head_dim
)
out = self.fc_out(out)
return out
2.2. Трансформер для классификации текста
python
Copy
class TransformerBlock(nn.Module):
def __init__(self, embed_size, heads, dropout, forward_expansion):
super(TransformerBlock, self).__init__()
self.attention = SelfAttention(embed_size, heads)
self.norm1 = nn.LayerNorm(embed_size)
self.norm2 = nn.LayerNorm(embed_size)
self.feed_forward = nn.Sequential(
nn.Linear(embed_size, forward_expansion * embed_size),
nn.ReLU(),
nn.Linear(forward_expansion * embed_size, embed_size)
)
self.dropout = nn.Dropout(dropout)
def forward(self, value, key, query, mask):
attention = self.attention(value, key, query, mask)
x = self.dropout(self.norm1(attention + query))
forward = self.feed_forward(x)
out = self.dropout(self.norm2(forward + x))
return out
2.3. Использование Hugging Face Transformers
python
Copy
from transformers import BertTokenizer, BertForSequenceClassification
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForSequenceClassification.from_pretrained('bert-base-uncased')
inputs = tokenizer("Hello, world!", return_tensors="pt")
outputs = model(**inputs)
predictions = torch.argmax(outputs.logits, dim=1)
3. Домашнее задание
Задача 1: Реализация Positional Encoding
1. Реализуйте синусоидальное позиционное кодирование для трансформера.
2. Визуализируйте кодировки для разных позиций.
Решение:
python
Copy
class PositionalEncoding(nn.Module):
def __init__(self, embed_size, max_len=5000):
super(PositionalEncoding, self).__init__()
pe = torch.zeros(max_len, embed_size)
position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
div_term = torch.exp(torch.arange(0, embed_size, 2).float() * (-math.log(10000.0) / embed_size))
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
pe = pe.unsqueeze(0)
self.register_buffer('pe', pe)
def forward(self, x):
return x + self.pe[:, :x.shape[1]]
Задача 2: Трансформер для машинного перевода
1. Реализуйте encoder-decoder архитектуру на основе трансформера.
2. Обучите на датасете для перевода (например, English-German).
Решение:
python
Copy
class Transformer(nn.Module):
def __init__(self, src_vocab_size, trg_vocab_size, src_pad_idx, trg_pad_idx, embed_size=256, num_layers=6, forward_expansion=4, heads=8, dropout=0.1, max_len=100):
super(Transformer, self).__init__()
self.encoder = Encoder(src_vocab_size, embed_size, num_layers, heads, forward_expansion, dropout, max_len)
self.decoder = Decoder(trg_vocab_size, embed_size, num_layers, heads, forward_expansion, dropout, max_len)
self.src_pad_idx = src_pad_idx
self.trg_pad_idx = trg_pad_idx
def make_src_mask(self, src):
src_mask = (src != self.src_pad_idx).unsqueeze(1).unsqueeze(2)
return src_mask
def make_trg_mask(self, trg):
N, trg_len = trg.shape
trg_mask = torch.tril(torch.ones((trg_len, trg_len))).expand(N, 1, trg_len, trg_len)
return trg_mask
def forward(self, src, trg):
src_mask = self.make_src_mask(src)
trg_mask = self.make_trg_mask(trg)
enc_src = self.encoder(src, src_mask)
out = self.decoder(trg, enc_src, src_mask, trg_mask)
return out
Задача 3: Fine-tuning BERT
1. Загрузите предобученный BERT через Hugging Face.
2. Дообучите для анализа тональности на датасете IMDB.
Решение:
python
Copy
from transformers import BertTokenizer, BertForSequenceClassification, AdamW
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)
optimizer = AdamW(model.parameters(), lr=2e-5)
# Пример обучения
for batch in train_loader:
inputs = tokenizer(batch['text'], padding=True, truncation=True, return_tensors="pt")
outputs = model(**inputs, labels=batch['label'])
loss = outputs.loss
loss.backward()
optimizer.step()
optimizer.zero_grad()
Итоги недели
✅ Изучили архитектуру трансформеров и механизм внимания.
✅ Реализовали Self-Attention и Positional Encoding.
✅ Научились использовать Hugging Face Transformers.
✅ Применили трансформеры для NLP-задач.
Следующая тема: Генеративные модели (GAN, VAE). 🎨