当前位置: 首页 > news >正文

T6:好莱坞明星识别

文章目录

  • **T6周:好莱坞明星识别**
      • **一、前期工作**
        • 1.设置GPU(用CPU可忽略该步骤)
        • 2.导入数据
        • 3.查看数据
      • **二、数据预处理**
        • 1.加载数据
        • 2.可视化数据
        • 3.配置数据集
      • **三、构建CNN网络模型**
      • **四、编译模型**
      • **五、训练模型**
      • **六、模型评估**
      • **七、预测**
      • 八、总结(临时)

T6周:好莱坞明星识别

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊

🍺 要求:

  1. 使用categorical_crossentropy(多分类的对数损失函数)完成本次选题
  2. 探究不同损失函数的使用场景与代码实现

🍻 拔高(可选):

  1. 自己搭建VGG-16网络框架
  2. 调用官方的VGG-16网络框架
  3. 使用VGG-16算法训练该模型

🔎 探索(难度有点大)

  1. 准确率达到60%

⛽ 我的环境

  • 语言环境:Python3.10.12
  • 编译器:Google Colab
  • 深度学习环境:
    • TensorFlow2.17.0

⛽ 参考博客:

  • 深度学习 Day6——T6好莱坞明星识别

一、前期工作

1.设置GPU(用CPU可忽略该步骤)
#os提供了一些与操作系统交互的功能,比如文件和目录操作
import os
#提供图像处理的功能,包括打开和显示、保存、裁剪等
import PIL
#pathlib提供了一个面向对象的接口来处理文件系统路径。路径被表示为Path对象,可以调用方法来进行各种文件和目录操作。
import pathlib#用于绘制图形和可视化数据
import tensorflow as tf
import matplotlib.pyplot as plt
#用于数值计算的库,提供支持多维数组和矩阵运算
import numpy as np
#keras作为高层神经网络API,已被集成进tensorflow,使得训练更方便简单
from tensorflow import keras
#layers提供了神经网络的基本构建块,比如全连接层、卷积层、池化层等
#提供了构建和训练神经网络模型的功能,包括顺序模型(Sequential)和函数式模型(Functional API)
from tensorflow.keras import layers, models
#导入两个重要的回调函数:前者用于训练期间保存模型最佳版本;后者监测到模型性能不再提升时提前停止训练,避免过拟合
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping
# 获取所有可用的GPU设备列表,储存在变量gpus中
gpus = tf.config.list_physical_devices("GPU")# 如果有GPU,即列表不为空
if gpus:# 获取第一个 GPU 设备gpu0 = gpus[0]# 设置 GPU 内存增长策略。开启这个选项可以让tf按需分配gpu内存,而不是一次性分配所有可用内存。tf.config.experimental.set_memory_growth(gpu0, True)#设置tf只使用指定的gpu(gpu[0])tf.config.set_visible_devices([gpu0],"GPU")gpus
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
2.导入数据
data_dir = "/content/drive/Othercomputers/My laptop/jupyter notebook/data/T6"
data_dir = pathlib.Path(data_dir)
3.查看数据
# 使用glob方法获取当前目录的子目录里所有以'.jpg'为结尾的文件
# '*/*.jpg' 是一個通配符模式
# 第一个星号表示当前目录
# 第二个星号表示子目录
image_count = len (list(data_dir.glob("*/*.jpg")))print("图片总数:", image_count)
图片总数: 1800
ex = list(data_dir.glob("Jennifer Lawrence/*.jpg"))
image=PIL.Image.open(str(ex[5]))
#查看图像属性
print(image.format, image.size,image.mode)
plt.axis("off")
plt.imshow(image)
plt.show()
JPEG (474, 577) RGB

在这里插入图片描述

二、数据预处理

