深度学习第四周,猴痘识别

第四周,猴痘识别

🍺要求:

训练过程中保存效果最好的模型参数。
加载最佳模型参数识别本地的一张图片。
测试集accuracy到达88%。
参考文章: https://blog.csdn.net/qq_38251616/article/details/126284706
作者:K同学啊
本文为360天深度学习训练营中的学习记录博客

一、前期工作

import pathlib
from tensorflow import keras
from tensorflow.keras import models,layers
import matplotlib.pyplot as plt
import tensorflow as tf

1、导入数据`

data_dir = 'D:\AIoT学习\深度学习训练营\第四周\pictures'
data_dir = pathlib.Path(data_dir)

该文章数据为训练内部数据集

2、查看数据

image_count = len(list(data_dir.glob('*/*.jpg')))
print('图片总数为',image_count)

图片总数为 2142

import PIL
monkeypox = list(data_dir.glob('Monkeypox/*.jpg'))
PIL.Image.open(str(monkeypox[0]))

二、数据预处理

1、加载数据

使用image_dataset_from_directory方法将磁盘中的数据加载到tf.data.Dataset中,与上周一样
测试集与验证集的关系:

    1. 验证集并没有参与训练过程梯度下降过程的,狭义上来讲是没有参与模型的参数训练更新的。
    1. 但是广义上来讲,验证集存在的意义确实参与了一个“人工调参”的过程,我们根据每一个epoch训练之后模型在valid data上的表现来决定是否需要训练进行early stop,或者根据这个过程模型的性能变化来调整模型的超参数,如学习率,batch_size等等。
    1. 因此,我们也可以认为,验证集也参与了训练,但是并没有使得模型去overfit验证集
img_height = 224
img_width = 224
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
            data_dir,
            validation_split=0.2,
            subset='training',
            seed=123,
            image_size=(img_height,img_width))

Found 2142 files belonging to 2 classes.
Using 1714 files for training.

class_names = train_ds.class_names
print(class_names)

[‘Monkeypox’, ‘Others’]

val_ds = tf.keras.preprocessing.image_dataset_from_directory(
            data_dir,
            validation_split=0.2,
            subset='validation',
            seed=123,
            image_size=(img_height,img_width))

Found 2142 files belonging to 2 classes.
Using 428 files for validation.

2、可视化数据

plt.figure(figsize=(20,10))
for image,labels in train_ds.take(1):
    for i in range(20):
        plt.subplot(5,10,i+1)
        plt.imshow(image[i].numpy().astype('uint8'))#变量存储为 1 个字节(8 位)的无符号整数
        plt.title(class_names[labels[i]])
        
        plt.axis('off')

3、再次检查数据`

for image_batch,labels_batch in train_ds:
    print(image_batch.shape)   #每批图片的shape
    print(labels_batch.shape) #每批图片对应label的shape
    break

(32, 224, 224, 3)
(32,)

4、配置数据

AUTOTUNE = tf.data.AUTOTUNE

train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)

三、构建CNN网络

num_classes = 2


model = models.Sequential([
            layers.experimental.preprocessing.Rescaling(1./255,input_shape=(img_height,img_width,3)),
            layers.Conv2D(16,(3,3),activation='relu',input_shape=(img_height,img_width,3)),
            layers.MaxPool2D((2,2)), #考虑首先关注这类病的特殊之处而不是背景信息
            layers.Conv2D(32,(3,3),activation='relu'),
            layers.AveragePooling2D((2,2)),
            layers.Conv2D(64,(3,3)),
            layers.Flatten(),
            layers.Dense(128,activation='relu'),
            layers.Dropout(0.3),
            layers.Dense(2,activation='sigmoid')  #二分类数据,因此激活函数采用sigmoid
])

model.summary()

四、编译

opt = tf.keras.optimizers.Adam(learning_rate=1e-4)

model.compile(optimizer=opt,
                  loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                  metrics=['accuracy'])

五、训练模型

tf.keras.callbacks.ModelCheckpoint(
    filepath, monitor='val_loss', verbose=0, save_best_only=False,
    save_weights_only=False, mode='auto', save_freq='epoch',
    options=None, **kwargs)

* monitor:要监视的值
* verbose:信息展示模式,01
* save_best_only :设置为True时,检测值有改进时才会保存当前模型
* mode:'auto','min','max'之一,在save_best_only=True时决定性能最佳模型的评判准则,如当检测值为val_acc时,模型应为max,val_loss对应min,在auto模式下,评价准则由被
        检测值的名字自动推断
