本文主要是介绍365天深度学习训练营-第T6周:好莱坞明星识别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
我的环境:
- 语言环境:Python3.10.7
- 编译器:VScode
- 深度学习环境:TensorFlow2
一、前期工作:
1、导入数据集
import os, PIL, pathlib
import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, models
import matplotlib.pyplot as pltdata_dir = "D:\T6star"
print(type(data_dir))
data_dir = pathlib.Path(data_dir)
print(type(data_dir))
data_dir = pathlib.Path(data_dir)这行代码的作用是将一个字符串路径转换为`pathlib`模块中的`Path`对象。`Path`对象提供了一组方法来操作文件路径,例如访问文件名、父目录、文件扩展名等。
通过将字符串路径转换为`Path`对象,可以更方便地进行路径操作,例如拼接路径、创建文件或目录、检查路径是否存在等。`Path`对象还提供了一些便捷的方法来处理文件和目录,例如复制文件、删除文件、遍历目录等。
将`data_dir`字符串转换为`Path`对象后,可以使用`Path`对象的方法来执行与路径相关的操作,例如:
- `data_dir.name`:获取路径中的文件名
- `data_dir.parent`:获取路径中的父目录
- `data_dir.exists()`:检查路径是否存在
- `data_dir.mkdir()`:创建目录
- `data_dir.is_file()`:检查路径是否为文件
- `data_dir.is_dir()`:检查路径是否为目录
通过使用`Path`对象可以更方便地处理文件路径,并执行各种文件和目录操作,而无需手动解析字符串路径。
运行结果:
2.查看图片数量
image_count = len(list(data_dir.glob("*/*.jpg")))
print("图片数目:", image_count)
运行结果:
3.查看测试图片
roses = list(data_dir.glob("Jennifer Lawrence/*.jpg"))
image_path = str(roses[0])# Open the image using PIL
image = PIL.Image.open(image_path)# Display the image using matplotlib
plt.imshow(image)
plt.axis("off")
plt.show()
运行结果:
二、数据预处理 :
1.格式设置、划分训练集及数据集、图片标签展示
#设施图片格式
batch_size = 32
img_height = 224
img_width = 224#划分训练集
#train_ds = tf.keras.preprocessing.image_dataset_from_directory(
# "D:\T6star",
# seed = 123,
# image_size = (img_height, img_width),
# batch_size = batch_size)train_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir,validation_split = 0.1,subset = "training",label_mode = "categorical",seed = 123,image_size = (img_height, img_width),batch_size = batch_size
)#划分验证集
#val_ds = tf.keras.preprocessing.image_dataset_from_directory(
# "D:\T6star",
# seed = 123,
# image_size = (img_height, img_width),
# batch_size = batch_size
#)val_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir,validation_split = 0.1,subset = "validation",label_mode = "categorical",seed = 123,image_size = (img_height, img_width),batch_size = batch_size
)#查看标签
class_names = train_ds.class_names
print(class_names)
运行结果:
2.数据可视化
#数据可视化
plt.figure(figsize = (20, 10))for images, labels in train_ds.take(1):for i in range(20):plt.subplot(5, 10, i + 1)plt.imshow(images[i].numpy().astype("uint8"))plt.title(class_names[labels[i]])plt.axis("off")
plt.show()
plt.figure(figsize = (20, 10)) 创建一个图形对象,并指定其大小为20x10英寸
for images, labels in train_ds.take(1): 遍历train_ds数据集中的第一个批次,每个批次包含一批图和对应的标签。这里使用take(1)函数从数据集中获取一个批次。
plt.subplot(5, 10, i +1) 在图形对象中创建一个子图,这里的子图是一个5x10的网格,并将当前子图设置为第i+1个位置。
plt.imshow(images[i].numpy().astype("uint8")) 使用Matplotlib的imshow函数显示当前图像。images[i]是当前图像的张量表示,使用.numpy()将其转换为NumPy数组,并使用.astype("uint8")将数据类型转换为uint8以便显示。
plt.title(class_names[labels[i]]) 为当前图像设置标题,标题内容是通过索引labels[i]从class_names列表中获取的类别名称。
plt.axis(“off”) 是 Matplotlib 库中的一个函数调用,它用于控制图像显示时的坐标轴是否可见。
具体来说,当参数为 “off” 时,图像的坐标轴会被关闭,不会显示在图像周围。这个函数通常在 plt.imshow() 函数之后调用,以便在显示图像时去掉多余的细节信息,仅仅显示图像本身。
运行结果:
3.检验数据、配置数据
#检验数据
for image_batch, labels_batch in train_ds:print(image_batch.shape)print(labels_batch.shape)break
运行结果:
#配置数据
AUTOTUNE = tf.data.AUTOTUNEtrain_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size = AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size = AUTOTUNE)
配置数据集的预处理和性能优化:
tf.data.AUTOTUNE
常量,它的作用是自动选择合适的数值作为性能优化参数,以充分利用可用的系统资源。
`train_ds`和`val_ds`是训练集和验证集的数据集对象,在上述段代码中,以下操作被应用于这两个数据集:
1. `.cache()`该方法将数据集缓存到内存中或本地磁盘上,以便在训练过程中快速重用数据。这可以提高训练效率,特别是当数据集无法一次性全部加载到内存时。
2. `.shuffle(1000)`该方法对数据集进行随机化操作,打乱样本的顺序。参数`1000`表示要使用的缓冲区大小,它定义了打乱操作所使用的元素数量。这有助于使训练更具随机性,提高模型的泛化能力。
3. `.prefetch(buffer_size=AUTOTUNE)`该方法用于数据集的预取操作。参数`buffer_size`指定了要预取的元素数量。`AUTOTUNE`常量的值由之前定义的`tf.data.AUTOTUNE`决定,它会自动根据可用的系统资源动态选择合适的缓冲区大小,以加速数据加载。这样,当模型在训练时,预取操作可以在后台异步加载数据,从而减少模型等待数据的时间。
通过这些数据集配置操作,可以在训练过程中加速数据加载和预处理,从而提高训练的效率,并确保数据集在训练过程中始终提供足够的数据供应给模型。
三、搭建CNN网络
#设置Sequential模型,创建神经网络
model = models.Sequential([layers.experimental.preprocessing.Rescaling(1./ 255, input_shape = (img_height, img_width, 3)),#定义了一个图像预处理层,即 Rescaling 层。该层会将图像的像素值缩放到 [0, 1] 之间,以便模型更好地学习图像特征。#其中,1. / 255 是缩放的因子,input_shape 则是可选参数,用于指定输入图像的大小。#由于神经网络算法通常对输入数据有一定的要求(如数据必须位于同一尺度或范围内),因此在训练神经网络之前,通常需要对输入数据进行预处理。#在这个例子中,将图像的像素值除以 255,可以将像素值缩放到 [0, 1] 范围内。这样做不仅可以提高模型训练的效果,还可以加速模型训练的收敛。layers.Conv2D(16, (3, 3), activation = "relu", input_shape = (img_height, img_width)),layers.AveragePooling2D((2, 2)),layers.Conv2D(32, (3, 3), activation = "relu"),layers.AveragePooling2D((2, 2)),layers.Dropout(0.5),layers.Conv2D(64, (3, 3), activation = "relu"),layers.AveragePooling2D((2, 2)),layers.Dropout(0.5),layers.Conv2D(128, (3, 3), activation = "relu"),#layers.AveragePooling2D((2, 2)),layers.Dropout(0.5),layers.Flatten(),layers.Dense(128, activation = "relu"),layers.Dense(len(class_names))
])model.summary()
运行结果:
四、编译
#设置动态学习率
initial_learning_rate = 1e-4
lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(initial_learning_rate,decay_steps = 30,decay_rate = 0.92,staircase = True
)#设置优化器
opt = keras.optimizers.Adam(learning_rate=lr_schedule)
model.compile(#设置优化器为Adam优化器optimizer = opt,#设置损失函数为交叉熵损失函数loss = keras.losses.SparseCategoricalCrossentropy(from_logits=True),#设置性能指标列表,将在模型训练时对列表中的指标进行监控metrics = ['accuracy']
)
from_logits
参数是用于控制模型的输出是否经过概率转换。
当 from_logits=True
时,表示模型的输出没有经过概率转换,即模型的输出是未经归一化的原始值。这通常适用于模型的最后一层没有经过 softmax 函数的情况。在这种情况下,训练过程中会应用 softmax 函数来将输出转换为概率分布,并计算交叉熵损失。
当 from_logits=False
时,表示模型的输出已经经过了概率转换,即模型的输出已经是一个概率分布。这通常适用于模型的最后一层已经经过 softmax 函数的情况。在这种情况下,训练过程中不会再应用 softmax 函数,而是直接使用模型输出的概率分布与标签计算交叉熵损失。
损失函数Loss详解:
1. binary_ crossentropy (对数损失函数)
与sigmoid相对应的损失函数,针对于二分类问题。
2. categorical crossentropy (多分类的对数损失函数)
与softmax相对应的损失函数,如果是one -hot编码,则使用
categorical_ crossentropy
3. sparse_ categorical crossentropy (稀疏性多分类的对数损失函数)
与 softmax相对应的损失函数,如果是整数编码,则使用sparse_ categorical_ crossentropy
函数原型
1 tf .keras .losses .SparseCategoricalCrossentropy(
from_logits=False,
reduction=losses_utils. ReductionV2. AUTO,
name=' sparse_categorical_ crossentropy'
)
参数说明: .
from_logits :为True时,会将y_pred转化为概率 (用softmax) ,否则不进行转换,通常情况下用True结果更稳定;
reduction :类型为tf.keras.losses. Reduction,对loss进行处理,默认是AUTO;
name : name
通过指数衰减学习率,初始学习率为 `0.0001`,每经过 `30` 步衰减一次,衰减率为 `0.92`,并且采用阶梯函数进行衰减。调度器对象 `lr_schedule` 可以在训练过程中根据指定的规则自动调整学习率。
学习率大与学习率小的优缺点分析:
学习率大
优点:
。1、加快学习速率。
。2、有助于跳出局部最优值。
●缺点:
。1、 导致模型训练不收敛。
0 2、单单使用大学习率容易导致模型不精确。
学习率小.
优点:
。1、有助于模型收敛、模型细化。
0 2、提高模型精度。
● 缺点:
。1、很难跳出局部最优值。
。2、收敛缓慢。
这里设置的动态学习率为:指数衰减型(ExponentialDecay) 。在每一-个epoch开始前, 学习率
(learning_ rate) 都将会重置为初始学习率(initial. _learning. rate),然后再重新开始衰减。计算公式如下:
learning_ rate = initial. learning. _rate * decay_ rate ^ (step / decay_ steps)
五、训练模型
#模型训练 早停与保存最佳模型参数
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStoppingepochs = 100checkpoint = ModelCheckpoint("best_model.h5",monitor = 'val_accuracy',verbose = 1,save_best_only = True,save_weights_only = True)earlystopper = EarlyStopping(monitor = 'val_accuracy',min_delta = 0.001,patience = 20,verbose = 1)history = model.fit(train_ds,validation_data = val_ds,epochs = epochs,callbacks = [checkpoint, earlystopper]
)
代码添加了一个新的回调函数 `EarlyStopping`,用于在训练过程中实现早停(early stopping)机制。
`EarlyStopping` 是 Keras 中的一个回调函数,它监视指定的指标(在这个例子中是验证准确率 `'val_accuracy'`),并根据预先设置的条件来判断是否停止训练。
参数解释如下:
monitor:要监视的指标,这里是验证准确率。
min_delta:用于定义要监视指标的最小变化量,当指标的变化小于该值时,将被视为没有进一步改进。
patience:允许没有进一步改进的训练轮数的数量。如果在连续的 `patience` 轮中没有进一步改进,则训练将提前停止。
verbose:控制是否显示早停信息的详细程度,设为 `1` 表示显示信息。
在训练过程中,当验证准确率不再改进或改进量非常小(小于 `min_delta`)时,`EarlyStopping` 回调函数会触发停止训练的操作,从而防止模型过拟合或在不再有进一步改进时继续训练。
将 EarlyStopping 回调函数添加到 callbacks 列表中,如下所示:
callbacks = [checkpointer, earlystopper]
callbacks 列表是在模型训练过程中使用的回调函数的集合。
在机器学习中,回调函数是一种机制,可以在训练过程中的不同阶段执行特定的操作。这些操作可以包括保存模型、记录指标、调整学习率、可视化训练进度等。
在 Keras 中,可以通过创建回调函数对象并将其添加到 `callbacks` 列表中来定义和配置这些操作。在模型的训练过程中,Keras 将自动调用这些回调函数,并在合适的时间点执行相应的操作。
常见的回调函数包括:
- `ModelCheckpoint`:用于保存模型的权重或整个模型的回调函数。
- `EarlyStopping`:在验证指标不再改进时提前停止训练的回调函数。
- `TensorBoard`:用于将训练指标和可视化图表保存为 TensorBoard 日志的回调函数。
- `ReduceLROnPlateau`:在验证指标不再改进时降低学习率的回调函数。
通过使用回调函数,可以在模型训练过程中实现更复杂的功能和控制,以提高模型的性能和训练效果。将这些回调函数添加到 `callbacks` 列表中,传递给 `model.fit()` 方法,就可以在训练过程中执行相应的操作。
在例程中callbacks = [checkpointer, earlystopper]除了保存模型权重外,还会检查验证准确率是否满足早停的条件,以便在适当的时候停止训练。
六、模型评估
1.Loss和Acc图
#模型评估
loss = history.history['loss']
val_loss = history.history['val_loss']acc = history.history['accuracy']
val_acc = history.history['val_accuracy']epochs_range = range(len(loss))plt.figure(figsize = (12, 4))plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label = "Training Acc")
plt.plot(epochs_range, val_acc, label = "Validation Acc")
plt.legend(loc = 'lower right')
plt.title("Training And Validation Acc")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()
运行结果:
2.指定结果进行预测
model.load_weights('best_model.h5')
from PIL import Image
import numpy as np
img = Image.open("D:/T6star/Hugh Jackman/001_9adc92c2.jpg")
image = tf.image.resize(img, [img_height, img_width])
img_array = tf.expand_dims(image, 0)
predictions = model.predict(img_array)
#这个函数用于对输入图像进行分类预测。它使用已经训练好的模型来对输入数据进行推断,并输出每个类别的概率分布。
print("预测结果为:", class_names[np.argmax(predictions)])
运行结果:
这篇关于365天深度学习训练营-第T6周:好莱坞明星识别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!