1.加载数据
#设置批量大小,即每次训练模型时输入图像数量
#每次训练迭代时,模型需处理32张图像
batch_size = 32
#图像的高度,加载图像数据时,将所有的图像调整为相同的高度
img_height = 224
#图像的宽度,加载图像数据时,将所有的图像调整为相同的宽度
img_width = 224
"""
关于image_dataset_from_directory()的详细介绍可以参考文章:https://mtyjkh.blog.csdn.net/article/details/117018789
"""
tr_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir,validation_split=0.1,#指定数据集中分割出多少比例数据当作验证集,0.1表示10%数据会被用来当验证集subset="training",#指定是用于训练还是验证的数据子集,这里设定为traininglabel_mode = "categorical",#标签编码为分类向量,独热编码数组--使用损失函数应为--categorical_crossentropy lossseed=123,#用于设置随机数种子,以确保数据集划分的可重复性和一致性image_size=(img_height, img_width),batch_size=batch_size)
Found 1800 files belonging to 17 classes.
Using 1620 files for training.
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
)
Found 1800 files belonging to 17 classes.
Using 180 files for validation.
class_names = tr_ds.class_names
# 可以通过class_names输出数据集的标签。标签将按字母顺序对应于目录名称
class_names
['Angelina Jolie','Brad Pitt','Denzel Washington','Hugh Jackman','Jennifer Lawrence','Johnny Depp','Kate Winslet','Leonardo DiCaprio','Megan Fox','Natalie Portman','Nicole Kidman','Robert Downey Jr','Sandra Bullock','Scarlett Johansson','Tom Cruise','Tom Hanks','Will Smith']

随机数种子相关可参考:https://blog.csdn.net/weixin_51390582/article/details/124246873

2.可视化数据
plt.figure(figsize=(20,10))
for images, labels in tr_ds.take(1):for i in range(20):ax = plt.subplot(5, 10, i + 1)plt.imshow(images[i].numpy().astype("uint8"))plt.title(class_names[np.argmax(labels[i])], fontsize=10)plt.axis("off")# 显示图片
plt.show()

请添加图片描述

for image_batch, labels_batch in tr_ds:print(image_batch.shape)print(labels_batch.shape)break#`(32, 224, 224, 3)`--最后一维指的是彩色通道RGB
#`label_batch`是形状(32,17)的张量,这些标签对应32张图片,分为17类
(32, 224, 224, 3)
(32, 17)
3.配置数据集
#自动调整数据管道性能
AUTOTUNE = tf.data.AUTOTUNE
# 使用 tf.data.AUTOTUNE 具体的好处包括:
#自动调整并行度:自动决定并行处理数据的最佳线程数,以最大化数据吞吐量。
#减少等待时间:通过优化数据加载和预处理,减少模型训练时等待数据的时间。
#提升性能:自动优化数据管道的各个环节,使整个训练过程更高效。
#简化代码:不需要手动调整参数,代码更简洁且易于维护。#使用cache()方法将训练集缓存到内存中,这样加快数据加载速度
#当多次迭代训练数据时,可以重复使用已经加载到内存的数据而不必重新从磁盘加载
#使用shuffle()对训练数据集进行洗牌操作,打乱数据集中的样本顺序
#参数1000指缓冲区大小,即每次从数据集中随机选择的样本数量
#prefetch()预取数据,节约在训练过程中数据加载时间
tr_ds = tr_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)

三、构建CNN网络模型

卷积神经网络(CNN)的输入是张量 (Tensor) 形式的 (image_height, image_width, color_channels),包含了图像高度、宽度及颜色信息。不需要输入batch size。color_channels 为 (R,G,B) 分别对应 RGB 的三个颜色通道(color channel)。在此示例中,我们的 CNN 输入形状是 (224, 224, 3)。我们需要在声明第一层时将形状赋值给参数input_shape。

CNN的输入张量表示图像的结构和颜色信息。每个像素点都被表示为具有color_channels个数值的向量,在训练时,通过一系列卷积层、池化层和全连接层等操作提取和处理图像特征。

