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

Какие проблемы возникают при инициализации весов нулями?

2.0 Middle🔥 161 комментариев
#Глубокое обучение

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

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.

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

Проблемы инициализации весов нулями

Инициализация всех весов нейронной сети нулями - одна из классических ошибок, которая приводит к полной неработоспособности обучения. Основная причина - проблема симметрии (symmetry breaking problem).

Проблема симметрии

Когда все веса равны нулю (или любому одинаковому значению), все нейроны одного слоя вычисляют одинаковый выход, получают одинаковый градиент и обновляются одинаково:

import numpy as np

# Все веса = 0
W = np.zeros((3, 4))  # 3 нейрона, 4 входа
x = np.array([1.0, 2.0, 3.0, 4.0])

# Все нейроны дают одинаковый выход
output = W @ x  # [0, 0, 0] - все одинаковые

# При обратном распространении: dL/dW одинаков для всех нейронов
# После обновления все веса снова одинаковы!

Это означает, что сеть с N нейронами в слое эквивалентна сети с 1 нейроном - вся ёмкость модели теряется. Независимо от количества эпох обучения, нейроны никогда не станут различными.

Конкретные последствия

1. Нулевые градиенты на первом шаге:

Для функций активации, проходящих через ноль (ReLU, tanh, sigmoid), выход при нулевых весах будет 0 или 0.5. Градиенты будут одинаковыми для всех нейронов.

2. Dead neurons при ReLU:

# При весах = 0, pre-activation = 0
# ReLU(0) = 0, ReLU'(0) = 0
# Градиент = 0 -> веса не обновляются -> нейрон "мёртв" навсегда

3. Потеря репрезентативной способности:

Сеть не может выучить разные признаки разными нейронами, что делает глубокую архитектуру бесполезной.

Правильные стратегии инициализации

Xavier/Glorot инициализация (для sigmoid, tanh):

import torch.nn as nn

# Дисперсия = 2 / (fan_in + fan_out)
nn.init.xavier_uniform_(layer.weight)
nn.init.xavier_normal_(layer.weight)

He/Kaiming инициализация (для ReLU и вариантов):

# Дисперсия = 2 / fan_in
nn.init.kaiming_uniform_(layer.weight, nonlinearity="relu")
nn.init.kaiming_normal_(layer.weight, nonlinearity="relu")

Orthogonal инициализация (для RNN/LSTM):

nn.init.orthogonal_(layer.weight)

Что можно инициализировать нулями

Не все нули вредны. Bias (смещения) безопасно инициализировать нулями, потому что симметрию нарушают именно различия в весах:

nn.init.zeros_(layer.bias)  # OK для bias
nn.init.kaiming_normal_(layer.weight)  # но не для весов!

Также в BatchNorm параметр beta (сдвиг) инициализируется нулём, а gamma (масштаб) - единицей. Это корректно, так как BatchNorm сам обеспечивает разнообразие выходов через нормализацию.

Практические рекомендации

  • PyTorch и TensorFlow по умолчанию используют правильную инициализацию (Kaiming для Linear/Conv)
  • Не переопределяйте инициализацию без веской причины
  • Для transfer learning веса предобученной модели уже корректны
  • При fine-tuning новый классификационный слой инициализируют Xavier/Kaiming, а не нулями