Размер отрицательного размера, вызванный вычитанием 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