* save_weights_only:若设置为True,则只保存模型权重,否则将保存整个模型
* period:CheckPoint之间间隔的epoch数

回调函数是一个函数的合集,会在训练的阶段中所使用。你可以使用回调函数来查看训练模型的内在状态和统计。你可以传递一个列表的回调函数(作为 callbacks 关键字参数)到 Sequential 或 Model 类型的 .fit() 方法。

  • modelcheckpoint在每次迭代之后保存模型
  • EarlyStopping :这个callback能监控设定的评价指标,在训练过程中,评价指标不再上升时,训练将会提前结束,防止模型过拟合,
  • LearningRateScheduler :模型训练过程中调整学习率,通常而言,随着训练次数的变多,适当地降低学习率有利于模型收敛在全局最优点,因此这个callback需要搭配一个学习率调度器使用,在每个epoch开始时,schedule函数会获取最新的学习率并用在当前的epoch中
  • ReduceLROnPlateau:不是按照预先设定好的调度调整学习率,它会在评价指标停止提升时降低学习率
  • TerminateOnNaN :在损失变为NaN时停止训练。
from tensorflow.keras.callbacks import ModelCheckpoint

epochs = 50

checkpointer = ModelCheckpoint(filepath = 'best_model.h5',
                              monitor='val_accuracy',
                              verbose=1,
                              save_best_only = True,
                              mode='max',
                              save_weights_only=True)
history = model.fit(
                    train_ds,
                    validation_data=val_ds,
                    epochs=epochs,
                    callbacks=[checkpointer])

最终结果val_accuracy did not improve from 0.89252
画出对应准确率与损失函数图像
在这里插入图片描述
可见第10轮后,模型测试集准确率不再有显著提升,但随着训练集损失函数不断减小并趋于稳定,测试集损失函数不断上升,可以看出存在明显过拟合现象,但最优模型的测试集准确率已达到89%

方案二

添加L2正则化,对第一个卷积层修改

            layers.Conv2D(16,(3,3),activation='relu',input_shape=(img_height,img_width,3),kernel_regularizer=keras.regularizers.l2(0.05)),

并将池化层全部更改为平均值池化,同时将Drop层参数增加至0.5
最终结果为val_accuracy did not improve from 0.89252
图像为在这里插入图片描述
过拟合情况仍十分明显

方案三

model3 = models.Sequential([
            layers.experimental.preprocessing.Rescaling(1./255,input_shape=(img_height,img_width,3)),
            layers.Conv2D(16,(3,3),activation='relu',input_shape=(img_height,img_width,3),kernel_regularizer=keras.regularizers.l2(0.1),padding='same'),
            layers.AveragePooling2D((2,2)),
            layers.Conv2D(32,(3,3),activation='relu'),
            layers.AveragePooling2D((2,2)),
            layers.Conv2D(64,(3,3),activation='relu'),
            layers.AveragePooling2D((2,2)),
            layers.Conv2D(128,(3,3),activation='relu'),#增加新卷积层
            layers.Dropout(0.5),#对卷积层与全连接层后均添加drop层
            layers.Flatten(),
            layers.Dense(64,activation='relu'), #将全连接层特征数缩减
            layers.Dropout(0.3),
            layers.Dense(2,activation='sigmoid')
])

在这里插入图片描述
该方案下,测试集损失函数趋于稳定,最高准确率达到了89.4%,但仍有过拟合风险。

2. 指定图片进行预测

#加载效果最好的模型权重
model4.load_weights('best_model4.h5')

import numpy as np
import tensorflow as tf
#img = Image.open("./第四周/pictures/Others/NM15_02_11.jpg")
img = PIL.Image.open(r'D:\AIoT学习\深度学习训练营\第四周\pictures\Others\NM15_02_11.jpg') 
image = np.array(img)  #需要先转为ndarray格式
image = tf.image.resize(image,size=(224,224))

img_array = tf.expand_dims(image,0)
predictions = model4.predict(img_array)
print("预测结果为:",class_names[np.argmax(predictions)])

预测结果为: Others

总结

当模型出现过拟合时,有时存在随着测试集损失函数随模拟轮次增加逐渐变大的现象,我们通过正则化,drop层,池化等方法有时可以时测试集损失函数趋于稳定的情况,但可能无法显著改善测试集准确率。
通过callsback模块我们可以更好的对模型进行检测,同时仅保留模型优化后的系数

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值