Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

+1 361новая вакансия за сутки·93 707вакансий открыто сейчас·Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Новые вакансии в TelegramРаботодателям
Talanto
Вакансии
Компании7 266
РезюмеAIПодготовкаСтатьи
BoostТарифыBoost
Войти

Не нашли подходящее?

Пусть нужная вакансия найдёт вас сама.

  1. Подборка в TelegramНовые вакансии по вашему фильтру — сразу в бота.Подключить
  2. Мэтчи по резюмеЗагрузите резюме — покажем, где вы подходите лучше всего.Загрузить
  3. Сохранить фильтрНастройте поиск один раз и возвращайтесь к новым вакансиям.Настроить
Что нового на TalantoTalanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Для работодателей

Опубликуйте вакансию — отклики придут в ваш кабинет.

  1. Вакансиябесплатно
  2. Откликиконтакты бесплатно
  3. Наймэтапы и интервью

40 компаний публикуют вакансии напрямую · 4 402 кандидата открыты к предложениям

Разместить вакансию

Популярные направления

Все подборки
  • Python17 108
  • Облачные технологии14 073
  • QA вакансии3 460
  • Backend вакансии2 114
  • Инженер данных1 805
  • Продакт-менеджер1 266

Разработка

  • Android1 866
  • iOS1 699
  • Fullstack вакансии986
  • AI вакансии955
  • Frontend вакансии745
  • Mobile вакансии44

По стеку

  • Go8 652
  • Java6 545
  • Node.js2 019
  • .NET1 721
  • Kotlin1 623
  • Rust1 453
  • C#710
  • PHP683
  • C++571

DevOps и инфраструктура

  • Kubernetes7 763
  • DevOps вакансии6 060
  • Linux-инфраструктура5 492
  • Terraform / IaC4 261
  • CI/CD3 241
  • Мониторинг и Observability1 783
  • SRE566
  • Кибербезопасность453

Аналитика и данные

  • Data Scientist1 140
  • Бизнес-аналитик930
  • Аналитик данных853
  • Системный аналитик154

Другие направления

  • Проджект-менеджер615
  • UI/UX дизайн146
  • Ручное тестирование14

По регионам

  • Вакансии в США44 321
  • Вакансии в Европе23 862
  • Вакансии в Канаде4 479
  • Работа в России3 913

По формату

  • Удалённые вакансии75 064
  • Релокация в США44 314
  • Гибридная работа12 393
  • Офисная работа7 089

По уровню

  • Senior вакансии42 691
  • Middle вакансии20 905
  • Junior вакансии6 727

Сейчас нанимают

Все компании
  • Wise190 вакансий
  • Rakuten189 вакансий
  • ASML166 вакансий
  • Grab138 вакансий
  • Celonis39 вакансий
  • Spotify36 вакансий
  • Adyen29 вакансий
  • Infobip28 вакансий
  • Monzo20 вакансий
  • Darktrace16 вакансий

Вакансии из 344 источников: карьерные страницы компаний и джоб-борды.

КомпанииО насНовостиПубличная офертаУсловия использованияПолитика конфиденциальностиПоддержка
←К подготовке по вакансии←К теме PyTorchВсе вопросы
PyTorchMiddleКодинг

Как реализовать кастомную функцию потерь в PyTorch?

В закладки
Сначала попробуйте ответить сами30 секунд
Сравнить с ответом ↓

Кастомная loss — это функция или nn.Module, принимающая logits и targets и возвращающая скалярный тензор; главные требования — численная стабильность (log-space операции) и корректный reduction для .backward().

Вариант 1: функция (без параметров)

import torch
import torch.nn.functional as F

def focal_loss(logits: torch.Tensor, targets: torch.Tensor, gamma: float = 2.0, alpha: float = 0.25) -> torch.Tensor:
    """Focal Loss для несбалансированных классов (Lin et al. 2017)."""
    bce = F.binary_cross_entropy_with_logits(logits, targets, reduction='none')
    probs = torch.sigmoid(logits)
    pt = torch.where(targets == 1, probs, 1 - probs)
    focal_weight = alpha * (1 - pt) ** gamma
    return (focal_weight * bce).mean()

# Пример использования
logits = torch.randn(32, 1)      # выход модели
targets = torch.randint(0, 2, (32, 1)).float()
loss = focal_loss(logits, targets, gamma=2.0)
loss.backward()  # градиенты вычисляются автоматически

Кастомная функция потерь в PyTorch

Кастомная loss function в PyTorch реализуется двумя способами: как обычная функция Python или как подкласс nn.Module. Второй вариант предпочтителен, когда у функции потерь есть обучаемые параметры или нужно управлять состоянием.

Вариант 2: nn.Module (с параметрами или состоянием)

import torch
import torch.nn as nn

