сверточная нейронная сеть keras - выходная форма

Пожалуйста, простите мое невежество, так как я действительно новичок в этой области. Я пытаюсь получить правильную форму вывода из моей нейронной сети, которая имеет 3 слоя Conv2D, а затем 2 плотных слоя. Моя форма ввода (140, 140, 4), которая представляет собой 4 изображения в градациях серого. Когда я помещаю 1 вход, я ожидаю на выходе (1, 4), но здесь я получаю форму (14, 14, 4). Что я здесь делаю неправильно? Большое спасибо за вашу помощь заранее!

meta_layers = [Conv2D, Conv2D, Conv2D, Dense, Dense]
meta_inits = ['lecun_uniform'] * 5
meta_nodes = [32, 64, 64, 512, 4]
meta_filter = [(8,8), (4,4), (3,3), None, None]
meta_strides = [(4,4), (2,2), (1,1), None, None]
meta_activations = ['relu'] * 5
meta_loss = "mean_squared_error"
meta_optimizer=RMSprop(lr=0.00025, rho=0.9, epsilon=1e-06)
meta_n_samples = 1000
meta_epsilon = 1.0;
    meta = Sequential()
    meta.add(self.meta_layers[0](self.meta_nodes[0], init=self.meta_inits[0], input_shape=(140, 140, 4), kernel_size=self.meta_filters[0], strides=self.meta_strides[0]))
    meta.add(Activation(self.meta_activations[0]))
    for layer, init, node, activation, kernel, stride in list(zip(self.meta_layers, self.meta_inits, self.meta_nodes, self.meta_activations, self.meta_filters, self.meta_strides))[1:]:
        if(layer == Conv2D):
            meta.add(layer(node, init = init, kernel_size = kernel, strides = stride))
            meta.add(Activation(activation))
        elif(layer == Dense):
            meta.add(layer(node, init=init))
            meta.add(Activation(activation))
        print("meta node: " + str(node))
    meta.compile(loss=self.meta_loss, optimizer=self.meta_optimizer)

person soulless    schedule 16.08.2017    source источник


Ответы (1)


Ваша проблема заключается в том, что в Keras с версией >= 2.0 к последнему каналу входов применяется слой Dense (вы можете прочитать об этом здесь). Итак, если вы подаете заявку:

Dense(512)

к слою Conv2D с формой (14, 14, 64) вы получите результат с формой (14, 14, 512), а затем применив к нему Dense(4), вы получите результат с формой (14, 14, 4). Вы можете вызвать метод model.summary(), чтобы подтвердить мои слова.

Чтобы решить эту проблему, вам нужно применить один из следующих слоев: GlobalMaxPooling2D, GlobalAveragePooling2D или Flatten к выходным данным последнего сверточного слоя, чтобы ваш вывод был только двумерным (с формой (batch_size, features).

person Marcin Możejko    schedule 16.08.2017
comment
это просто добавление плоского слоя? Я попытался добавить один после последнего сверточного слоя, и это дает мне эту ошибку: Вход 0 несовместим со слоем flatten_2: ожидаемый min_ndim = 3, найденный ndim = 2 - person soulless; 16.08.2017
comment
Это кажется странным. Похоже, вы раздавили свой первый сверточный слой. - person Marcin Możejko; 16.08.2017
comment
Неважно, просто глупая ошибка, когда я добавлял его. Использование flatten решает проблему. Спасибо! - person soulless; 16.08.2017
comment
Попробуйте также протестировать другие слои — с Pooling, так как они могут помочь и ускорить вычисления. - person Marcin Możejko; 16.08.2017
comment
Эти слои влияют только на скорость? Или они тоже могут повлиять на результаты тренировок? - person soulless; 16.08.2017
comment
Добавление GlobalPooling делает вывод этого слоя меньше и без каких-либо пространственных подсказок. Это может помочь (поскольку уменьшается пространство параметров) или навредить (поскольку модель несет меньше информации). - person Marcin Możejko; 16.08.2017
comment
Понятно. Спасибо! - person soulless; 16.08.2017