num_classes = 17#创建序列模型,一种线性堆叠模型,各层按照他们被添加到模型中的顺序来堆叠
model = models.Sequential([#输入层layers.Input(shape=(img_height,img_width,3)),# 数据预处理层:将像素值从 [0, 255] 缩放到 [0, 1]即归一化,输入(224, 224 ,3),layers.Rescaling(scale=1./255),#2.17.0的tensorflow貌似已经移除了experimental.preprocessing,而直接放在layers库中(*最好用Input作为单独输入层)#layers.experimental.preprocessing.Rescaling(1./255, input_shape=(img_height,img_width,3)),# 卷积层1:16 个 3x3 的卷积核,使用 ReLU 激活函数,输出 (222, 222, 16),layers.Conv2D(16, (3, 3), activation='relu', input_shape=(img_height, img_width, 3)),# 池化层1:2x2 的平均池化,输出(111,111,16)layers.AveragePooling2D((2, 2)),  #池化层1,2*2采样# 卷积层2:32 个 3x3 的卷积核,使用 ReLU 激活函数,(109,109,32)layers.Conv2D(32, (3, 3), activation='relu'), #卷积层2,卷积核3*3# 池化层2:2x2 的平均池化,(54,54,32)layers.AveragePooling2D((2, 2)),  #池化层2,2*2采样# Dropout层:随机停止50%的神经元工作,防止过拟合layers.Dropout(0.5),# 卷积层3:64 个 3x3 的卷积核,使用 ReLU 激活函数 (52,52,64)layers.Conv2D(64, (3, 3), activation='relu'),# 池化层3:2x2 的平均池化,(26,26,64)layers.AveragePooling2D((2, 2)),# Dropout层:随机停止30%的神经元工作,防止过拟合layers.Dropout(0.5),# 卷积层4:128个 3x3的卷积核,使用ReLU 激活函数 (24,24,128)layers.Conv2D(128, (3,3), activation ="relu"),# Dropout层:随机停止30%的神经元工作,防止过拟合layers.Dropout(0.5),#flatten层layers.Flatten(),layers.Dense(128, activation="relu"), #全连接层,特征进一步提取layers.Dense(num_classes)])
model.summary()  # 打印网络结构
/usr/local/lib/python3.10/dist-packages/keras/src/layers/convolutional/base_conv.py:107: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.super().__init__(activity_regularizer=activity_regularizer, **kwargs)
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓
┃ Layer (type)                         ┃ Output Shape                ┃         Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩
│ rescaling (Rescaling)                │ (None, 224, 224, 3)         │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ conv2d (Conv2D)                      │ (None, 222, 222, 16)        │             448 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ average_pooling2d (AveragePooling2D) │ (None, 111, 111, 16)        │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ conv2d_1 (Conv2D)                    │ (None, 109, 109, 32)        │           4,640 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ average_pooling2d_1                  │ (None, 54, 54, 32)          │               0 │
│ (AveragePooling2D)                   │                             │                 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dropout (Dropout)                    │ (None, 54, 54, 32)          │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ conv2d_2 (Conv2D)                    │ (None, 52, 52, 64)          │          18,496 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ average_pooling2d_2                  │ (None, 26, 26, 64)          │               0 │
│ (AveragePooling2D)                   │                             │                 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dropout_1 (Dropout)                  │ (None, 26, 26, 64)          │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ conv2d_3 (Conv2D)                    │ (None, 24, 24, 128)         │          73,856 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dropout_2 (Dropout)                  │ (None, 24, 24, 128)         │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ flatten (Flatten)                    │ (None, 73728)               │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense (Dense)                        │ (None, 128)                 │       9,437,312 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_1 (Dense)                      │ (None, 17)                  │           2,193 │
└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
 Total params: 9,536,945 (36.38 MB)
 Trainable params: 9,536,945 (36.38 MB)
 Non-trainable params: 0 (0.00 B)

四、编译模型

在准备对模型进行训练之前,还需要再对其进行一些设置。以下内容是在模型的编译步骤中添加的:

  • 损失函数(loss):用于衡量模型在训练期间的准确率。
  • 优化器(optimizer):决定模型如何根据其看到的数据和自身的损失函数进行更新。
  • 指标(metrics):用于监控训练和测试步骤。以下示例使用了准确率,即被正确分类的图像的比率。
#本次使用代码
# 设置初始学习率
initial_learning_rate = 1e-4lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(initial_learning_rate,decay_steps=60, # 敲黑板!!!这里是指 steps,不是指epochsdecay_rate=0.94, # lr经过一次衰减就会变成 decay_rate*lrstaircase=True)# 将指数衰减学习率送入优化器
optimizer = tf.keras.optimizers.Adam(learning_rate=lr_schedule)model.compile(optimizer=optimizer,loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),metrics=['accuracy'])#Adam优化器是一种常用的梯度下降优化算法,用于更新模型的权重以最小化训练过程中的损失函数
#由于是多分类问题这里使用categorical crossentropy损失函数

五、训练模型

epochs = 100# 保存最佳模型参数
checkpointer = ModelCheckpoint("/content/drive/Othercomputers/My laptop/jupyter notebook/xunlianying/6best.weights.h5",monitor='val_accuracy',verbose=1,mode = "max",save_best_only=True,save_weights_only=True)# 设置早停
earlystopper = EarlyStopping(monitor='val_accuracy',min_delta=0.001,patience=20,mode = "max",verbose=1)
history = model.fit(tr_ds,validation_data=val_ds,epochs=epochs,callbacks=[checkpointer, earlystopper])
Epoch 1/100

六、模型评估

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()

请添加图片描述

七、预测

注释参考:https://blog.csdn.net/qq_45735298/article/details/130056861?spm=1001.2014.3001.5502

model.load_weights('../xunlianying/6best.weights.h5')
#这段代码用于加载之前训练中保存的最佳模型权重。使用之前保存的模型权重文件路径和名称。
#这样可以避免从头开始训练模型,直接使用已经训练好的最佳模型进行预测的工作。from PIL import Image
import numpy as npimg = Image.open("./5/test/nike/4.jpg") #使用 PIL 库中的 Image.open() 方法打开一张待预测的图片。
image = tf.image.resize(img, [img_height, img_width])
#这个函数调整输入图像的大小以符合模型的要求。
#在这个例子中,使用 TensorFlow 的 tf.image.resize() 函数将图像缩放为指定大小,其中 img_height 和 img_width 是指定的图像高度和宽度。img_array = tf.expand_dims(image, 0)
'''
这个函数将输入图像转换为形状为 (1, height, width, channels) 的四维数组,
其中 height 和 width 是图像的高度和宽度,channels 是图像的通道数(例如 RGB 图像有 3 个通道)。
这里使用 TensorFlow 的 tf.expand_dims() 函数来扩展图像数组的维度,以匹配模型的输入格式。具体来说:
image 是一个二维图片张量,它的形状是 (height, width, channels)。其中 height 和 width 分别为图片的高度和宽度,channels 为图片的颜色通道数。0 是一个整数值,它指定在哪个维度上扩展此张量,这里表示在最前面(第一个)的维度上扩展。
因此,函数的作用是将输入张量 image 在最前面添加一个额外的维度(batch_size),生成一个四维张量。tf.expand_dims(input, axis)
其中 input 表示要扩展的输入张量,axis 表示要在哪个维度上进行扩展。在这个例子中,input 是变量 image,axis 是 0。
'''pre = model.predict(img_array)
#这个函数用于对输入图像进行分类预测。它使用已经训练好的模型来对输入数据进行推断,并输出每个类别的概率分布。
print("预测结果为:", class_names[np.argmax(pre)])#将模型输出的概率分布转换为最终预测结果。
#具体来说,使用 np.argmax() 函数找到概率最大的类别索引,然后使用该索引在 class_names 列表中查找相应的类别名称,并输出预测结果。

八、总结(临时)

  • 训练第一次结果val acc最高0.377,修改了一下decay_rate待再次训练
  • 学习了不同损失函数的特点和适用的场景条件
  • VGG16模型待搭建

http://www.mrgr.cn/news/6103.html

相关文章:

  • 韩国云主机玩游戏性能怎么样
  • 基于大语言模型的物联网(artificial intelligence of thing)
  • 网络通信tcp
  • 【HTML】模拟插头连接断开动画
  • 线段树的原理
  • Swagger
  • VUE3的computed()使用场景
  • [数据集][目标检测]手钳检测数据集VOC+YOLO格式141张1类别
  • 初始redis:List
  • SpringCache操作Redis
  • 每天一个数据分析题(四百九十七)- 序列模式挖掘
  • ChatGLM-4-9b-chat本地化|天翼云GPU上vLLM本地部署开源模型完整攻略
  • 第1节 安装Flask
  • NNG简介和使用总结
  • 使用 Apache POI 的 DataFormatter 处理 Excel 数据
  • iPhone抹掉数据后能恢复吗?详解数据恢复的可能性与方法
  • Python接口自动化之unittest单元测试
  • 打造编程学习的“知识宝库”:高效笔记记录与整理的艺术
  • 【随笔】编程学习笔记
  • Ubuntu 20.04 上安装 gcc/g++7.5 多版本gcc切换