如何在keras中提供可变大小的图像作为输入

Hit*_*esh 4 machine-learning image-processing neural-network deep-learning keras

我正在使用带有tensorflow后端的keras编写两个类别的图像分类代码。我的图像存储在计算机的文件夹中,我想将这些图像作为我的keras模型的输入。load_img我只需要一个输入图像,所以我必须使用flow(x,y)flow_from_directory(directory),但是flow(x,y)我们还需要提供标签,这是长度任务,所以我正在使用flow_from_directory(directory)。我的图像大小可变,例如20 * 40、55 * 43 .....,但是这里提到需要固定的target_size。在解决方案中,我们可以使用以下方法将可变大小的图像作为卷积层的输入input_shape=(1, None, None)或input_shape =(None,None,3)(最后一个通道和彩色图像),但fchollet提到它对平坦层没有用,我的模型同时包括卷积层和平坦层。在那篇文章中,只有moi90建议尝试不同的批次,但是每个批次都应具有相同大小的图像,但是由于我的数据非常分散,因此无法对相同尺寸的图像进行分组。所以我决定去batch size=1写下面的代码:

from __future__ import print_function
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
from keras import backend as K
import numpy as np
from keras.preprocessing.image import ImageDataGenerator

input_shape = (None,None,3)

model = Sequential()
model.add(Conv2D(8, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=input_shape))
model.get_weights()
model.add(Conv2D(16, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax'))

model.compile(loss='binary_crossentropy',optimizer='rmsprop',metrics=['accuracy'])

train_datagen = ImageDataGenerator()
test_datagen = ImageDataGenerator()
train_generator = train_datagen.flow_from_directory('/data/train', target_size=input_shape, batch_size=1,class_mode='binary') 
validation_generator = test_datagen.flow_from_directory('/data/test',target_size=input_shape,batch_size=1,class_mode='binary')
model.fit_generator(train_generator,steps_per_epoch=1,epochs=2,validation_data=validation_generator,validation_steps=1)
Run Code Online (Sandbox Code Playgroud)

现在我得到以下错误:

Traceback (most recent call last):

  File "<ipython-input-8-4e22d22e4bd7>", line 23, in <module>
    model.add(Flatten())

  File "/home/nd/anaconda3/lib/python3.6/site-packages/keras/models.py", line 489, in add
    output_tensor = layer(self.outputs[0])

  File "/home/nd/anaconda3/lib/python3.6/site-packages/keras/engine/topology.py", line 622, in __call__
    output_shape = self.compute_output_shape(input_shape)

  File "/home/nd/anaconda3/lib/python3.6/site-packages/keras/layers/core.py", line 478, in compute_output_shape
    '(got ' + str(input_shape[1:]) + '. '

ValueError: The shape of the input to "Flatten" is not fully defined (got (None, None, 16). Make sure to pass a complete "input_shape" or "batch_input_shape" argument to the first layer in your model.
Run Code Online (Sandbox Code Playgroud)

我相信这是不是因为img_dim_orderingbackend而是因为这个我检查都是th请帮助纠正他的代码或如何帮助我可以给可变大小的图像输入到我的模型。

Dan*_*ler 6

您可以训练变量大小,只要您不尝试将变量大小放入numpy数组中即可。

但是某些图层不支持可变大小,Flatten而是其中之一。不可能训练包含可变大小的Flatten图层的模型。

你可以试试,不过,与无论是更换展平层GlobalMaxPooling2DGlobalAveragePooling2D层。但是这些层可能会将太多的信息压缩为少量数据,因此可能有必要在它们之前的更多通道中添加更多卷积。

但是,您必须确保生成器将生成包含相同大小图像的批处理。尝试将两个或多个具有不同大小的图像放入同一numpy数组时,生成器将失败。


Dro*_*man 5

请参阅https://github.com/keras-team/keras/issues/1920中的答案哟 ,您应该将输入更改为:

input = Input(shape=(None, None,3))
Run Code Online (Sandbox Code Playgroud)

最后添加GlobalAveragePooling2D()

尝试类似的事情......

input = Input(shape=(None, None,3))

model = Sequential()
model.add(Conv2D(8, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=(None, None,3)))  #Look on the shape
model.add(Conv2D(16, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
# IMPORTANT !
model add(GlobalAveragePooling2D())
# IMPORTANT !
model.add(Flatten())
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax'))

model.compile(loss='binary_crossentropy',optimizer='rmsprop',metrics=['accuracy'])
Run Code Online (Sandbox Code Playgroud)


Ioa*_*ios 4

不幸的是,你无法用各种尺寸的图像来训练神经网络。您必须将所有图像调整为给定尺寸。幸运的是,您不必在硬盘上执行此操作,keras 会永久为您实时执行此操作。

在 flow_from_directory 中,您应该定义一个 target_size ,如下所示:

train_generator = train_datagen.flow_from_directory(
    'data/train',
    target_size=(150, 150), #every image will be resized to (150,150) before fed to neural network
    batch_size=32,
    class_mode='binary')
Run Code Online (Sandbox Code Playgroud)

另外,如果你这样做,你可以拥有任何你想要的批量大小。