训练一个具有可变大小的输入的完全卷积神经网络在Keras/Tensorflow中需要不合理的时间



我正在尝试实现一个可以接受可变大小输入的图像分类的FCNN。该模型是在带有TensorFlow后端的Keras中构建的。

考虑以下玩具示例:

model = Sequential()
# width and height are None because we want to process images of variable size 
# nb_channels is either 1 (grayscale) or 3 (rgb)
model.add(Convolution2D(32, 3, 3, input_shape=(nb_channels, None, None), border_mode='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(32, 3, 3, border_mode='same'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(16, 1, 1))
model.add(Activation('relu'))
model.add(Convolution2D(8, 1, 1))
model.add(Activation('relu'))
# reduce the number of dimensions to the number of classes
model.add(Convolution2D(nb_classses, 1, 1))
model.add(Activation('relu'))
# do global pooling to yield one value per class
model.add(GlobalAveragePooling2D())
model.add(Activation('softmax'))

这个模型运行良好,但我遇到了性能问题。与固定尺寸的输入相比,对可变大小的图像进行培训需要不合理的时间。如果我将所有图像大小调整到数据集中的最大尺寸,那么训练模型的时间仍然要比可变大小输入的训练要少得多。那么input_shape=(nb_channels, None, None)是指定变量大小输入的正确方法吗?有什么方法可以缓解这种绩效问题?

update

model.summary()用于具有3个类和灰度图像的型号:

Layer (type)                     Output Shape          Param #     Connected to                     
====================================================================================================
convolution2d_1 (Convolution2D)  (None, 32, None, None 320         convolution2d_input_1[0][0]      
____________________________________________________________________________________________________
activation_1 (Activation)        (None, 32, None, None 0           convolution2d_1[0][0]            
____________________________________________________________________________________________________
maxpooling2d_1 (MaxPooling2D)    (None, 32, None, None 0           activation_1[0][0]               
____________________________________________________________________________________________________
convolution2d_2 (Convolution2D)  (None, 32, None, None 9248        maxpooling2d_1[0][0]             
____________________________________________________________________________________________________
maxpooling2d_2 (MaxPooling2D)    (None, 32, None, None 0           convolution2d_2[0][0]            
____________________________________________________________________________________________________
convolution2d_3 (Convolution2D)  (None, 16, None, None 528         maxpooling2d_2[0][0]             
____________________________________________________________________________________________________
activation_2 (Activation)        (None, 16, None, None 0           convolution2d_3[0][0]            
____________________________________________________________________________________________________
convolution2d_4 (Convolution2D)  (None, 8, None, None) 136         activation_2[0][0]               
____________________________________________________________________________________________________
activation_3 (Activation)        (None, 8, None, None) 0           convolution2d_4[0][0]            
____________________________________________________________________________________________________
convolution2d_5 (Convolution2D)  (None, 3, None, None) 27          activation_3[0][0]               
____________________________________________________________________________________________________
activation_4 (Activation)        (None, 3, None, None) 0           convolution2d_5[0][0]            
____________________________________________________________________________________________________
globalaveragepooling2d_1 (Global (None, 3)             0           activation_4[0][0]               
____________________________________________________________________________________________________
activation_5 (Activation)        (None, 3)             0           globalaveragepooling2d_1[0][0]   
====================================================================================================
Total params: 10,259
Trainable params: 10,259
Non-trainable params: 0

我认为 @marcin-moêjko在他的评论中可能有正确的答案。它可能与此错误有关,该错误是固定的。如果要经常汇编事情,可能会警告您。

因此,升级到TF-nightly-GPU-2.0-preview软件包可能会解决此问题。另外,您是否有tf.keras的问题。

如果我将所有图像大小调整到数据集中的最大尺寸,那么训练模型的时间仍然要比训练尺寸输入

要少得多。

请注意,对于具有"相同"填充的基本卷积,零填充物应对输出具有"无"影响,除了像素对齐。

因此,一种方法是在固定尺寸列表中训练这些尺寸的尺寸和零垫图像。例如,在128x128、256x256、512x512的批次上进行训练。如果您无法修复动态汇编内容,至少只能将其编译3次。这有点像2D"逐序长度"的方法有时使用序列模型看到。

不同尺寸的图像意味着在不同规模上的相似事物的图像。如果规模上的差异很大,那么随着图像大小的减小,相似事物的相对位置将从位于框架的中心向左上角转移。所示的(简单)网络体系结构在空间上意识到,因此,由于模型收敛速率降级的速率是一致的,因为截然不同的数据将不一致。这种体系结构不太适合在不同或多个地方找到同一件事。

一定程度的剪切,旋转,镜像将有助于模型概括,但重新尺寸为一致。因此,当您重新尺寸时,请修复缩放问题并使输入数据在空间上保持一致。

简而言之,我认为这是该网络体系结构不适合您提供的任务,即各种规模。

最新更新