我在尝试为 MNIST 手写数据集创建一个卷积神经网络时,遇到了代码问题:
initWeight = initializers.RandomNormal(stddev = 0.0025)initBias = initializers.Constant(0.1)model = models.Sequential()model.add(layers.Conv2D(25, (12,12), activation='relu', strides = 2, padding = "valid", input_shape=(28, 28, 1), kernel_initializer= initWeight, bias_initializer=initBias))model.add(layers.Conv3D(64, (5,5,25), activation='relu', padding = "same", kernel_initializer= initWeight, bias_initializer=initBias))model.summary()
我得到了以下错误:
ValueError: Input 0 of layer conv3d is incompatible with the layer: : expected min_ndim=5, found ndim=4. Full shape received: [None, 9, 9, 25]
但我不完全确定问题出在哪里,我希望在二维层之后创建一个层,使用5x5x25的核大小创建64个滤波器。
回答:
我想我明白了你的意图。假设张量是channel last
格式。对于Conv2D
层,接受的输入是四维的,即(batch_size, width, height, number_of_channels)
。因此,对于Conv3D
层,它将接受一个五维张量。
从第一个Conv2D
层,你得到的输出形状是(batch_size, 9, 9, 25)
。batch_size
显示为None
,因为它在我们提供数据之前并不知道批次大小。换句话说,它可以接受任何批次大小。
但无论如何,重点是,虽然Conv2D
返回的输出有25
个通道,你不需要在下一层中显式地提到每个滤波器的通道数(可能是你误用3D卷积的原因)。实际上,框架已经设计好可以为每个滤波器(在下一层)自动采用确切的通道数(25),以便它们与其输入(第一个Conv2D的输出)的通道数匹配。
因此,将Conv3D
替换为以下Conv2D
:
model.add(layers.Conv2D(64, (5,5), activation='relu', padding = "same", kernel_initializer= initWeight, bias_initializer=initBias))
这实际上会采用64
个滤波器,每个滤波器的形状为(5, 5, 25)
。虽然我们没有提到25
,但它会自动这样做,以匹配其输入的通道数。