'conv2d_2/convolution'1减3导致的负维度大小

Negative dimension size caused by subtracting 3 from 1 for 'conv2d_2/convolution'

我在 Keras 中声明输入层时收到此错误消息。

ValueError: Negative dimension size caused by subtracting 3 from 1 for 'conv2d_2/convolution' (op: 'Conv2D') with input shapes: [?,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

默认情况下,Convolution2D (https://keras.io/layers/convolutional/) 期望输入的格式为 (samples, rows, cols, channels),即 "channels-last"。您的数据似乎采用以下格式(样本、通道、行、列)。在声明 Convolution2D 层时,您应该能够使用可选关键字 data_format = 'channels_first' 来解决此问题。

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。

然后另一个卷积层将它减少到 13 x 13...

我希望你能看到这是怎么回事: 最后,我的 特征图太小以至于我的池化层(或卷积层)太大而无法通过它 - 这导致了错误


解决方案

解决此错误的简单方法是增大图像尺寸或使用较少的卷积层或池化层。

Keras 具有以下后端兼容性:

TensorFlow:来自 google, Theano:由 LISA 实验室开发, CNTK:微软

每当您看到 [?,X,X,X], [X,Y,Z,X] 的错误时,这是​​一个解决 Keras 使用自动模式的渠道问题:

导入

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

"tf" 格式意味着卷积核的形状为 (rows, cols, input_depth, depth)

这将永远有效...

您可以通过将值设置为“相同”来保留体积的空间尺寸,使输出体积大小与输入体积大小相匹配。 使用填充='same'

使用以下内容:

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

根据您的喜好,您可以使用'channels_first''channels_last'来设置图像数据格式。 (Source)

如果这不起作用并且您的图像尺寸很小,请尝试减少 CNN 的架构,如之前的海报所述。

希望对您有所帮助!

    # 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