Почему увеличение сложности нейронных сетей чаще достигается путем добавления новых слоев, а не увеличением количества нейронов в каждом слое?

«Почему увеличение сложности нейронных сетей чаще достигается путем добавления новых слоев, а не увеличением количества нейронов в каждом слое?» — вопрос из категории Нейронные сети и Deep Learning, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Глубина (добавление слоев) предпочтительнее ширины (увеличение нейронов в слое) по нескольким ключевым причинам:

  1. Иерархическое извлечение признаков: Глубокие сети могут выстраивать сложные иерархии абстракций. Например, в компьютерном зрении первые слои учатся распознавать края и текстуры, средние — простые формы, а глубокие — целые объекты. Широкие, но неглубокие сети хуже справляются с такой композиционностью.
  2. Параметрическая эффективность: Для аппроксимации сложных функций глубокой сети часто требуется экспоненциально меньше параметров, чем широкой. Это следует из теоремы об универсальной аппроксимации для глубоких сетей.
  3. Улучшенная регуляризация и обучаемость: Современные архитектурные элементы (например, остаточные связи (ResNet), нормализация пакетов (BatchNorm)) позволяют эффективно обучать очень глубокие сети, смягчая проблемы исчезающих/взрывающихся градиентов, которые были бы критичны для просто широких сетей.

Практический пример с TensorFlow/Keras:

import tensorflow as tf

# Эффективный подход: увеличение глубины
model_deep = tf.keras.Sequential([
    tf.keras.layers.Dense(64, activation='relu', input_shape=(100,)),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(64, activation='relu'),  # Добавленный слой
    tf.keras.layers.Dense(10, activation='softmax')
])

# Менее эффективный подход: увеличение ширины
model_wide = tf.keras.Sequential([
    tf.keras.layers.Dense(256, activation='relu', input_shape=(100,)), # Широкий слой
    tf.keras.layers.Dense(10, activation='softmax')
])

# Глубокая модель часто показывает лучшее соотношение точности и количества параметров.
print(f"Глубокая модель параметров: {model_deep.count_params():,}")
print(f"Широкая модель параметров: {model_wide.count_params():,}")

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