Введение в PyTorch
PyTorch — это библиотека для языка Python с открытым исходным кодом, созданная на базе Torch для машинного обучения. Она разрабатывается преимущественно группой искусственного интеллекта Facebook (Meta*).
PyTorch отличается своим подходом к построению динамических вычислительных графов, что делает его особенно удобным для исследователей в области глубокого обучения.
Ключевые особенности PyTorch:
- Динамический вычислительный граф
- Императивный стиль программирования
- Простая интеграция с Python экосистемой
- Поддержка GPU через CUDA
- Автоматическое дифференцирование
Основная формула PyTorch
PyTorch = NumPy + CUDA + Автоматическое дифференцирование
Это означает, что PyTorch сочетает в себе знакомый интерфейс работы с многомерными массивами (как в NumPy), возможность использования графических процессоров через CUDA и механизм автоматического вычисления градиентов, необходимый для обучения нейронных сетей.
Место среди других фреймворков
Схематичное изображение трёх основных категорий фреймворков глубокого обучения
PyTorch относится к фреймворкам с динамическим вычислительным графом, что отличает его от TensorFlow и других библиотек со статическим графом.
Фиксированные модули
Подобно Lego: пользователь комбинирует заранее определённые блоки. Низкая расширяемость, но высокая скорость разработки.
Примеры: Caffe, CNTK, Keras
Статический граф
Как полимерная глина: после «запекания» (компиляции) граф становится фиксированным. Компромисс между гибкостью и скоростью.
Примеры: TensorFlow, Theano, MXNet
Динамический граф
Граф строится динамически при каждом запуске. Максимальная гибкость и расширяемость, все возможности Python.
Примеры: PyTorch, Torch
Архитектура и структура PyTorch
Архитектурная схема библиотеки PyTorch
PyTorch построен в виде многоуровневой архитектуры, где каждый уровень обеспечивает определенную функциональность. Эта модульная структура позволяет использовать только необходимые компоненты библиотеки.
Уровни архитектуры PyTorch:
1. Низкоуровневый движок тензоров
Базовый уровень, обеспечивающий операции с многомерными массивами (тензорами). Оптимизирован для работы как на CPU, так и на GPU.
2. Система автоматического дифференцирования
Реализует алгоритм обратного распространения ошибки (backpropagation) для вычисления градиентов сложных функций.
3. Модуль нейронных сетей (torch.nn)
Высокоуровневый API для создания и обучения нейронных сетей с готовыми слоями, функциями активации, критериями потерь.
4. Оптимизаторы и инструменты обработки данных
Включает различные алгоритмы оптимизации и компоненты для загрузки, обработки и манипулирования данными.
5. Специализированные домены
Дополнительные модули для работы с конкретными типами данных, например, torchvision для компьютерного зрения, torchaudio для обработки звука, torchtext для обработки естественного языка.
Релизная стратегия PyTorch
PyTorch использует трехуровневую систему для классификации функций по их стабильности:
Stable
Стабильные функции с долгосрочной поддержкой, полной документацией и без серьезных ограничений производительности. Обратная совместимость сохраняется.
Beta
Функции, API которых может меняться на основе обратной связи от пользователей, или требующие улучшения производительности. Обратная совместимость не гарантируется.
Prototype
Экспериментальные функции, обычно недоступные в стандартных дистрибутивах или скрытые за флагами времени выполнения. Находятся на ранней стадии разработки.
Основные модули PyTorch
PyTorch состоит из нескольких ключевых модулей, каждый из которых отвечает за определенную функциональность библиотеки.
torch
Основной модуль, содержащий базовые операции с тензорами, математические функции и примитивы для создания тензоров.
Включает функции для создания, манипуляции и выполнения операций над тензорами, аналогично NumPy, но с возможностью выполнения на GPU.
torch.autograd
Реализует механизм автоматического дифференцирования для всех операций с тензорами.
Позволяет автоматически вычислять градиенты для обратного распространения ошибки при обучении нейронных сетей.
torch.nn
Высокоуровневый API для создания и обучения нейронных сетей.
Предоставляет готовые реализации слоев, функций активации, функций потерь и других компонентов для построения сложных архитектур нейронных сетей.
torch.optim
Реализует различные алгоритмы оптимизации для обучения моделей.
Включает популярные оптимизаторы: SGD, Adam, RMSProp, Adagrad и другие, а также планировщики скорости обучения.
torch.utils.data
Предоставляет инструменты для эффективной загрузки и обработки данных.
Включает Dataset и DataLoader для организации, батчинга и асинхронной загрузки данных во время обучения.
torch.cuda
Обеспечивает интеграцию с CUDA для выполнения вычислений на GPU.
Позволяет перемещать тензоры между CPU и GPU, контролировать использование памяти и управлять несколькими устройствами.
torch.distributed
Поддерживает параллельные и распределенные вычисления.
Позволяет эффективно обучать модели на нескольких GPU или даже на нескольких машинах.
torch.library
API для расширения PyTorch пользовательскими операторами и функциями.
Позволяет создавать, тестировать и интегрировать новые операторы с полной поддержкой autograd, батчинга и компиляции.
Дополнительные домен-специфичные пакеты
torchvision
Библиотека для работы с изображениями и компьютерным зрением. Включает готовые модели, преобразования данных и популярные наборы данных.
torchaudio
Инструменты для работы с аудиоданными и обработки звука. Предоставляет функции для чтения, преобразования и извлечения признаков из аудиосигналов.
torchtext
Библиотека для обработки естественного языка (NLP). Содержит инструменты для работы с текстовыми данными и языковыми моделями.
torchrec
Библиотека для крупномасштабных рекомендательных систем, оптимизированная для обработки разреженных данных.
torchserve
Фреймворк для развертывания моделей PyTorch в производство с поддержкой масштабирования и мониторинга.
Тензоры и операции
Тензоры являются фундаментальными структурами данных в PyTorch, аналогичными массивам NumPy, но с дополнительными возможностями для автоматического дифференцирования и выполнения на GPU.
Схема работы с тензорами в PyTorch
Типы тензоров
| Тип | Описание | Пример создания |
|---|---|---|
| torch.FloatTensor | 32-бит, с плавающей точкой | torch.FloatTensor(2, 3) |
| torch.DoubleTensor | 64-бит, с плавающей точкой | torch.DoubleTensor(2, 3) |
| torch.IntTensor | 32-бит, целочисленный, знаковый | torch.IntTensor(2, 3) |
| torch.LongTensor | 64-бит, целочисленный, знаковый | torch.LongTensor(2, 3) |
| torch.ByteTensor | 8-бит, целочисленный, беззнаковый | torch.ByteTensor(2, 3) |
Важно: В отличие от NumPy, PyTorch не выполняет автоматическое приведение типов. Необходимо явно преобразовывать тензоры, используя методы .float(), .long(), .to(dtype=torch.float32) и т.д.
Создание тензоров
# Из списка Python
x = torch.tensor([[1, 2], [3, 4]])
# С определенным типом данных
x = torch.tensor([[1.0, 2.0], [3.0, 4.0]], dtype=torch.float32)
# Заполнение нулями
x = torch.zeros(2, 3)
# Заполнение единицами
x = torch.ones(2, 3)
# Случайные значения из нормального распределения
x = torch.randn(2, 3)
# Случайные значения из равномерного распределения [0, 1)
x = torch.rand(2, 3)
# Единичная матрица
x = torch.eye(3)
# Из NumPy массива
import numpy as np
numpy_array = np.random.rand(2, 3)
x = torch.from_numpy(numpy_array)
Операции с тензорами
Графическое представление mutable и immutable функций в PyTorch
Соглашение о наименованиях: В PyTorch функции вида xxx возвращают новый тензор (immutable), а функции вида xxx_ изменяют исходный тензор (mutable/inplace).
Арифметические операции
Immutable операции
z = x.add(y)илиz = x + yz = x.sub(y)илиz = x - yz = x.mul(y)илиz = x * yz = x.div(y)илиz = x / y
Mutable операции
x.add_(y)илиx += yx.sub_(y)илиx -= yx.mul_(y)илиx *= yx.div_(y)илиx /= y
Матричные операции
z = x.mm(y)— матричное умножениеz = x.mv(v)— умножение матрицы на векторz = x.dot(y)— скалярное произведениеz = x.t()— транспонированиеbz = bx.bmm(by)— батчевое матричное умножение
Операции редукции
s = x.mean(dim)— среднее значениеs = x.sum(dim)— суммаs = x.prod(dim)— произведениеs = x.max(dim)— максимумs = x.min(dim)— минимумs = x.std(dim)— стандартное отклонениеs = x.var(dim)— дисперсияs = x.median(dim)— медиана
Манипуляции формой и преобразования
# Изменение размерности
x = torch.randn(4, 4)
y = x.view(16) # преобразование в одномерный тензор
z = x.view(-1, 8) # -1 автоматически определяет размер
# Конкатенация тензоров
a = torch.randn(2, 3)
b = torch.randn(2, 3)
c = torch.cat([a, b], dim=0) # по первому измерению
d = torch.cat([a, b], dim=1) # по второму измерению
# Расширение размерности
x = torch.randn(2, 3)
y = x.unsqueeze(0) # добавляет измерение в начало
z = x.unsqueeze(1) # добавляет измерение после первого
# Сжатие размерности
x = torch.randn(1, 2, 3)
y = x.squeeze() # удаляет все измерения размера 1
z = x.squeeze(0) # удаляет указанное измерение, если его размер 1
Индексирование и срезы
# Индексирование как в Python
x = torch.randn(4, 3)
print(x[0]) # первая строка
print(x[:, 1]) # второй столбец
print(x[0, 1]) # элемент в первой строке, втором столбце
# Индексирование с помощью тензора
indices = torch.tensor([0, 2])
print(x[indices]) # выбирает строки с указанными индексами
# Булево индексирование
mask = x > 0
print(x[mask]) # выбирает элементы, где условие истинно
Интеграция с NumPy
# Из NumPy в PyTorch
import numpy as np
np_array = np.random.rand(2, 3)
torch_tensor = torch.from_numpy(np_array)
# Из PyTorch в NumPy
torch_tensor = torch.randn(2, 3)
np_array = torch_tensor.numpy()
# Важно: тензоры, созданные через from_numpy(),
# разделяют память с исходным NumPy массивом
Автоматическое дифференцирование
Автоматическое дифференцирование (AutoGrad) — ключевая особенность PyTorch, позволяющая автоматически вычислять градиенты для оптимизации моделей машинного обучения.
«Механизм автоматического дифференцирования, заключённый в модуле torch.autograd, является хоть и не главным, но, без сомнения, важнейшим компонентом библиотеки, без которого та потеряла бы всякий смысл.»
Принцип работы
В PyTorch используется техника дифференцирования, при которой граф вычислений строится динамически во время выполнения (define-by-run). Это позволяет:
- Автоматически отслеживать все операции с тензорами
- Вычислять градиенты всех переменных относительно любой другой переменной
- Сохранять полный контроль над всем процессом вычислений
Основы использования
# Создание тензоров с возможностью вычисления градиентов
x = torch.randn(2, 2, requires_grad=True)
y = torch.randn(2, 2, requires_grad=True)
# Выполнение операций
z = x * y
out = z.mean()
# Вычисление градиентов
out.backward()
# Доступ к градиентам
print(x.grad) # d(out)/dx
print(y.grad) # d(out)/dy
Важные свойства:
requires_grad— флаг, указывающий, нужно ли отслеживать вычисления для тензораgrad— содержит градиент тензора (None, если градиент не был вычислен)grad_fn— содержит ссылку на функцию, создавшую тензорis_leaf— указывает, является ли тензор листовым узлом в графе вычислений
Управление вычислением градиентов
torch.no_grad()
Контекстный менеджер, временно отключающий вычисление градиентов. Полезно при выполнении оценки модели (validation/inference).
with torch.no_grad():
model_output = model(input_data)
torch.set_grad_enabled()
Функция для включения/отключения вычисления градиентов. Удобна для использования в циклах обучения.
torch.set_grad_enabled(is_training)
# вычисления
torch.set_grad_enabled(True)
detach()
Создает новый тензор, отделенный от графа вычислений. Полезно для прерывания потока градиентов.
detached = x.detach()
# detached не будет накапливать градиенты
retain_grad()
Сохраняет градиенты для промежуточных тензоров, которые обычно не сохраняются после вызова backward().
z = x * y
z.retain_grad() # сохранит z.grad после backward()
Пример сложного вычисления с градиентами
import torch
# Создаем тензоры с отслеживанием вычислений
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = torch.tensor([4.0, 5.0, 6.0], requires_grad=True)
# Выполняем операции
a = torch.sum(x * y)
b = torch.sum(x)
c = a * b
# Вычисляем градиенты
c.backward()
# Проверяем результаты
print(f"x.grad: {x.grad}") # d(c)/dx
print(f"y.grad: {y.grad}") # d(c)/dy
Нейронные сети
Модуль torch.nn предоставляет высокоуровневый интерфейс для создания и обучения нейронных сетей, позволяя строить как простые, так и сложные архитектуры.
Структура и компоненты нейронных сетей в PyTorch
Основные компоненты torch.nn
Module
Базовый класс для всех нейронных сетевых компонентов. Все модели и слои должны наследоваться от него.
class MyModel(nn.Module):
def __init__(self):
super().__init__()
# определение слоев
def forward(self, x):
# логика прямого прохода
return output
Functional
Функциональный интерфейс для операций, которые не содержат обучаемых параметров (функции активации и др.).
import torch.nn.functional as F
output = F.relu(input)
output = F.max_pool2d(input, kernel_size=2)
Основные слои
Линейные слои
nn.Linear(in_features, out_features)— полносвязный слойnn.Bilinear(in1_features, in2_features, out_features)— билинейный слой
Сверточные слои
nn.Conv1d(in_channels, out_channels, kernel_size)— одномерная сверткаnn.Conv2d(in_channels, out_channels, kernel_size)— двумерная сверткаnn.Conv3d(in_channels, out_channels, kernel_size)— трехмерная сверткаnn.ConvTranspose2d(in_channels, out_channels, kernel_size)— транспонированная свертка
Рекуррентные слои
nn.RNN(input_size, hidden_size)— рекуррентный слойnn.LSTM(input_size, hidden_size)— LSTM слойnn.GRU(input_size, hidden_size)— GRU слой
Функции активации
nn.ReLU(),nn.LeakyReLU(),nn.PReLU()nn.Sigmoid(),nn.Tanh()nn.Softmax(dim),nn.LogSoftmax(dim)nn.GELU(),nn.SiLU()(Swish)
Нормализация и регуляризация
nn.BatchNorm1d/2d/3d(num_features)— пакетная нормализацияnn.LayerNorm(normalized_shape)— нормализация слояnn.Dropout(p)— случайное отключение нейроновnn.Weight1d/2d/3d(p, reduction)— L1/L2 регуляризация
Функции потерь
nn.MSELoss()— среднеквадратичная ошибкаnn.CrossEntropyLoss()— кросс-энтропия (сочетает LogSoftmax и NLLLoss)nn.BCELoss()— бинарная кросс-энтропияnn.L1Loss()— средняя абсолютная ошибкаnn.NLLLoss()— отрицательное логарифмическое правдоподобиеnn.KLDivLoss()— дивергенция Кульбака-Лейблераnn.HuberLoss()— Huber Loss (устойчивый к выбросам)nn.CosineEmbeddingLoss()— косинусное расстояние для эмбеддингов
Определение модели
Существует несколько подходов к определению моделей в PyTorch:
Определение через классы
import torch.nn as nn
class SimpleNN(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super(SimpleNN, self).__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.relu = nn.ReLU()
self.fc2 = nn.Linear(hidden_dim, output_dim)
def forward(self, x):
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
model = SimpleNN(10, 50, 3)
Использование Sequential
import torch.nn as nn
model = nn.Sequential(
nn.Linear(10, 50),
nn.ReLU(),
nn.Linear(50, 3)
)
Обучение модели
import torch
import torch.nn as nn
import torch.optim as optim
# Определение модели
model = SimpleNN(input_dim, hidden_dim, output_dim)
# Перенос на GPU (если доступно)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
# Определение функции потерь и оптимизатора
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# Цикл обучения
for epoch in range(num_epochs):
for inputs, targets in dataloader:
# Перенос данных на то же устройство, что и модель
inputs, targets = inputs.to(device), targets.to(device)
# Обнуление градиентов
optimizer.zero_grad()
# Прямой проход
outputs = model(inputs)
# Вычисление потерь
loss = criterion(outputs, targets)
# Обратное распространение и обновление весов
loss.backward()
optimizer.step()
print(f'Epoch {epoch+1}/{num_epochs}, Loss: {loss.item():.4f}')
CUDA и производительность
Одно из ключевых преимуществ PyTorch — простая и эффективная поддержка вычислений на GPU через CUDA, что значительно ускоряет обучение моделей глубокого обучения.
Основы работы с CUDA
# Проверка доступности CUDA
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")
# Проверка количества доступных GPU
if torch.cuda.is_available():
num_gpus = torch.cuda.device_count()
print(f"Available GPUs: {num_gpus}")
for i in range(num_gpus):
print(f"GPU {i}: {torch.cuda.get_device_name(i)}")
# Создание тензора на GPU
x = torch.randn(10, 10, device=device)
# или
x = torch.randn(10, 10).to(device)
# Перемещение тензора между устройствами
x_cpu = x.cpu()
x_gpu = x_cpu.cuda() # или x_cpu.to('cuda')
# Указание конкретного GPU
if torch.cuda.device_count() > 1:
x_gpu1 = torch.randn(10, 10, device="cuda:1") # второй GPU
Важно: Перемещение тензора на GPU создает его копию. Оригинальный тензор остается неизменным.
Перемещение модели на GPU
# Перемещение всей модели на GPU
model = MyModel()
model = model.to(device)
# Если нужно использовать несколько GPU
if torch.cuda.device_count() > 1:
print(f"Using {torch.cuda.device_count()} GPUs")
model = nn.DataParallel(model)
model = model.to(device)
Оптимизация производительности
Закрепленная память (Pinned Memory)
Ускоряет передачу данных между CPU и GPU, предотвращая копирование через буфер.
dataloader = DataLoader(
dataset,
batch_size=32,
pin_memory=True # Использование закрепленной памяти
)
Асинхронные операции
PyTorch выполняет операции на GPU асинхронно. Можно использовать это для оптимизации.
# Ожидание завершения всех асинхронных операций
torch.cuda.synchronize()
# Синхронизация конкретного устройства
torch.cuda.synchronize("cuda:1")
Управление памятью
Контроль за использованием памяти GPU для предотвращения утечек.
# Проверка использования памяти
print(f"Allocated: {torch.cuda.memory_allocated() / 1e9} GB")
print(f"Cached: {torch.cuda.memory_reserved() / 1e9} GB")
# Очистка неиспользуемой кэшированной памяти
torch.cuda.empty_cache()
Смешанная точность
Использование вычислений с половинной точностью (FP16) для ускорения без существенной потери качества.
from torch.cuda.amp import autocast, GradScaler
# Инициализация масштабировщика градиентов
scaler = GradScaler()
# В цикле обучения
with autocast():
outputs = model(inputs)
loss = criterion(outputs, targets)
# Масштабирование градиентов для предотвращения потери точности
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
Контекстные менеджеры для CUDA
# Указание устройства по умолчанию для новых тензоров
with torch.cuda.device(1):
# Все тензоры, созданные здесь, будут на cuda:1
x = torch.randn(10, 10) # x будет на cuda:1
# Временное использование определенного устройства
x = torch.randn(10, 10) # на текущем устройстве по умолчанию
with torch.cuda.device(1):
y = torch.randn(10, 10) # на cuda:1
# После выхода из контекста снова используется предыдущее устройство
z = torch.randn(10, 10) # на первоначальном устройстве
Практические примеры
Пример 1: Линейная регрессия
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
# Генерация данных
np.random.seed(42)
x = np.random.rand(100, 1)
y = 1 + 2 * x + 0.1 * np.random.randn(100, 1) # y = 1 + 2x + шум
# Преобразование в тензоры
x_tensor = torch.from_numpy(x).float()
y_tensor = torch.from_numpy(y).float()
# Определение модели
class LinearRegression(nn.Module):
def __init__(self):
super().__init__()
self.linear = nn.Linear(1, 1)
def forward(self, x):
return self.linear(x)
model = LinearRegression()
# Функция потерь и оптимизатор
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.1)
# Обучение модели
epochs = 100
losses = []
for epoch in range(epochs):
# Прямой проход
y_pred = model(x_tensor)
# Вычисление потерь
loss = criterion(y_pred, y_tensor)
losses.append(loss.item())
# Обратное распространение
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch+1) % 10 == 0:
print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')
# Получение параметров модели
w = model.linear.weight.item()
b = model.linear.bias.item()
print(f'Параметры модели: w = {w:.4f}, b = {b:.4f}')
Пример 2: CNN для классификации изображений
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
# Определение преобразований
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
# Загрузка данных MNIST
train_dataset = torchvision.datasets.MNIST(
root='./data', train=True, transform=transform, download=True)
test_dataset = torchvision.datasets.MNIST(
root='./data', train=False, transform=transform, download=True)
train_loader = torch.utils.data.DataLoader(
train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(
test_dataset, batch_size=1000, shuffle=False)
# Определение CNN модели
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
self.fc1 = nn.Linear(64 * 7 * 7, 128)
self.fc2 = nn.Linear(128, 10)
self.relu = nn.ReLU()
def forward(self, x):
x = self.conv1(x)
x = self.relu(x)
x = self.pool(x)
x = self.conv2(x)
x = self.relu(x)
x = self.pool(x)
x = x.view(-1, 64 * 7 * 7)
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
# Инициализация модели, функции потерь и оптимизатора
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = CNN().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# Обучение модели
num_epochs = 5
for epoch in range(num_epochs):
running_loss = 0.0
for i, (images, labels) in enumerate(train_loader):
images = images.to(device)
labels = labels.to(device)
# Прямой проход
outputs = model(images)
loss = criterion(outputs, labels)
# Обратное распространение
optimizer.zero_grad()
loss.backward()
optimizer.step()
running_loss += loss.item()
if (i+1) % 100 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {running_loss/100:.4f}')
running_loss = 0.0
# Оценка на тестовом наборе
model.eval()
with torch.no_grad():
correct = 0
total = 0
for images, labels in test_loader:
images = images.to(device)
labels = labels.to(device)
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Accuracy: {100 * correct / total:.2f}%')
Пример 3: Трансформер для анализа текста
import torch
import torch.nn as nn
import torch.optim as optim
from torch.nn import TransformerEncoder, TransformerEncoderLayer
# Определение параметров модели
vocab_size = 10000 # размер словаря
embed_dim = 200 # размерность эмбеддингов
hidden_dim = 200 # размерность скрытого состояния
num_layers = 2 # количество слоев трансформера
num_heads = 8 # количество голов внимания
dropout = 0.2 # вероятность дропаута
max_len = 100 # максимальная длина последовательности
# Модель трансформера для классификации текста
class TransformerClassifier(nn.Module):
def __init__(self, vocab_size, embed_dim, hidden_dim, num_classes,
num_layers, num_heads, max_len, dropout=0.5):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embed_dim)
self.pos_encoder = PositionalEncoding(embed_dim, dropout, max_len)
encoder_layers = TransformerEncoderLayer(
embed_dim, num_heads, hidden_dim, dropout)
self.transformer_encoder = TransformerEncoder(encoder_layers, num_layers)
self.classifier = nn.Linear(embed_dim, num_classes)
self.dropout = nn.Dropout(dropout)
def forward(self, x):
# x имеет форму [batch_size, seq_len]
embedded = self.embedding(x) # [batch_size, seq_len, embed_dim]
embedded = self.pos_encoder(embedded)
# Изменение размерности для трансформера: [seq_len, batch_size, embed_dim]
embedded = embedded.permute(1, 0, 2)
encoded = self.transformer_encoder(embedded)
# Используем выход для первого токена [CLS] как представление всей последовательности
pooled = encoded[0]
output = self.dropout(pooled)
output = self.classifier(output)
return output
# Позиционное кодирование
class PositionalEncoding(nn.Module):
def __init__(self, embed_dim, dropout=0.1, max_len=5000):
super().__init__()
self.dropout = nn.Dropout(p=dropout)
pe = torch.zeros(max_len, embed_dim)
position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
div_term = torch.exp(
torch.arange(0, embed_dim, 2).float() * (-torch.log(torch.tensor(10000.0)) / embed_dim)
)
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):
x = x + self.pe[:, :x.size(1), :]
return self.dropout(x)
# Пример использования модели
model = TransformerClassifier(
vocab_size=vocab_size,
embed_dim=embed_dim,
hidden_dim=hidden_dim,
num_classes=2, # бинарная классификация
num_layers=num_layers,
num_heads=num_heads,
max_len=max_len,
dropout=dropout
)
# Проверка формы выходных данных
batch_size = 8
seq_len = 64
dummy_input = torch.randint(0, vocab_size, (batch_size, seq_len))
output = model(dummy_input)
print(f"Форма выходных данных: {output.shape}") # должна быть [batch_size, num_classes]
Экосистема
Вокруг PyTorch сформировалась богатая экосистема библиотек и инструментов, расширяющих его функциональность для различных задач.
torchvision
Пакет для компьютерного зрения, содержит датасеты, модели и преобразования для работы с изображениями.
- torchvision.datasets
- torchvision.models
- torchvision.transforms
torchaudio
Библиотека для обработки аудио данных, содержит функции для загрузки, преобразования и работы со звуком.
- torchaudio.datasets
- torchaudio.transforms
- torchaudio.models
torchtext
Инструменты для обработки естественного языка (NLP), включая загрузку данных, токенизацию и векторизацию текста.
- torchtext.datasets
- torchtext.vocab
- torchtext.data
TorchServe
Фреймворк для развертывания моделей PyTorch в производство, обеспечивающий масштабируемость и мониторинг.
- RESTful API
- Управление моделями
- Мониторинг производительности
PyTorch Lightning
Высокоуровневая обертка над PyTorch, упрощающая организацию кода и обучение сложных моделей.
- Структурированный код
- Автоматическая распределенное обучение
- Встроенные инструменты для логирования
Captum
Библиотека для интерпретации и объяснения моделей машинного обучения.
- Интегрированные градиенты
- Guided GradCAM
- LIME, SHAP
TorchDynamo и TorchInductor
Современные компоненты для компиляции и оптимизации PyTorch кода, значительно повышающие производительность.
- torch.compile()
Weights & Biases
Инструмент для отслеживания экспериментов, визуализации и сравнения результатов моделей.
- Логирование метрик
- Сохранение артефактов
- Отслеживание гиперпараметров
Hugging Face Transformers
Библиотека современных моделей трансформеров для NLP, полностью интегрированная с PyTorch.
- BERT, GPT, T5
- RoBERTa, ALBERT
- DistilBERT, XLNet
Интеграции
Экспорт моделей
- ONNX (Open Neural Network Exchange)
- TorchScript
- C++ API
- PyTorch Mobile
- TensorRT (NVIDIA)
Интеграция с другими инструментами
- Ray
- MLflow
- TensorBoard
- Streamlit
- Apache Spark
* Meta (Facebook) признана экстремистской организацией и запрещена на территории РФ