这个CNN适用于40x40x2图像,但是现在我想更改为13x78x2​​并得到以下错误。 CNN的架构应该改变什么?

Negative dimension size caused by subtracting 3 from 2 for 'conv2d_13/convolution' (op: 'Conv2D') with input shapes: [?,2,35,64], [3,3,64,64].


我的代码:

  data_w = 40 #CHANGE TO 13
  data_h = 40 #CHANGE TO 78
  n_classes = 2
  n_filters_1 = 32
  n_filters_2 = 64
  d_filter = 3
  p_drop_1 = 0.25
  p_drop_2 = 0.50
  model = Sequential()
  model.add(Convolution2D(n_filters_1, d_filter, d_filter, border_mode='valid', input_shape=(data_w, data_h,2)))
  model.add(Activation('relu'))
  model.add(Convolution2D(n_filters_1, d_filter, d_filter))
  model.add(Activation('relu'))
  model.add(MaxPooling2D(pool_size=(2, 2)))
  model.add(Dropout(p_drop_1))
  model.add(Convolution2D(n_filters_2, d_filter, d_filter, border_mode='valid'))
  model.add(Activation('relu'))
  model.add(Convolution2D(n_filters_2, d_filter, d_filter))
  model.add(Activation('relu'))
  model.add(MaxPooling2D(pool_size=(2, 2)))
  model.add(Dropout(p_drop_1))
  ## Used to flat the input (1, 10, 2, 2) -> (1, 40)
  model.add(Flatten())
  # Full Connected layer
  model.add(Dense(256))
  model.add(Activation('relu'))
  # Drop layer
  model.add(Dropout(p_drop_2))
  # Output Full Connected layer
  model.add(Dense(n_classes))
  model.add(Activation('softmax'))

最佳答案

因为您已选择valid作为卷积的border_mode,所以将发生3x 3滤镜大小的情况,因此我们将在每个Convolution2D层上为生成的滤镜输出删除边框周围的1个像素。另请注意,省略参数也假定有效填充。如果计算出每层输出尺寸的减小量,则会达到输出过滤器尺寸的尺寸(行)之一为0的程度,因此会出现错误。对于d_filter = 3,让我们遍历输入图像尺寸为13 x 78的每一层的输出滤镜尺寸。请注意,由于我们已经知道,我省略了显示ActivationDropout层的滤镜尺寸输出的信息。为了简洁起见,它们保持相同的输出大小:

  model.add(Convolution2D(n_filters_1, d_filter, d_filter, border_mode='valid', input_shape=(data_w, data_h,2))) # 11 x 76
  model.add(Activation('relu'))
  model.add(Convolution2D(n_filters_1, d_filter, d_filter)) # 9 x 74
  model.add(Activation('relu'))
  model.add(MaxPooling2D(pool_size=(2, 2))) # 4 x 37
  model.add(Dropout(p_drop_1))
  model.add(Convolution2D(n_filters_2, d_filter, d_filter, border_mode='valid')) # 2 x 35
  model.add(Activation('relu'))
  model.add(Convolution2D(n_filters_2, d_filter, d_filter)) # 0 x 33 (!!!!)
  model.add(Activation('relu'))
  model.add(MaxPooling2D(pool_size=(2, 2)))
  model.add(Dropout(p_drop_1))


我建议的一件事是将border_mode更改为'same'。这样,在每个Convolution2D层到达Pooling层之前,都将保留其输出过滤器大小。我不确定您选择有效卷积的目的,但是请尝试这样做:

  model.add(Convolution2D(n_filters_1, d_filter, d_filter, border_mode='same', input_shape=(data_w, data_h,2))) # 13 x 78
  model.add(Activation('relu'))
  model.add(Convolution2D(n_filters_1, d_filter, d_filter), border_mode='same') # 13 x 78
  model.add(Activation('relu'))
  model.add(MaxPooling2D(pool_size=(2, 2))) # 6 x 39
  model.add(Dropout(p_drop_1))
  model.add(Convolution2D(n_filters_2, d_filter, d_filter, border_mode='same')) # 6 x 39
  model.add(Activation('relu'))
  model.add(Convolution2D(n_filters_2, d_filter, d_filter), border_mode='same') # 6 x 39
  model.add(Activation('relu'))
  model.add(MaxPooling2D(pool_size=(2, 2))) # 3 x 19
  model.add(Dropout(p_drop_1))


如果不是,则需要删除一些Convolution2DMaxPooling2D层,以便生成非零的过滤器输出。进行与我上面相同的工作,以找出删除所需图层所需的层数。我建议使用Convolution2D过滤器删除第一个Activationn_filters_2层之后的层:

  model.add(Convolution2D(n_filters_1, d_filter, d_filter, border_mode='valid', input_shape=(data_w, data_h,2))) # 11 x 76
  model.add(Activation('relu'))
  model.add(Convolution2D(n_filters_1, d_filter, d_filter)) # 9 x 74
  model.add(Activation('relu'))
  model.add(MaxPooling2D(pool_size=(2, 2))) # 4 x 37
  model.add(Dropout(p_drop_1))
  model.add(Convolution2D(n_filters_2, d_filter, d_filter, border_mode='valid')) # 2 x 35
  model.add(Activation('relu'))
#  model.add(Convolution2D(n_filters_2, d_filter, d_filter)) # 0 x 33 (!!!!)
#  model.add(Activation('relu'))
#  model.add(MaxPooling2D(pool_size=(2, 2)))
#  model.add(Dropout(p_drop_1))

10-05 23:57