Как рассчитать количество параметров для сверточной нейронной сети?

Я использую Lasagne для создания CNN для набора данных MNIST. Я внимательно слежу за этим примером: сверточные нейронные сети и выделение функций с помощью Python .

Архитектура CNN, которая у меня есть на данный момент, которая не включает в себя ни одного отсекающего слоя, такова:

NeuralNet( layers=[('input', layers.InputLayer), # Input Layer ('conv2d1', layers.Conv2DLayer), # Convolutional Layer ('maxpool1', layers.MaxPool2DLayer), # 2D Max Pooling Layer ('conv2d2', layers.Conv2DLayer), # Convolutional Layer ('maxpool2', layers.MaxPool2DLayer), # 2D Max Pooling Layer ('dense', layers.DenseLayer), # Fully connected layer ('output', layers.DenseLayer), # Output Layer ], # input layer input_shape=(None, 1, 28, 28), # layer conv2d1 conv2d1_num_filters=32, conv2d1_filter_size=(5, 5), conv2d1_nonlinearity=lasagne.nonlinearities.rectify, # layer maxpool1 maxpool1_pool_size=(2, 2), # layer conv2d2 conv2d2_num_filters=32, conv2d2_filter_size=(3, 3), conv2d2_nonlinearity=lasagne.nonlinearities.rectify, # layer maxpool2 maxpool2_pool_size=(2, 2), # Fully Connected Layer dense_num_units=256, dense_nonlinearity=lasagne.nonlinearities.rectify, # output Layer output_nonlinearity=lasagne.nonlinearities.softmax, output_num_units=10, # optimization method params update= momentum, update_learning_rate=0.01, update_momentum=0.9, max_epochs=10, verbose=1, ) 

Это выводит следующую информацию о слое:

  # name size --- -------- -------- 0 input 1x28x28 1 conv2d1 32x24x24 2 maxpool1 32x12x12 3 conv2d2 32x10x10 4 maxpool2 32x5x5 5 dense 256 6 output 10 

и выводит количество обучаемых параметров в виде 217,706

Мне интересно, как рассчитывается это число? Я прочитал ряд ресурсов, включая этот вопрос StackOverflow, но ни один из них явно не обобщает расчет.

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

Например, сверточный слой: количество фильтров x ширина фильтра x высота фильтра.

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

  • Входной уровень : весь входной слой считывает входное изображение, поэтому нет параметров, которые вы могли бы узнать здесь.
  • Сверточные слои : рассмотрим сверточный слой, который на l отображает l карт характеристик, и имеет k карт функций в качестве вывода. Размер фильтра равен n x m . Например, это будет выглядеть так:

    Визуализация сверточного слоя

    Здесь вход имеет l=32 карты функций в качестве входных данных, k=64 карт функций в качестве вывода, а размер фильтра n=3 x m=3 . Важно понимать, что мы не просто имеем фильтр 3×3, а фактически фильтр 3x3x32, так как наш вход имеет 32 измерения. И мы изучаем 64 различных фильтра 3x3x32. Таким образом, общее число весов равно n*m*k*l . Тогда для каждого отображения признаков есть также смещающий член, поэтому мы имеем общее число параметров (n*m*l+1)*k .

  • Объединение слоев : слои объединения, например, делают следующее: «замените соседнюю зону 2×2 на ее максимальное значение». Таким образом, нет параметров, которые вы могли бы изучить на уровне объединения.
  • Полностью подключенные уровни : в полностью подключенном слое все модули ввода имеют отдельный вес для каждого блока вывода. Для n входов и m выходов число весов равно n*m . Кроме того, у вас есть смещение для каждого выходного узла, поэтому вы находитесь в параметрах (n+1)*m .
  • Выходной уровень : выходной уровень является нормальным полностью подключенным слоем, поэтому (n+1)*m параметров, где n – количество входов, а m – количество выходов.

Последней трудностью является первый полностью связанный слой: мы не знаем размерности ввода этого слоя, поскольку он является сверточным слоем. Чтобы вычислить его, мы должны начать с размера входного изображения и вычислить размер каждого сверточного слоя. В вашем случае Lasagne уже рассчитывает это для вас и сообщает размеры, которые облегчают нам задачу. Если вам нужно рассчитать размер каждого слоя самостоятельно, это немного сложнее:

  • В простейшем случае (например, ваш пример) размер вывода сверточного слоя – input_size - (filter_size - 1) , в вашем случае: 28 – 4 = 24. Это связано с характером свертки: мы используем например, 5×5-окрестности для вычисления точки, но две внешние строки и столбцы не имеют 5×5-окрестности, поэтому мы не можем вычислить какой-либо выход для этих точек. Вот почему наш результат равен 2 * 2 = 4 строки / столбца меньше ввода.
  • Если вы не хотите, чтобы выход был меньше, чем вход, можно выполнить нулевое изображение (с параметром pad сверточного слоя в Лазанье). Например, если вы добавляете 2 изображения / столбцы нhive вокруг изображения, размер вывода будет (28 + 4) -4 = 28. Таким образом, в случае заполнения, выходной размер – input_size + 2*padding - (filter_size -1) .
  • Если вы явно хотите уменьшить размер изображения во время свертки, вы можете определить шаг, например, stride=2 , что означает, что вы перемещаете фильтр с шагом в 2 пикселя. Затем выражение становится ((input_size + 2*padding - filter_size)/stride) +1 .

В вашем случае полные расчеты:

  # name size parameters --- -------- ------------------------- ------------------------ 0 input 1x28x28 0 1 conv2d1 (28-(5-1))=24 -> 32x24x24 (5*5*1+1)*32 = 832 2 maxpool1 32x12x12 0 3 conv2d2 (12-(3-1))=10 -> 32x10x10 (3*3*32+1)*32 = 9'248 4 maxpool2 32x5x5 0 5 dense 256 (32*5*5+1)*256 = 205'056 6 output 10 (256+1)*10 = 2'570 

Таким образом, в вашей сети у вас есть 832 + 9’248 + 205’056 + 2’570 = 217’706 обучаемых параметров, что и есть то, что сообщает Лазань.

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

введите описание изображения здесь

Кроме того, (1) слой свертки с шагом 2×2 и (2) свертывающий слой 1×1 stride + (max / avg) пул с 2×2 шагом, каждый из которых вносит одинаковое количество параметров с «одинаковым» дополнением, как можно видеть ниже:

введите описание изображения здесь

  • Проверка доступности хоста с помощью ping в сценариях bash
  • Параметр TCP SO_LINGER (ноль) - когда требуется
  • В чем разница между 127.0.0.1 и localhost
  • Давайте будем гением компьютера.