Типичные ошибки начинающих
Собираем в одном месте грабли, на которые наступают почти все, и как их распознать.
Большинство багов в PyTorch — не падения логики, а несовпадения форм, забытые служебные вызовы и неверные режимы. Их легко поймать, зная симптомы.
1. Несовпадение размерностей
Это ошибка номер один. Слой ждёт вход одной формы, а получает другую — или матрицы не перемножаются. Текст ошибки прямо называет ожидаемые и фактические размеры.
# mat1 and mat2 shapes cannot be multiplied (4x3 and 4x2)
# -> внутренние размерности не совпали: 3 != 4
Лечение: печатайте x.shape после каждого слоя, пока не найдёте, где форма «сломалась». Держите в голове, что вход в nn.Linear(in, out) должен иметь последнюю размерность ровно in.
2. Забытый zero_grad
Код работает, ошибок нет, но обучение странное: loss скачет или не падает. Причина — градиенты накапливаются между шагами (мы разбирали это во втором разделе).
# ПЛОХО: нет zero_grad — градиенты складываются
loss.backward()
optimizer.step()
# ХОРОШО
optimizer.zero_grad()
loss.backward()
optimizer.step()
Симптом: loss ведёт себя хаотично без видимой причины — первым делом ищите пропущенный zero_grad().
3. Перепутанный режим train/eval
Два варианта беды. Забыли model.eval() на инференсе — dropout продолжает гасить нейроны, предсказания «прыгают». Забыли вернуть model.train() после валидации — регуляризация отключена всю следующую эпоху.
Симптом: предсказания одной и той же модели на одних данных каждый раз разные → вы в режиме train с активным dropout, нужен eval().
4. Неверная функция потерь или её вход
Классика — CrossEntropyLoss: ей дали вероятности после softmax вместо логитов, или one-hot вместо индексов классов.
# ПЛОХО: лишний softmax перед CrossEntropyLoss (двойное применение)
probs = torch.softmax(logits, dim=1)
loss = criterion(probs, target)
# ХОРОШО: CrossEntropyLoss сама делает softmax
loss = criterion(logits, target) # logits сырые, target — индексы
Симптом: модель учится подозрительно плохо или метрика не растёт — проверьте, что подаёте в loss и в каком виде target.
5. Тензоры на разных устройствах
Модель на GPU, а батч забыли перенести (раздел про GPU). Текст ошибки: «Expected all tensors to be on the same device».
Лечение: переносите и X, и y на device в начале каждой итерации.
6. Целые числа там, где нужен float
Сеть и градиенты работают с float32. Если данные пришли как int (частая история при чтении из numpy), будет ошибка типа.
# expected scalar type Float but found Long
X = X.float() # привести признаки к float32
Чек-лист отладки
| Симптом | Первое подозрение |
| ошибка про shapes/multiply | несовпадение размерностей слоёв |
| loss скачет/не падает | забытый zero_grad() или большой lr |
| предсказания нестабильны | забыт model.eval() |
| модель плохо учится | неверный loss или его вход |
| same device error | батч не перенесён на устройство модели |
| expected Float but found Long | нужен .float() на данных |
Итог
- Большинство багов PyTorch — формы, забытый
zero_grad, неверный режим, loss и устройства. - Печать
x.shapeпосле слоёв находит ошибки размерностей быстрее всего. - Хаотичный loss → ищите
zero_grad; нестабильные предсказания → нуженeval(). CrossEntropyLossхочет логиты и индексы; данные часто надо приводить к.float().