我是机器学习的新手。我正在关注这个Keras 博客来使用 Keras 训练图像分类器。尽管此博客仅演示了如何使用 binary_crossentropy 仅训练两个类,但我希望使用我自己的自定义多类 (6) 图像数据集使用 categorial_crossentropy 和一个热编码向量来训练模型。所以,这是我到目前为止所尝试的:
import os
import numpy as np
from keras import applications
from keras import Model
from keras.models import Sequential
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.layers import Input
from keras.preprocessing.image import ImageDataGenerator, img_to_array, load_img
from keras import optimizers
import cv2
img_width, img_height = 150, 150
class_indics = 'class_indices.npy'
bottleneck_train_path = 'bottleneck_features_train.npy'
bottleneck_validation_path = 'bottleneck_features_validation.npy'
top_model_weights_path = 'bottleneck_fc_model.h5'
train_data_dir = 'data/train'
validation_data_dir = 'data/validation/'
nb_train_samples = 4800
nb_validation_samples = 1200
epochs = 50
batch_size = 15
def generate_class_indics():
datagen = ImageDataGenerator(rescale=1. / 255)
generator_top = datagen.flow_from_directory(train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
shuffle=False)
# save the class indices to use later in predictions
np.save(class_indics, generator_top.class_indices)
def save_bottleneck_features():
print('Using of bottleneck feature on pretrained model started.')
datagen = ImageDataGenerator(rescale=1. / 255)
# build the VGG16 network
model = applications.VGG16(include_top=False, weights='imagenet')
generator = datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
shuffle=False)
bottleneck_features_train = model.predict_generator(
generator, nb_train_samples // batch_size)
np.save(open(bottleneck_train_path, 'wb'),
bottleneck_features_train)
generator = datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
shuffle=False)
bottleneck_features_validation = model.predict_generator(
generator, nb_validation_samples // batch_size)
np.save(open(bottleneck_validation_path, 'wb'),
bottleneck_features_validation)
print('Using of bottleneck feature on pretrained model finished.')
def train_top_model():
print('Training of top model started.')
train_data = np.load(open(bottleneck_train_path, 'rb'))
train_labels = np.array(
[0] * (nb_train_samples // 2) + [1] * (nb_train_samples // 2))
validation_data = np.load(open(bottleneck_validation_path, 'rb'))
validation_labels = np.array(
[0] * (nb_validation_samples // 2) + [1] * (nb_validation_samples // 2))
class_dictionary = np.load('class_indices.npy').item()
num_classes = len(class_dictionary)
model = Sequential()
model.add(Flatten(input_shape=train_data.shape[1:]))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.7))
model.add(Dense(num_classes, activation='softmax')) #sigmoid
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy', metrics=['categorical_accuracy'])
model.fit(train_data, train_labels,
epochs=epochs,
batch_size=batch_size,
validation_data=(validation_data, validation_labels))
model.save_weights(top_model_weights_path)
print('Training of top model completed & saved as: ',top_model_weights_path)
def fine_tune_pretrained_model():
print('Fine tuning of pretrain model started.')
# build the VGG16 network
input_tensor = Input(shape=(150, 150, 3))
base_model = applications.VGG16(weights='imagenet', include_top=False, input_tensor=input_tensor)
class_dictionary = np.load('class_indices.npy').item()
num_classes = len(class_dictionary)
# build a classifier model to put on top of the convolutional model
top_model = Sequential()
top_model.add(Flatten(input_shape=base_model.output_shape[1:]))
top_model.add(Dense(256, activation='relu'))
top_model.add(Dropout(0.7))
top_model.add(Dense(num_classes, activation='softmax')) #sigmoid
# note that it is necessary to start with a fully-trained
# classifier, including the top classifier,
# in order to successfully do fine-tuning
top_model.load_weights(top_model_weights_path)
# add the model on top of the convolutional base
model = Model(inputs=base_model.input, outputs=top_model(base_model.output))
# set the first 25 layers (up to the last conv block)
# to non-trainable (weights will not be updated)
for layer in model.layers[:25]:
layer.trainable = False
# compile the model with a SGD/momentum optimizer
# and a very slow learning rate.
model.compile(loss='categorical_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metrics=['categorical_accuracy'])
# prepare data augmentation configuration
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
# fine-tune the model
model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size, # samples_per_epoch=nb_train_samples,
epochs=epochs,
validation_data=validation_generator,
validation_steps=nb_validation_samples)
print('Fine tuning of pretrain model completed.')
if __name__ == '__main__':
if not os.path.exists(class_indics):
generate_class_indics()
if not os.path.exists(bottleneck_train_path):
save_bottleneck_features()
if not os.path.exists(top_model_weights_path):
train_top_model()
fine_tune_pretrained_model()
当我运行此代码save_bottleneck_features()并train_top_model()正确执行时,但是当我尝试运行时,fine_tune_pretrained_model()它给了我这个错误:
回溯(最近一次调用最后):文件“/home/appsbee/PycharmProjects/fruit-classification-master/fruit-classification-master/fruit_classification_new.py”,第 266 行,在fine_tune_pretrained_model() 文件“/home/appsbee/PycharmProjects/ fruit-classification-master/fruit-classification-master/fruit_classification_new.py”,第 159 行,fine_tune_pretrained_model top_model.load_weights(top_model_weights_path) 文件“/usr/local/lib/python3.6/dist-packages/keras/engine/network .py”,第 1166 行,在 load_weights f,self.layers,reshape=reshape) 文件“/usr/local/lib/python3.6/dist-packages/keras/engine/saving.py”,第 1036 行,在 load_weights_from_hdf5_group str(len(filtered_layers)) + 'layers.') ValueError:您正在尝试将包含 3 层的权重文件加载到具有 2 层的模型中。
但我可以看到没有添加额外的图层fine_tune_pretrained_model()。
那么,为什么我会收到此错误?任何帮助将不胜感激。