Почему нельзя делать инициализацию весов нейронной сети нулями?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Почему нельзя инициализировать веса нейронной сети нулями?
Это фундаментальный вопрос в глубоком обучении, который касается самой природы обучения нейронных сетей. Инициализация весов нулями приводит к полной потере информационной способности модели.
Проблема симметрии (Symmetry Problem)
Основная проблема заключается в том, что все нейроны в слое становятся абсолютно идентичными. Если все веса инициализированы нулями, то все нейроны вычисляют одну и ту же функцию на одних и тех же входах.
# Плохая инициализация
W = np.zeros((input_size, hidden_size)) # ❌
print(W.shape) # (784, 128) — но все элементы = 0
Рассмотрим простой слой с нулевой инициализацией:
z1 = 0*x1 + 0*x2 + ... + 0*xn = 0
z2 = 0*x1 + 0*x2 + ... + 0*xn = 0
z3 = 0*x1 + 0*x2 + ... + 0*xn = 0
Все нейроны выдают одинаковый выход (после применения функции активации).
Последствия во время backpropagation
Проблема усугубляется при обратном распространении ошибки:
dW = (1/m) * X.T @ dZ
# Если dZ одинаков для всех нейронов (из-за симметрии)
# то dW для каждого нейрона будет пропорционален одному и тому же градиенту
Держите, расчет:
- Forward pass: все нейроны дают одинаковый выход (например, 0.5 после sigmoid)
- Loss function: вычисляется одна и та же ошибка для всех нейронов
- Backward pass: все нейроны получают одинаковый градиент
- Weight update:
W_new = W_old - learning_rate * dW
# Если W_old = 0 и dW одинаков для всех нейронов
# то все нейроны обновляются идентично!
Результат: нейроны остаются симметричными на протяжении всего обучения! Слой с N нейронов эффективно работает как один нейрон.
Пример с математикой
Для простого двухслойного сети:
import numpy as np
# Инициализация нулями
W1 = np.zeros((3, 4)) # 3 входа, 4 скрытых нейрона
W2 = np.zeros((4, 1)) # 4 скрытых, 1 выход
# Forward pass
X = np.random.randn(5, 3) # 5 примеров, 3 признака
Z1 = X @ W1 # (5, 4) матрица из нулей!
A1 = np.tanh(Z1) # (5, 4) матрица из нулей!
Z2 = A1 @ W2 # (5, 1) матрица из нулей!
print(np.all(Z1 == 0)) # True
print(np.all(A1 == 0)) # True
print(np.all(Z2 == 0)) # True
Модель не выучивает никакие полезные признаки.
Зачем нужна случайная инициализация?
Случайная инициализация нарушает симметрию и позволяет каждому нейрону учиться выявлять различные характеристики входных данных.
# Правильная инициализация
# 1. Xavier/Glorot инициализация
W = np.random.randn(input_size, output_size) * np.sqrt(1 / input_size)
# 2. He инициализация (для ReLU)
W = np.random.randn(input_size, output_size) * np.sqrt(2 / input_size)
# 3. В TensorFlow/Keras
from tensorflow.keras.layers import Dense
layer = Dense(128, kernel_initializer='he_normal') # ✅
Xavier (Glorot) инициализация
Оптимальный диапазон для инициализации:
var(W) = 1 / n_in (для сигмоида/танха)
var(W) = sqrt(1 / n_in) (стандартное отклонение)
Это предотвращает взрывающиеся/исчезающие градиенты:
# Xavier инициализация
limit = np.sqrt(6 / (input_size + output_size))
W = np.random.uniform(-limit, limit, (input_size, output_size))
He инициализация для ReLU
Для активационных функций ReLU нужна иная инициализация (больший диапазон):
var(W) = 2 / n_in
var(W) = sqrt(2 / n_in)
# He инициализация
W = np.random.randn(input_size, output_size) * np.sqrt(2.0 / input_size)
layer = Dense(128, kernel_initializer='he_normal') # Для ReLU
Таблица рекомендаций
| Функция активации | Инициализация | Формула |
|---|---|---|
| Sigmoid / Tanh | Xavier / Glorot | √(1 / n_in) |
| ReLU | He | √(2 / n_in) |
| Другие | He | √(2 / n_in) |
Практический пример проблемы
import tensorflow as tf
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
# ❌ Плохо: нулевая инициализация (эквивалент)
model_bad = Sequential([
Dense(128, activation='relu', kernel_initializer='zeros'),
Dense(10, activation='softmax')
])
# Модель не сможет обучиться эффективно
# ✅ Хорошо: He инициализация
model_good = Sequential([
Dense(128, activation='relu', kernel_initializer='he_normal'),
Dense(10, activation='softmax', kernel_initializer='glorot_uniform')
])
# Модель инициализирована правильно и сможет обучиться
Выводы
- Нулевая инициализация = полная потеря способности сети к обучению
- Все нейроны слоя становятся идентичными и остаются такими
- Случайная инициализация нарушает симметрию и позволяет каждому нейрону развиваться независимо
- Xavier инициализация подходит для сигмоида/танха
- He инициализация подходит для ReLU и других современных активаций
Правильная инициализация весов — это не просто деталь, а фундамент успешного обучения нейронной сети.