我有一个大数据集和大量扩充,因此我依靠keras.utils.Sequence
生成器并让Keras进行多处理。因此,对于可变的输入大小,使用简单的model.fit(...)
命令对我来说是没有选择的。此外,由于我的特定问题,调整图像大小或填充图像不是一个好主意。
由于BatchNormalization Layers,也选择批次大小为1的方法不是很方便。
我的图像尺寸可变,并创建了一个玩具问题示例:
from keras.applications.vgg16 import VGG16 as model
from keras.utils import Sequence
import numpy as np
from keras.layers import Input, Flatten, Dense, GlobalAveragePooling2D
from keras.models import Model
CLASSES = 10
class ExampleGenerator(Sequence):
def __init__(self,dataset_length=100,batch_size=8):
self.dataset_length = dataset_length
self.batch_size = batch_size
def __len__(self):
return int(np.ceil(self.dataset_length / float(self.batch_size)))
def __getitem__(self,idx):
# create random targets
Y_batch = np.random.randint(0,2,size=(self.batch_size,CLASSES))
X = []
for i in range(self.batch_size):
# create a random image with a random size
width = np.random.randint(64,256)
height = np.random.randint(64,256)
img = np.random.rand(width,height,3)
X.append(img)
X_batch = np.array(X)
return X_batch,Y_batch
gen = ExampleGenerator()
input_tensor = Input(shape=(None, None, 3))
base_model = model(input_tensor=input_tensor,weights=None, include_top=False)
output = base_model.output
x = GlobalAveragePooling2D()(output)
x = Dense(512)(x)
predictions = Dense(CLASSES)(x)
model = Model(inputs=base_model.input, outputs=predictions)
model.compile(optimizer='adam', loss='categorical_crossentropy')
model.fit_generator(gen)
请注意,此示例仅是为了重现我的问题。
如果执行脚本,将提示跟随错误消息:
ValueError:检查输入时出错:预期input_2具有4 尺寸,但数组的形状为(8,1)
这当然是由于__getitem__
返回的numpy arry而只有batch_size为固定大小。
当列表X
未转换为numpy数组时,会发生其他错误:
ValueError:检查模型输入时出错:Numpy数组的列表 您传递给模型的信息不是模型期望的大小。 预计将看到1个数组,但得到以下8个列表 数组:
那么,如何使用keras生成器来改变输入大小?
谢谢您的帮助
答案 0 :(得分:3)
对于可变大小的图像,不能使用batch_size大于1的图像。如果您正在使用可变大小的图像,并且要发送大于一个的批量大小,则应固定模型输入的尺寸,并添加一些填充以在生成器中达到该固定尺寸。
答案 1 :(得分:0)
尝试使用
X_batch = np.asarray(X)