Какие проблемы возникают при инициализации весов нулями?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Проблемы инициализации весов нулями
Инициализация всех весов нейронной сети нулями - одна из классических ошибок, которая приводит к полной неработоспособности обучения. Основная причина - проблема симметрии (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, а не нулями