我已经使用VGG16预训练模型训练了一个模型,以将4种类型的眼部疾病分类。我是机器学习的新手,所以不知道从结果中得出什么。 在对90,000张图像进行约6个小时的训练后:
训练精度不断提高,同时损失也不断增加(从大约2降低到0.8最终达到88%的精度)
验证损失持续在每个时期1-2之间波动(准确性确实提高到85%) (我不小心重新运行了单元,所以看不到输出)
查看混乱矩阵后,看来我的测试表现不佳
Image_height = 196
Image_width = 300
val_split = 0.2
batches_size = 10
lr = 0.0001
spe = 512
vs = 32
epoch = 10
#Creating batches
#Creating batches
train_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input,validation_split=val_split) \
.flow_from_directory(directory=train_folder, target_size=(Image_height,Image_width), classes=['CNV','DME','DRUSEN','NORMAL'], batch_size=batches_size,class_mode="categorical",
subset="training")
validation_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input,validation_split=val_split) \
.flow_from_directory(directory=train_folder, target_size=(Image_height,Image_width), classes=['CNV','DME','DRUSEN','NORMAL'], batch_size=batches_size,class_mode="categorical",
subset="validation")
test_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input) \
.flow_from_directory(test_folder, target_size=(Image_height,Image_width),
classes=['CNV','DME','DRUSEN','NORMAL'], batch_size=batches_size,class_mode="categorical")
#Function to create model. We will be using a pretrained model
def create():
vgg16_model = keras.applications.vgg16.VGG16(input_tensor=Input(shape=(Image_height, Image_width, 3)),input_shape=(Image_height,Image_width,3), include_top = False)
model = Sequential()
model.add(vgg16_model)
for layer in model.layers:
layer.trainable = False
model.add(Flatten())
model.add(Dense(4, activation='softmax'))
return model
model = create()
model.compile(Adam(lr=lr),loss="categorical_crossentropy",metrics=['accuracy'])
model.fit(train_batches, steps_per_epoch=spe,
validation_data=validation_batches,validation_steps=vs, epochs=epoch)
关于我可以改进的任何建议,以免混淆矩阵的效果不佳?如果可能的话,还可以保存更多的模型来保存模型。
答案 0 :(得分:1)
除了最后一层外,您不训练其他任何层。 您需要将训练功能设置为最后几层或添加更多层。
添加
tf.keras.applications.VGG16(... weights='imagenet'... )
在您的代码中,权重没有预先设置在任何集合上。
此处说明了可用的选项:
https://www.tensorflow.org/api_docs/python/tf/keras/applications/VGG16
答案 1 :(得分:1)
许多问题和建议。您正在使用VGG16模型。该模型具有超过4000万个可训练参数。在90,000张图像的数据集上,您的训练时间将非常长。因此,我建议您考虑使用MobileNet模型。它仅具有400万个可训练参数,并且实质上与VGG16一样精确。接下来是文档[此处。] [1],无论使用哪种模型,都应将初始权重设置为imagenet权重。您的模型将开始在图像上进行训练。我发现通过使模型中的所有层都可训练,可以获得更好的结果。现在您说您的模型达到了88%的准确性。我认为那不是很好。我相信您至少需要达到95%。您可以通过调整学习率来做到这一点。 keras回调ReduceLROnPlateau使此操作变得容易。文档在[here。] [2]进行设置,以监视验证丢失并降低学习率(如果在连续时期内学习率下降的话)。接下来,您要保存验证损失最少的模型,然后使用该模型进行预测。可以设置Keras回调ModelCheckpoint来监视验证损失,并以最低的损失保存模型。文档在[here。] [3]中。 下面的代码显示了如何为您的问题实现MobileNet模型并定义回调。您还必须更改生成器以使用Mobilenet预处理并将目标大小设置为(224,224)。另外,我相信您在预处理功能周围缺少(),希望对您有所帮助。
mobile = tf.keras.applications.mobilenet.MobileNet( include_top=False,
input_shape=(224, 224,3),
pooling='max', weights='imagenet',
alpha=1, depth_multiplier=1,dropout=.5)
x=mobile.layers[-1].output
x=keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001 )(x)
predictions=Dense (4, activation='softmax')(x)
model = Model(inputs=mobile.input, outputs=predictions)
for layer in model.layers:
layer.trainable=True
model.compile(Adamax(lr=lr), loss='categorical_crossentropy', metrics=['accuracy'])
checkpoint=tf.keras.callbacks.ModelCheckpoint(filepath=save_loc, monitor='val_loss', verbose=0, save_best_only=True,
save_weights_only=False, mode='auto', save_freq='epoch', options=None)
lr_adjust=tf.keras.callbacks.ReduceLROnPlateau( monitor="val_loss", factor=0.5, patience=1, verbose=0, mode="auto",
min_delta=0.00001, cooldown=0, min_lr=0)
callbacks=[checkpoint, lr_adjust]
[1]: http://httphttps://keras.io/api/applications/mobilenet/s://
[2]: https://keras.io/api/callbacks/reduce_lr_on_plateau/
[3]: https://keras.io/api/callbacks/model_checkpoint/
答案 2 :(得分:0)
在向模型添加层时,您必须删除模型的最后一个密集层,因为您的模型有四个类,但 vgg16 有 1000 个类,因此您必须删除最后一个密集层,然后添加您自己的密集层:
def create():
vgg16_model = keras.applications.vgg16.VGG16(input_tensor=Input(shape=(Image_height, Image_width, 3)),input_shape=(Image_height,Image_width,3), include_top = False)
model = Sequential()
for layer in vgg16_model.layers[:-1]:
model.add(layer)
model.summary()
for layer in model.layers:
layer.trainable = False
model.add(Flatten())
model.add(Dense(4, activation='softmax'))
return model