Размер отрицательного размера, вызванный вычитанием 3 из 1 для 'conv2d_2/convolution'

Я получил это сообщение об ошибке при объявлении входного слоя в Keras.

ValueError: Отрицательный размерный размер, вызванный вычитанием 3 из 1 для 'conv2d_2/convolution' (op: 'Conv2D') с входными формами: [?,1,28,28], [3,3,28,32].

Мой код такой

model.add(Convolution2D(32, 3, 3, activation='relu', input_shape=(1,28,28)))

Пример приложения: https://github.com/IntellijSys/tensorflow/blob/master/Keras.ipynb

3 ответа

Решение

По умолчанию Convolution2D ( https://keras.io/layers/convolutional/) ожидает, что вход будет в формате (сэмплы, строки, столбцы, каналы), то есть "канал последний". Ваши данные, кажется, в формате (образцы, каналы, строки, столбцы). Вы должны быть в состоянии исправить это, используя дополнительное ключевое слово data_format = 'channels_first' при объявлении слоя Convolution2D.

model.add(Convolution2D(32, (3, 3), activation='relu', input_shape=(1,28,28), data_format='channels_first'))

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

Для начала вот мой код (я знаю, что это не хорошо, я все еще учусь)

imageSize=32
classifier=Sequential() 

classifier.add(Conv2D(64, (3, 3), input_shape = (imageSize, imageSize, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))

classifier.add(Conv2D(64, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))

classifier.add(Conv2D(64, (3, 3), activation = 'relu')) 
classifier.add(MaxPooling2D(pool_size = (2, 2)))

classifier.add(Conv2D(64, (3, 3), activation = 'relu')) 
classifier.add(MaxPooling2D(pool_size = (2, 2)))

classifier.add(Conv2D(64, (3, 3), activation = 'relu')) 
classifier.add(MaxPooling2D(pool_size = (2, 2)))

classifier.add(Flatten())

И только после прохождения каждой возможности я обнаружил ошибку:

Размер изображения 32 на 32. После первого сверточного слоя мы уменьшили его до 30 на 30 (думаю, если я правильно понял свертку)

Затем объединяющий слой уменьшает его вдвое, так что 15 на 15..

И так далее. В конце концов, моя карта объектов настолько мала, что мой слой объединения (или слой свертки) слишком велик, чтобы его преодолеть - и это вызывает ошибку

Таким образом, ошибку легко устранить, увеличив размер изображения или уменьшив сверточные или объединяющие слои.

Keras доступен со следующей совместимостью с бэкэндом:

TensorFlow: Google, Theano: Разработано лабораторией LISA, CNTK: Microsoft

Всякий раз, когда вы видите ошибку с [?,X,X,X], [X,Y,Z,X], проблема с каналом, чтобы исправить это, использует автоматический режим Keras:

Импортировать

from keras import backend as K
K.set_image_dim_ordering('th')

Формат "tf" означает, что сверточные ядра будут иметь форму (строки, столбцы, input_depth, глубина)

Это всегда будет работать...

Используйте следующее:

from keras import backend
backend.set_image_data_format('channels_last')

В зависимости от ваших предпочтений вы можете использовать 'channels_first' или 'channels_last'для установки формата данных изображения. (Источник)

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

Надеюсь, это поможет!

Вместо этого вы можете сохранить пространственные размеры тома таким образом, чтобы размер выходного тома соответствовал размеру входного тома, установив значение "одинаково". используйте padding='same'

    # define the model as a class
class LeNet:

  '''
      In a sequential model, we stack layers sequentially. 
      So, each layer has unique input and output, and those inputs and outputs 
      then also come with a unique input shape and output shape.

  '''

  @staticmethod                ## class can instantiated only once 
  def init(numChannels, imgRows, imgCols , numClasses, weightsPath=None):

    # if we are using channel first we have update the input size
    if backend.image_data_format() == "channels_first":
      inputShape = (numChannels , imgRows , imgCols)
    else: 
      inputShape = (imgRows , imgCols , numChannels)

    # initilize the model
    model = models.Sequential()

    # Define the first set of CONV => ACTIVATION => POOL LAYERS

    model.add(layers.Conv2D(  filters=6,kernel_size=(5,5),strides=(1,1), 
                              padding="valid",activation='relu',kernel_initializer='he_uniform',input_shape=inputShape))
    model.add(layers.AveragePooling2D(pool_size=(2,2),strides=(2,2)))

Надеюсь, это поможет:)

См. Код: Fashion_Mnist_Using_LeNet_CNN

Другие вопросы по тегам