class WeightedMSELoss(nn.Module):
    """MSE с обучаемым вектором весов для каждого выхода."""

    def __init__(self, num_outputs: int):
        super().__init__()
        # nn.Parameter автоматически регистрируется в model.parameters()
        self.weights = nn.Parameter(torch.ones(num_outputs))

    def forward(self, preds: torch.Tensor, targets: torch.Tensor) -> torch.Tensor:
        # preds, targets: (batch, num_outputs)
        per_output_mse = ((preds - targets) ** 2).mean(dim=0)  # (num_outputs,)
        # softmax чтобы веса суммировались в 1 и были положительными
        w = torch.softmax(self.weights, dim=0)
        return (w * per_output_mse).sum()

loss_fn = WeightedMSELoss(num_outputs=3)
optimizer = torch.optim.Adam(
    list(model.parameters()) + list(loss_fn.parameters()),
    lr=1e-3
)

preds = torch.randn(16, 3)
targets = torch.randn(16, 3)
loss = loss_fn(preds, targets)
optimizer.zero_grad()
loss.backward()
optimizer.step()

Числовая стабильность

Нельзя вручную считать log(p) от вероятностей — это вызывает log(0) = -inf и NaN в градиентах. Вместо этого используют log-space операции:

import torch.nn.functional as F

# Плохо:
loss = -(targets * torch.log(probs)).mean()        # NaN при probs→0

# Хорошо:
loss = F.nll_loss(torch.log(probs + 1e-8), targets)  # добавить epsilon
# Лучше: принять logits и использовать встроенный log_softmax:
loss = F.cross_entropy(logits, targets)              # численно стабильно

Проверка корректности градиентов

from torch.autograd import gradcheck

# gradcheck требует float64 и requires_grad=True
logits = torch.randn(4, 3, dtype=torch.float64, requires_grad=True)
targets = torch.randint(0, 3, (4,))

def loss_fn_for_check(x):
    return F.cross_entropy(x, targets)

assert gradcheck(loss_fn_for_check, (logits,), eps=1e-6, atol=1e-4)

Подводные камни

  • reduction='none' vs 'mean': если loss возвращает тензор вместо скаляра, вызов .backward() упадёт с ошибкой; нужен явный .mean() или .sum().
  • Gradient через targets: если targets — тензор с requires_grad=True, PyTorch будет считать градиент и по ним, что замедляет обучение; передавайте targets как .detach().
  • NaN при log(0): всегда используйте встроенные функции (F.cross_entropy, F.binary_cross_entropy_with_logits) вместо ручного логарифма.
  • Mixed precision (AMP): с torch.cuda.amp.autocast операции выполняются в float16; если loss содержит операции, нечувствительные к fp16 (exp, log), оберните в with torch.cuda.amp.autocast(enabled=False).
  • Параметры loss_fn не в optimizer: при использовании nn.Module-loss нужно добавить loss_fn.parameters() в оптимизатор, иначе обучаемые веса не обновляются.
  • Несовпадение shape: бинарная классификация — targets shape (N,), logits (N, 1); нужен logits.squeeze(1) перед F.binary_cross_entropy_with_logits.
  • Дисбаланс классов: F.cross_entropy принимает параметр weight (тензор весов классов); его стоит считать из частот в тренировочной выборке, а не задавать вручную.
  • gradcheck в float32: численное дифференцирование неточно в float32, gradcheck нужно запускать в float64.

Типичные ошибки

  • Объяснять custom loss function только синтаксисом без shape, dtype, состояния или режима выполнения.
  • Игнорировать leakage, воспроизводимость, пустые входы и скрытые копии данных.
  • Не проверять production-симптомы: latency, память, ретраи, дрейф качества и несовпадение версий.

Что проверяет интервьюер

  • Может ли связать custom loss function с реальным контрактом входов и выходов.
  • Упоминает ли тесты, метрики, reproducibility и диагностику ошибок.
  • Видит ли различие между demo-кодом в ноутбуке и production-пайплайном.

Как вы знаете этот вопрос?

Проверить себя по теме PyTorch →

Источники

  • https://docs.pytorch.org/docs/stable/index.html
←Предыдущий вопросКак работает `torch.nn.Embedding` и когда его следует использовать?Следующий вопрос→Как реализовать кастомный слой `nn.Module` в PyTorch?

Связанные темы

PyTorchdata-aievaluationmodel-training

Частые вопросы на собеседовании

  • Как сохранять и загружать веса модели в PyTorch (state_dict vs полная модель)?
  • Объясните разницу между режимами model.train() и model.eval().
  • Зачем нужен optimizer.zero_grad() и почему его необходимо вызывать перед каждым обратным проходом?
  • В каких data/AI-задачах PyTorch даёт реальный выигрыш, а где лучше выбрать другой инструмент или более простой pipeline?