我想在Keras中使用InceptionV3来进行转移学习的瓶颈。 我已经使用了一些关于创建,加载和使用瓶颈的技巧 https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html
我的问题是我不知道如何使用瓶颈(numpy数组)作为带有新顶层的InceptionV3的输入。
我收到以下错误:
ValueError:检查输入时出错:期望input_3有形状 (无,无,无,3)但是有形状的数组(248,8,8,2048)
248是指这种情况下的图像总数。
我知道这条线错了,但我不知道如何纠正它:
model = Model(inputs = base_model.input,outputs = predictions)
将瓶颈输入InceptionV3的正确方法是什么?
创建InceptionV3瓶颈:
def create_bottlenecks():
datagen = ImageDataGenerator(rescale=1. / 255)
model = InceptionV3(include_top=False, weights='imagenet')
# Generate bottlenecks for all training images
generator = datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode=None,
shuffle=False)
nb_train_samples = len(generator.filenames)
bottlenecks_train = model.predict_generator(generator, int(math.ceil(nb_train_samples / float(batch_size))), verbose=1)
np.save(open(train_bottlenecks_file, 'w'), bottlenecks_train)
# Generate bottlenecks for all validation images
generator = datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode=None,
shuffle=False)
nb_validation_samples = len(generator.filenames)
bottlenecks_validation = model.predict_generator(generator, int(math.ceil(nb_validation_samples / float(batch_size))), verbose=1)
np.save(open(validation_bottlenecks_file, 'w'), bottlenecks_validation)
加载瓶颈:
def load_bottlenecks(src_dir, bottleneck_file):
datagen = ImageDataGenerator(rescale=1. / 255)
generator = datagen.flow_from_directory(
src_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
shuffle=False)
num_classes = len(generator.class_indices)
# load the bottleneck features saved earlier
bottleneck_data = np.load(bottleneck_file)
# get the class lebels for the training data, in the original order
bottleneck_class_labels = generator.classes
# convert the training labels to categorical vectors
bottleneck_class_labels = to_categorical(bottleneck_class_labels, num_classes=num_classes)
return bottleneck_data, bottleneck_class_labels
开始培训:
def start_training():
global nb_train_samples, nb_validation_samples
create_bottlenecks()
train_data, train_labels = load_bottlenecks(train_data_dir, train_bottlenecks_file)
validation_data, validation_labels = load_bottlenecks(validation_data_dir, validation_bottlenecks_file)
nb_train_samples = len(train_data)
nb_validation_samples = len(validation_data)
base_model = InceptionV3(weights='imagenet', include_top=False)
# add a global spatial average pooling layer
x = base_model.output
x = GlobalAveragePooling2D()(x)
# let's add a fully-connected layer
x = Dense(1024, activation='relu')(x)
# and a logistic layer -- let's say we have 2 classes
predictions = Dense(2, activation='softmax')(x)
# What is the correct input? Obviously not base_model.input.
model = Model(inputs=base_model.input, outputs=predictions)
# first: train only the top layers (which were randomly initialized)
# i.e. freeze all convolutional InceptionV3 layers
for layer in base_model.layers:
layer.trainable = False
model.compile(optimizer=optimizers.SGD(lr=0.01, momentum=0.9), loss='categorical_crossentropy', metrics=['accuracy'])
# train the model on the new data for a few epochs
history = model.fit(train_data, train_labels,
epochs=epochs,
batch_size=batch_size,
validation_data=(validation_data, validation_labels),
)
任何帮助将不胜感激!
答案 0 :(得分:4)
当您尝试使用与模型支持的形状不同的输入数据训练模型时,会发生此错误。
您的模型支持(None, None, None, 3)
,意思是:
因此,您必须确保train_data
(和validation_data
)符合此形状。
系统告诉train_data.shape = (248,8,8,2048)
我看到train_data
来自load_botlenecks
。真的应该来自那里吗?什么是火车数据应该是什么?一个图像?别的什么?什么是瓶颈?
您的模型从Inception模型开始,Inception模型拍摄图像。
但是,如果瓶颈已经是Inception模型的结果,并且您想要仅提供 瓶颈,那么Inception模型就不应该参与任何事情。
从:
开始inputTensor = Input((8,8,2048)) #Use (None,None,2048) if bottlenecks vary in size
x = GlobalAveragePooling2D()(inputTensor)
.....
使用以下命令创建模型:
model = Model(inputTensor, predictions)
这个想法是:
只有在您没有预先加载瓶颈的情况下才需要组合这两种模型,但是您有自己的图像需要先预测瓶颈。 (当然你也可以使用不同的模型)
然后你将只输入图像(瓶颈将由Inception创建并传递给你的模型,内部的一切):
为此:
inputImage = Input((None,None,3))
bottleNecks = base_model(inputImage)
predictions = model(bottleNecks)
fullModel = Model(inputImage, predictions)