- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
我的环境:
- 语言环境:Python3.11.2
- 编译器:PyCharm Community Edition 2022.3
- 深度学习环境:TensorFlow2
一、代码实现
1.1 前期准备
导入本次学习需要使用的库
#用于获取文件,展示图片
import pathlib,PIL
#深度学习模块
import tensorflow as tf
#用于图片展示,模型评估
import matplotlib.pyplot as plt
#用于构建神经网络
from tensorflow.keras import layers,models
#防止过拟合的模块
from tensorflow.keras.callbacks import ModelCheckpoint,EarlyStopping
import numpy as np
依旧使用pathlib库获取数据集
#import pathlib
path = 'F:/46-data'
data = pathlib.Path(path)
查看导入的数据
#import PIL
img = len(list(data.glob('*/*/*.jpg')))
print(img)
'''578'''
r = list(data.glob('train/nick/*.jpg'))
PIL.Image.open(str(r[0])).show()
1.2 数据预处理
使用image_dataset_from_directory方法将数据加载至tf.data.Dataset中
注意导入文件的位置,代码中的是在脚本文件同一级的文件夹下的,而我的数据集存放在F盘中(批注为实际位置),若没有在脚本文件同一级中添加数据集则数据的位置应该使用文件所在位置的绝对路径。
#import tensorflow as tf
batch_size = 32
img_height = 224
img_width = 224
train_ds = tf.preprocessing.image_dataset_from_directory(
#数据
#F:/46-data/train/
'./46-data/train/',
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size
)
val_ds = tf.preprocessing.image_dataset_from_directory(
#F:/46-data/test/
'./46_data/test/',
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size
)
#设置标签
class_name = train_ds.class_names
print(class_names)
1.3 可视化数据
#import matplotlib.pyplot as plt
plt.figure(figsize(20,10))
for images,labels in train_da.take(1):
for i in range(20):
ax = plt.subplot(5,10,i+1)
plt.imshow(images[i].numpy().astype('uint8'))
plt.title(class_name[labels[i]])
plt.axis('off')
plt.show()
检查一下数据
for image,labels in train_ds:
print(image.shape)
print(labels.shape)
break
这里的图片、标签都是张量,查看图片的结果表示为一批图片的张数,图片的长、宽以及图片的通道数。
1.4 配置数据集
#import tensorflow as tf
AUTOTUNE = tf.data.AUTOTUNE
train_ds = train_da.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
1.5 构建CNN网络
#from tensorflow.keras import layers,models
model = models.Sequential([
layers.experimental.preprocessing.Rescaling(1./255,input_shape=(img_height,img_weigh,3)),
layers.Conv2D(64,(3,3),activation='relu',input_shape=(img_height,img_weigh,3)),
layers.AveragePooling2D(2*2),
layers.Conv2D(64,(3,3),activation='relu'),
layers.Dropout(0.5),
layers.AveragePooling2D(2*2),
layers.Conv2D(64,(3,3),activation='relu'),
layers.Dropout(0.5),
layers.Flatten(),
layers.Dense(128,activation='relu'),
layers.Dense(len(class_names)),
])
先对数据预处理,并在构建神经网络时加入Dropout防止过拟合。
1.6 训练模型
通过设置学习率调整优化器
#import tensorflow as tf
#from tensorflow import layers,models
#设置初始学习率
init_learn = 0.1
lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
#学习率
init_learn
#设置衰减步数
decay_steps=10,
#设置衰减参数
decay_rate=0.92,
staircase=True
)
optimizer = tf.keras.optimizers.Adam(learning_rate=lr_schedule)
model.compile(optimizer=optimizer,
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
这里设置了动态学习率:指数衰减型(ExponentialDecay),其中的参数为学习率,每轮epochs中每经过steps步后衰减一次,每次衰减的参数以及将学习率衰减看作阶梯状(取整)。每开始一轮epochs都会将学习率重置为初始值。
steps为训练过程中每一轮迭代中的步数,每个epochs包含多个steps,通过在训练模型中设置steps_pre_epochs设置steps,默认为数据集样本数/batch_size。
学习率的大小会对模型有影响,学习率大会使得模型学习速率更快,同时有助于模型跳出局部最优解,但是会导致模型不收敛,易使模型不精确;学习率小有助于模型收敛、细化,可以提高模型的精度,但是会使得模型难以跳出局部最优解,同时使模型收敛缓慢。
#from tensorflow.keras.callback import ModelCheckpoint,EarlyStopping
epochs=50
#保存最佳的模型参数
check = ModelCheckpoint('best_model.h5',
monitor='val_accuracy',
verbose=1,
save_best_only=True,
save_weight_only=True)
#早停法
early = EarlyStopping(monitor='val_accuracy',
min_delta=0.001,
patience=20,
verbose=1)
早停法参数设置为被检测数据、准确度最小提升率、检测到无提升后再进行的训练轮次以及详细信息模式。
训练模型
history = model.fit(train_ds,
validation_data=vali_ds,
epochs=epochs,
steps_per_epoch=32,
callbacks=[check,early])
1.7 模型评估
#import matplotlib.pyplot as plt
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(len(loss))
plt.figure(figsize=(12,4))
plt.subplot(1,2,1)
plt.plot(epochs_range,acc,label='Training Accuracy')
plt.plot(epochs_range,val_acc,label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1,2,2)
plt.plot(epochs_range,loss,label='Training Loss')
plt.plot(epochs_range,val_loss,label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
这里准确率异常,尝试将学习率调小
init_learn = 1e-4
在调小一点,调到1e-5
可以看到准确率又开始起伏。
将学习率固定
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-4)
固定学习率后的准确率要高一些,所以应多尝试几个值进行选择。
1.8 预测
model.load_weights('best_model.h5')
i = PIL.Image.open('F:/46-data/test/nike/1.jpg')
imge = tf.image.resize(i,[img_height,img_weigh])
img_array = tf.expand_dims(imge,0)
predictions = model.predict(img_array)
print(class_names[np.argmax(predictions)])
'''
nike
'''
二、学习总结
本次学习中依旧通过导入外部数据进行模型的训练,了解了steps和epochs的区别,steps是指每个epoch中的迭代次数,而epochs是指整个数据集被遍历的次数。设置了优化器,包括设置学习率、学习率变化步数、学习率变化参数,以此更好的编译模型。实际使用了earlystop方法训练模型,防止过拟合,使得模型更好的进行数据预测。