CNN Keras: сколько весов будет обучено? - PullRequest
0 голосов
/ 05 июня 2018

У меня маленькая проблема с пониманием CNN.И я не совсем уверен, сколько фильтров и, следовательно, весов обучено.

Пример: у меня есть входной слой с 32x32 пикселями и 3 каналами (т.е. форма (32,32,3)).Сейчас я использую слой 2D-свертки с 10 фильтрами формы (4,4).Таким образом, я получаю 10 каналов, каждый из которых имеет форму (28,28), но теперь я тренирую отдельный фильтр для каждого входного канала или они используются совместно?Я тренируюсь с весами 3х10х4х4 или тренируюсь с весами 10х4х4?

1 Ответ

0 голосов
/ 05 июня 2018

Вы можете узнать количество (не) обучаемых параметров модели в Керасе, используя функцию summary:

from keras import models, layers

model = models.Sequential()
model.add(layers.Conv2D(10, (4,4), input_shape=(32, 32, 3)))

model.summary()

Вот результат:

Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 29, 29, 10)        490       
=================================================================
Total params: 490
Trainable params: 490
Non-trainable params: 0

В общем случае для слоя 2D-свертки с фильтрами k размером w*w, применяемыми к входу с каналами c, число обучаемых параметров (с учетом одного параметра смещения для каждого фильтра в случае по умолчанию) равноравно k*w*w*c+k или k*(w*w*c+1).В приведенном выше примере мы имеем: k=10, w=4, c=3 поэтому у нас есть 10*(4*4*3+1) = 490 обучаемые параметры.Как вы можете сделать вывод, для каждого канала существуют отдельные веса, и они не являются общими.Кроме того, количество параметров слоя 2D-свертки не зависит от ширины или высоты предыдущего слоя.

Обновление:

Сверточный слой с глубинойобщие весовые коэффициенты: я не знаю о таком слое и не смог найти встроенную реализацию этого в Keras или Tensorflow.Но подумав об этом, вы понимаете, что это по сути эквивалентно суммированию всех каналов вместе, а затем применяет двумерную свертку к результату.Например, в случае изображения 32*32*3 сначала все три канала суммируются, в результате чего получается тензор 32*32*1, а затем к нему можно применить двумерную свертку.Поэтому, по крайней мере, один способ достижения 2D-свертки с общими весами по каналам может быть таким в Керасе (который может или не может быть эффективным):

from keras import models, layers
from keras import backend as K

model = models.Sequential()
model.add(layers.Lambda(lambda x: K.expand_dims(K.sum(x, axis=-1)), input_shape=(32, 32, 3)))
model.add(layers.Conv2D(10, (4,4)))

model.summary()

Вывод:

Layer (type)                 Output Shape              Param #   
=================================================================
lambda_1 (Lambda)            (None, 32, 32, 1)         0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 29, 29, 10)        170       
=================================================================
Total params: 170
Trainable params: 170
Non-trainable params: 0

Одна хорошая вещь в этом лямбда-слое состоит в том, что он может быть добавлен в любом месте (например, после свертки).Но я думаю, что самый важный вопрос, который нужно здесь задать, это: «Почему было бы полезно использовать слой 2D-conv с распределенными весами по глубине?»Один очевидный ответ заключается в том, что размер сети (т. Е. Общее число обучаемых параметров) уменьшается, и, следовательно, может быть сокращение времени обучения, которое, я подозреваю, будет незначительным.Кроме того, использование общих весов по каналам подразумевает, что шаблоны, присутствующие в разных каналах, более или менее похожи.Но это не всегда так, например, в изображениях RGB, и поэтому, используя общие веса по каналам, я думаю, вы могли бы наблюдать (заметное) снижение точности сети.Так что, по крайней мере, вы должны иметь в виду этот компромисс и поэкспериментировать с ним.

Однако есть еще один вид сверточного слоя, который вас может заинтересовать, называемый «Разделяемая свертка с глубиной»который был реализован в Tensorflow, и Keras также поддерживает его .Идея состоит в том, что на каждом канале применяется отдельный фильтр 2D-свёртки, а затем полученные карты характеристик агрегируются с использованием k 1*1 сверток (k здесь - количество выходных каналов).Он в основном разделяет изучение пространственных и глубинных элементов.В своей статье «Xception: глубокое обучение с отделимыми по глубине извилинами» Франсуа Шоле (создатель Keras) показывает, что использование отделимых по глубине извилистых извилин повышает как производительность, так и точность сети.И здесь вы можете прочитать больше о различных видах слоев свертки, используемых в глубоком обучении.

...