В чем разница между архитектурами ResNet и U-Net?

«В чем разница между архитектурами ResNet и U-Net?» — вопрос из категории Компьютерное зрение, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

ResNet и U-Net — это фундаментальные архитектуры в компьютерном зрении, созданные для принципиально разных задач.

Архитектура Основная задача Ключевая идея Структура
ResNet (Residual Network) Классификация изображений (например, ImageNet). Skip-connections (остаточные связи), которые пропускают градиент через несколько слоев, решая проблему исчезающего градиента и позволяя обучать очень глубокие сети (более 100 слоев). Последовательная (encoder). Состоит из начальных сверток, нескольких стадий (stage) с residual-блоками и финального полносвязного слоя для классификации.
U-Net Семантическая сегментация изображений (пиксельная классификация, например, в медицине). Симметричная encoder-decoder архитектура с skip-connections, которые соединяют соответствующие слои энкодера и декодера, передавая детальную пространственную информацию для точного восстановления маски. Имеет форму буквы "U": энкодер сжимает изображение, извлекая признаки, а декодер восстанавливает пространственное разрешение.

Практическое сравнение:

  • ResNet выдает один вектор вероятностей для всего изображения ("собака", "кошка").
  • U-Net выдает карту сегментации того же размера, что и входное изображение, где каждый пиксель помечен классом (например, "фон", "орган").

Пример использования ResNet в PyTorch для классификации:

import torch
import torchvision.models as models
import torch.nn as nn

# Загрузка предобученной ResNet-18
model = models.resnet18(pretrained=True)
# Замена финального классификатора под свои классы (например, 10 классов)
model.fc = nn.Linear(model.fc.in_features, 10)

# Прямой проход для классификации
input_image = torch.randn(1, 3, 224, 224)  # [batch, channels, height, width]
output = model(input_image)  # Форма: [1, 10] - логиты для 10 классов

Ключевая идея U-Net (упрощенная схема блока):

import torch.nn as nn

class UNetConvBlock(nn.Module):
    """Типичный блок энкодера U-Net: две свертки + ReLU."""
    def __init__(self, in_channels, out_channels):
        super().__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1),
            nn.ReLU(inplace=True)
        )
    def forward(self, x):
        return self.conv(x)

# В полной U-Net выход такого блока идет: 1) на следующий слой энкодера (с пулингом),
# 2) сохраняется как skip-connection для соответствующего слоя декодера.

Таким образом, ResNet — это инструмент для извлечения высокоуровневых признаков и классификации, а U-Net — для точного пиксельного предсказания на основе этих признаков.