【问题标题】:Keras MaxPooling2D layer does not reduce the shapeKeras MaxPooling2D 层不缩小形状
【发布时间】:2020-03-12 18:29:29
【问题描述】:

我正在构建一个神经网络,更具体地说是一个 CNN,用于对人体细胞器​​中各种蛋白质的位置进行分类。我在 4 个通道 R、G、B 和 Y 中有 512 x 512 图像:

def ModelMaker(intTuple):

    model = Sequential()

    model.add(Conv2D(8, (7, 7), strides=(2, 2), kernel_initializer='he_normal', bias_initializer='zeros',
                     kernel_regularizer='l2', padding='valid', data_format="channels_last", input_shape=intTuple))

    model.add(Conv2D(16, (3, 3), strides=(1, 1), padding='same', kernel_regularizer='l2'))
    model.add(PReLU(alpha_initializer=VarianceScaling(scale=1.0, mode='fan_in', distribution='normal', seed=None)))
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(1, 1), padding='same'))

    model.add(Conv2D(32, (3, 3), strides=(1, 1), padding='same', kernel_regularizer='l2'))
    model.add(PReLU(alpha_initializer=VarianceScaling(scale=1.0, mode='fan_in', distribution='normal', seed=None)))
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(1, 1), padding='same'))

    model.add(Conv2D(64, (3, 3), strides=(1, 1), padding='same', kernel_regularizer='l2'))
    model.add(PReLU(alpha_initializer=VarianceScaling(scale=1.0, mode='fan_in', distribution='normal', seed=None)))
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(1, 1), padding='same'))

    model.add(Conv2D(128, (3, 3), strides=(1, 1), padding='same', kernel_regularizer='l2'))
    model.add(PReLU(alpha_initializer=VarianceScaling(scale=1.0, mode='fan_in', distribution='normal', seed=None)))
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(1, 1), padding='same'))

    model.add(Conv2D(256, (3, 3), strides=(1, 1), padding='same', kernel_regularizer='l2'))
    model.add(PReLU(alpha_initializer=VarianceScaling(scale=1.0, mode='fan_in', distribution='normal', seed=None)))
    model.add(AveragePooling2D(pool_size=(2, 2), strides=(1, 1), padding='same'))

    model.add(Flatten())

    model.add(Dense(28))
    model.add(Activation('softmax'))

    return model

model = ModelMaker((512, 512, 4))
model.summary()

一切都很好,但是当我创建模型并运行model.summary() 并遍历各个层时,有些奇怪。对于每个卷积,我有以下层序列:Conv2D ---> PReLU ---> MaxPooling2D/AveragePooling2D。但是,模型摘要如下所示:

Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_6 (Conv2D)            (None, 253, 253, 8)       1576      
_________________________________________________________________
conv2d_7 (Conv2D)            (None, 253, 253, 16)      1168      
_________________________________________________________________
p_re_lu_5 (PReLU)            (None, 253, 253, 16)      1024144   
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 253, 253, 16)      0         
_________________________________________________________________
conv2d_8 (Conv2D)            (None, 253, 253, 32)      4640      
_________________________________________________________________
p_re_lu_6 (PReLU)            (None, 253, 253, 32)      2048288   
_________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, 253, 253, 32)      0         
_________________________________________________________________
conv2d_9 (Conv2D)            (None, 253, 253, 64)      18496     
_________________________________________________________________
p_re_lu_7 (PReLU)            (None, 253, 253, 64)      4096576   
_________________________________________________________________
max_pooling2d_6 (MaxPooling2 (None, 253, 253, 64)      0         
_________________________________________________________________
conv2d_10 (Conv2D)           (None, 253, 253, 128)     73856     
_________________________________________________________________
p_re_lu_8 (PReLU)            (None, 253, 253, 128)     8193152   
_________________________________________________________________
max_pooling2d_7 (MaxPooling2 (None, 253, 253, 128)     0         
_________________________________________________________________
conv2d_11 (Conv2D)           (None, 253, 253, 256)     295168    
_________________________________________________________________
p_re_lu_9 (PReLU)            (None, 253, 253, 256)     16386304  
_________________________________________________________________
average_pooling2d_1 (Average (None, 253, 253, 256)     0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 16386304)          0         
_________________________________________________________________
dense_1 (Dense)              (None, 28)                458816540 
_________________________________________________________________
activation_1 (Activation)    (None, 28)                0         
=================================================================
Total params: 490,959,908
Trainable params: 490,959,908
Non-trainable params: 0
_________________________________________________________________

降维似乎有问题。对于前两个维度(253、253、XX),张量的大小都是相同的。它保持在 253 不变......只有通道大小增加,这是正常的。我删除了最后两个密集层堆栈,因为模型甚至不会将自己定义为运行时崩溃,因为内存已用完。我猜这是由于当形状(253、253、256)变平并通过时,致密层的尺寸非常大。整个模型不适合 RAM。救命!

【问题讨论】:

  • 为什么不发布一个更小的模型来显示问题?
  • strides=(1,1)padding='same' 的组合负责在 conv2d 层中保持大小相同。您希望图层形状是什么?
  • 我希望图层形状从 256 --> 128 --> 64 --> 32 --> 16 等减小,大小应该减小,对吧?如果我从 MaxPooling2D 图层中删除填充,则会出现形状错误,但 strides = (2, 2) 解决了@Nicolas Gervais 回答的问题。
  • 好好想想吧。使用strides=(2,2),您每次在 x 和 y 方向上移动卷积窗口时都会滑动两个单位,这当然会产生一个输入宽度和高度一半的输出......

标签: python tensorflow keras deep-learning conv-neural-network


【解决方案1】:

使用strides=(2, 2) 或将其留空。然后,max_pooling2d 将起作用。可训练参数的数量将显着减少。如果未指定,max_pooling2d 将默认为 pool_size。请参阅docs

【讨论】:

  • 非常感谢!我忘记了我将 stride 参数设置为 (1, 1),它通常默认为什么?设置 strides = (2, 2) 可以立即解决问题!可训练参数的数量也减少了。
猜你喜欢
  • 2017-02-10
  • 1970-01-01
  • 1970-01-01
  • 2018-02-27
  • 2020-03-08
  • 2017-05-25
  • 2020-08-17
  • 2019-01-08
  • 2018-04-22
相关资源
最近更新 更多