我正在使用带有张量流后端的keras编写两个类的图像分类代码。我的图像存储在计算机的文件夹中,我想将这些图像作为输入提供给我的keras模型。 load_img
只需要一个输入图片,因此我必须使用flow(x,y)
或flow_from_directory(directory)
,但在flow(x,y)
我们还需要提供长度为任务的标签,以便我使用{ {1}}。我的图像是可变大小的,如20 * 40,55 * 43 .....但here提到固定的target_size是必需的。在this解决方案中,我们可以使用flow_from_directory(directory)
或input_shape =(无,无,3)(通道最后和彩色图像)将可变大小的图像作为卷积层的输入,但fchollet提到它对于展平图层没用,我的模型包括卷积和展平图层。在该帖子中,只有moi90建议尝试不同的批次,但每个批次应该具有相同大小的图像,但我不可能对具有相同大小的图像进行分组,因为我的数据非常分散。所以我决定选择input_shape=(1, None, None)
并编写以下代码:
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_ordering
而是因为this我检查了backend
请帮助纠正他的代码或帮助我可以将可变大小的图像作为我模型的输入。
答案 0 :(得分:5)
您可以训练可变大小,只要您不尝试将变量大小放在numpy数组中。
但有些图层不支持可变尺寸,而Flatten
就是其中之一。训练包含可变尺寸的Flatten图层的模型是不可能的。
但是,您可以尝试使用GlobalMaxPooling2D
或GlobalAveragePooling2D
图层替换Flatten图层。但是这些层可能会将过多的信息压缩成一个小数据,因此可能需要在它们之前添加更多包含更多通道的卷积。
但是,您必须确保您的生成器将生成包含相同大小的图像的批次。尝试在同一个numpy数组中放入两个或多个不同大小的图像时,生成器将失败。
答案 1 :(得分:3)
不幸的是,你无法训练具有各种尺寸图像的神经网络。您必须将所有图像调整为给定大小。幸运的是,您不必在您的硬盘中执行此操作,由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')
此外,如果您这样做,您可以拥有您想要的任何批量大小。
答案 2 :(得分:0)
在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'])