我正在尝试微调vgg16(imagenet pretrained)的最后一个卷积块,顶部添加了几个密集层。我的代码如下。我无法弄清楚为什么在执行Error when checking target: expected sequential_9 to have shape (None, 11) but got array with shape (4, 1)
时出现此错误。我的数据集中的类数是11,批量大小是4.我是否以某种方式混合这两个类?请帮忙。
def finetune( epochs):
num_classes = 11
batch_size = 4
base_model = VGG16(weights='imagenet', include_top=False, input_shape = (224,224,3))
print('Model loaded.')
print(base_model.output_shape[1:])
top_model = Sequential()
top_model.add(Flatten(input_shape=base_model.output_shape[1:]))
top_model.add(Dense(512, activation='relu',kernel_regularizer=regularizers.l2(0.01)))
top_model.add(Dropout(0.25))
top_model.add(Dense(256, activation='relu', kernel_regularizer=regularizers.l2(0.01)))
top_model.add(Dropout(0.25))
top_model.add(Dense(num_classes, activation='softmax'))
top_model.load_weights('vgg_ft_best.h5')
# add the model on top of the convolutional base
#model = Model(inputs= base_model.input, outputs= top_model(base_model.output))
#base_model.add(top_model)
#print(base_model.summary())
new_model = Sequential()
for l in base_model.layers:
new_model.add(l)
# CONCATENATE THE TWO MODELS
new_model.add(top_model)
print(new_model.summary())
# set the first 10 layers (up to the last conv block)
# to non-trainable (weights will not be updated)
for layer in new_model.layers[:11]:
layer.trainable = False
# prepare data augmentation configuration
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
train_data_dir = "./images/train"
validation_data_dir = "./images/validation"
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(224, 224),
batch_size=batch_size,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(224, 224),
batch_size=batch_size,
class_mode='binary')
num_train_samples = len(train_generator.filenames)
num_validation_samples = len(validation_generator.filenames)
print(num_validation_samples)
new_model.compile(loss='categorical_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metrics=['accuracy'])
# fine-tune the model
new_model.fit_generator(
train_generator,
steps_per_epoch=int(num_train_samples/batch_size),
epochs=epochs,
validation_data=validation_generator,
validation_steps = int(num_validation_samples/batch_size))
答案 0 :(得分:0)
问题在于您的数据(目标=真实输出,真实标签等)。
您的目标的形状为(batch,1)
,您的11个类的模型期待(batch,11)
所以,问题出在你的发电机上。它必须输出11个类的张量。
为此,请参阅the documentation for flow_from_directory
和突出显示的部分:
类:类子目录的可选列表(例如['dogs','cats'])。默认值:无。如果没有提供,类列表将从目录下的子目录名称/结构自动推断,其中每个子目录将被视为不同的类(以及将映射到的类的顺序)标签索引,将是字母数字)。包含从类名到类索引的映射的字典可以通过属性class_indices获得。
class_mode :“分类”,“二进制”,“稀疏”,“输入”或无之一。默认值:“分类”。确定返回的标签数组的类型:“分类”将是2D单热编码标签,“二进制”将是1D二进制标签,“稀疏”将是1D整数标签,“输入”将是与输入图像相同的图像(主要用于与自动编码器一起使用)。如果为None,则不返回任何标签(生成器将仅生成批量的图像数据,这对使用model.predict_generator(),model.evaluate_generator()等很有用)。请注意,如果class_mode为None,则数据仍需要驻留在目录的子目录中,以使其正常工作。
<强>解决方案强>
class_mode='categorical'
来获得(batch,11)
格式。 现在,如果您的类不是分类的(一个图像可以有两个或更多类),那么您需要创建自己的自定义生成器。