首页 文章

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

提问于
浏览
3

我正在使用带有张量流后端的keras编写两个类的图像分类代码 . 我的图像存储在计算机的文件夹中,我想将这些图像作为输入提供给我的keras模型 . load_img 只需要一个输入图像,所以我必须使用 flow(x,y)flow_from_directory(directory) ,但在 flow(x,y) 中我们还需要提供长度任务的标签,所以我使用 flow_from_directory(directory) . 我的图像是可变大小,如20 * 40,55 * 43 .....但here提到固定的target_size是必需的 . 在this解决方案中,我们可以使用 input_shape=(1, None, None) 或input_shape =(无,无,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)

现在我收到以下错误:

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.

我确定这不是因为 img_dim_orderingbackend 而是因为this我检查了两个都是 th 请帮助纠正他的代码或帮助我如何将可变大小的图像作为我的模型的输入 .

3 回答

  • 5

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

    但有些图层不支持可变尺寸, Flatten 就是其中之一 . 训练包含可变尺寸的Flatten图层的模型是不可能的 .

    但是,您可以尝试使用 GlobalMaxPooling2DGlobalAveragePooling2D 图层替换Flatten图层 . 但是这些层可能会将过多的信息压缩成一个小数据,因此可能需要在它们之前添加更多包含更多通道的卷积 .

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

  • 0

    遗憾的是,您无法训练具有各种大小图像的神经网络 . 您必须将所有图像调整为给定大小 . 幸运的是,您不必在您的硬盘中执行此操作,由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')
    

    此外,如果您这样做,您可以拥有所需的任何批量大小 .

  • 3

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

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

    最后添加 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'])
    

相关问题