nn.Module и слой nn.Linear
Знакомимся с фундаментом моделей PyTorch: классом nn.Module и полносвязным слоем nn.Linear.
nn.Module — базовый класс для всех слоёв и моделей; он автоматически отслеживает обучаемые параметры внутри себя.
Зачем нужен модуль torch.nn
В разделе про autograd мы складывали модель из голых тензоров с requires_grad=True. Для большой сети это неудобно: пришлось бы вручную создавать и хранить десятки тензоров весов. Модуль torch.nn даёт готовые слои — объекты, которые сами создают свои веса, сами включают им requires_grad и сами применяют forward. Из таких кирпичиков собирают сеть.
nn.Linear — полносвязный слой
Самый базовый слой — nn.Linear(in_features, out_features). Он реализует знакомую операцию y = x @ W.T + b: умножение входа на матрицу весов плюс bias. Это тот самый «линейный слой» из теории нейросетей.
import torch
import torch.nn as nn
layer = nn.Linear(3, 2) # принимает вектор из 3, выдаёт из 2
x = torch.randn(4, 3) # батч из 4 примеров, у каждого 3 признака
y = layer(x) # применяем слой
print(y.shape) # torch.Size([4, 2]) — 4 примера, по 2 числа
Обратите внимание на форму: вход (4, 3), выход (4, 2). Первая размерность — это батч (4 примера), она проходит насквозь. Слой превращает каждый 3-мерный вектор в 2-мерный. Внутри лежат матрица весов формы (2, 3) и вектор bias длины 2 — PyTorch создал их сам и инициализировал случайными числами.
Слой вызывают как функцию
Важная идиома: к слою применяют данные через вызов объекта — layer(x), а не layer.forward(x). Под капотом это вызывает forward, но через __call__ PyTorch делает дополнительную служебную работу (хуки, режимы). Поэтому правило: всегда вызывайте модель как model(x).
Заглянем внутрь слоя
Веса слоя — это обычные тензоры (точнее, nn.Parameter), их видно и можно потрогать:
layer = nn.Linear(3, 2)
print(layer.weight.shape) # torch.Size([2, 3]) — матрица W
print(layer.bias.shape) # torch.Size([2]) — вектор b
print(layer.weight.requires_grad) # True — это обучаемый параметр
Видно главное: веса уже помечены requires_grad=True. Это значит, что autograd из прошлого раздела будет считать по ним градиенты, а оптимизатор — двигать их. Слой избавил нас от ручного создания параметров.
Какие ещё бывают слои
| Слой | Назначение |
nn.Linear | полносвязный слой (взвешенная сумма + bias) |
nn.Conv2d | свёрточный слой для изображений |
nn.Embedding | таблица векторов для слов/категорий |
nn.Dropout | регуляризация — случайно гасит часть нейронов |
nn.BatchNorm1d | нормализация активаций внутри батча |
Все они — наследники nn.Module и применяются одинаково: создал, вызвал на входе. В следующем уроке мы соберём из таких слоёв полноценную сеть.
Итог
nn.Module— база всех слоёв и моделей; он сам отслеживает обучаемые параметры.nn.Linear(in, out)делаетy = x @ W.T + bи сам создаёт веса сrequires_grad=True.- Первая размерность входа — батч, она проходит насквозь; слой меняет размер признаков.
- Слой/модель вызывают как функцию:
model(x), а неmodel.forward(x).