← Назад к вопросам

Зачем нужен residual block?

1.0 Junior🔥 201 комментариев
#Глубокое обучение

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Residual Blocks в глубоких нейронных сетях

Residual block (остаточное соединение) — это архитектурный элемент глубоких нейронных сетей, который позволяет сетям успешно обучаться с очень большой глубиной. Впервые введены в архитектуру ResNet (Residual Networks) в 2015 году и стали революционным прорывом в области deep learning.

Основная идея

Вместо того чтобы сеть училась функции H(x), residual block позволяет сети учиться остаточной функции F(x) = H(x) - x, а затем выход вычисляется как H(x) = F(x) + x. Это означает, что выход слоя — это сумма выхода сети и исходного входа (skip connection).

Визуализация архитектуры

Вход x
  │
  ├──────────────────┐
  │                  │
  ▼                  │
[Conv2d]             │
  ▼                  │
[BatchNorm]          │
  ▼                  │
[ReLU]               │
  ▼                  │
[Conv2d]             │
  ▼                  │
[BatchNorm]          │
  ▼                  │
[+] ◄──────────────┤ (skip connection)
  ▼
[ReLU]
  │
  ▼
Выход

Реализация в PyTorch

import torch
import torch.nn as nn

class ResidualBlock(nn.Module):
    def __init__(self, in_channels, out_channels, stride=1):
        super(ResidualBlock, self).__init__()
        
        # Основной путь (main path)
        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, 
                               stride=stride, padding=1)
        self.bn1 = nn.BatchNorm2d(out_channels)
        self.relu = nn.ReLU(inplace=True)
        
        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, 
                               padding=1)
        self.bn2 = nn.BatchNorm2d(out_channels)
        
        # Skip connection (адаптация размеров, если необходимо)
        self.shortcut = nn.Sequential()
        if stride != 1 or in_channels != out_channels:
            self.shortcut = nn.Sequential(
                nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride),
                nn.BatchNorm2d(out_channels)
            )
    
    def forward(self, x):
        # Основной путь
        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)
        
        out = self.conv2(out)
        out = self.bn2(out)
        
        # Skip connection
        out += self.shortcut(x)
        out = self.relu(out)
        
        return out

Зачем нужны Residual Blocks

1. Решение проблемы исчезающего градиента (Vanishing Gradient Problem)

При тренировке очень глубоких сетей градиенты при обратном распространении становятся всё меньше и меньше, что затрудняет обучение ранних слоёв. Skip connections позволяют градиентам течь напрямую через сеть:

∂Loss/∂x = ∂Loss/∂out * (∂out/∂main_path + ∂out/∂skip_path)
         = ∂Loss/∂out * (something + 1)

Слагаемое +1 из skip connection гарантирует, что градиент не будет исчезать даже в очень глубоких сетях.

2. Улучшенная обучаемость

Резидуальные блоки облегчают сети учиться, так как она может учиться небольшим изменениям (residuals) вместо полной функции. Это более естественно для сетей и ускоряет сходимость.

3. Позволяет строить гораздо более глубокие сети

До ResNet сети с 50+ слоями плохо обучались. С residual blocks успешно обучаются сети с 152, 1000+ слоями:

# ResNet-152 (152 слоя) обучается лучше, чем ResNet-34 (34 слоя)
# Без residual blocks это было невозможно

4. Улучшенная регуляризация

Skip connections действуют как форма регуляризации, предотвращая переобучение, так как сеть не может произвольно игнорировать исходный вход.

Примеры использования в практике

ImageNet классификация:

import torchvision.models as models

# Предварительно обученный ResNet
resnet50 = models.resnet50(pretrained=True)
predictions = resnet50(images)

Медицинская диагностика:

# ResNet широко используется для анализа медицинских снимков
# благодаря способности обучаться глубоким признакам
model = models.resnet34(num_classes=3)  # 3 класса диагноза

Варианты Residual Connections

1. Identity Shortcuts — самый простой случай, когда размеры совпадают (x + f(x)).

2. Projection Shortcuts — когда нужно изменить размерность или количество каналов.

shortcut = nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride)

3. Bottleneck Architecture — используется в ResNet-50+, где блок состоит из 3 слоёв (1x1 -> 3x3 -> 1x1) для уменьшения вычислительной сложности.

Развитие идеи

После ResNet появились улучшения:

  • DenseNet — вместо добавления skip connection, объединяет (concatenate) всем предыдущим слоям
  • ResNeXt — добавляет кардинальность (cardinality) для лучшей репрезентации
  • Wide ResNet — увеличивает ширину сети вместо глубины
  • Squeeze-and-Excitation Networks — адаптивное масштабирование каналов

Метрики эффективности

Вклад residual blocks в улучшение результатов на ImageNet:

  • ResNet-34: 73.3% top-1 accuracy
  • ResNet-50: 76.1% top-1 accuracy
  • ResNet-152: 77.6% top-1 accuracy

Ключевое открытие: с увеличением глубины сеть обучается лучше, а не хуже.

Заключение

Residual blocks — это фундаментальная архитектурная инновация, которая позволила строить очень глубокие и эффективные нейронные сети. Они решили критическую проблему исчезающих градиентов и стали основой для большинства современных глубоких моделей (BERT, GPT, Vision Transformers). Понимание residual connections обязательно для любого Data Scientist, работающего с deep learning.