这个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的每一层的输出滤镜尺寸。请注意,由于我们已经知道,我省略了显示Activation
和Dropout
层的滤镜尺寸输出的信息。为了简洁起见,它们保持相同的输出大小:
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))
如果不是,则需要删除一些
Convolution2D
和MaxPooling2D
层,以便生成非零的过滤器输出。进行与我上面相同的工作,以找出删除所需图层所需的层数。我建议使用Convolution2D
过滤器删除第一个Activation
和n_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))