专业网站建,北京专业做网站的公司,丝绸之路网站建设报告,买好域名和云主机后怎么做网站#x1f368; 本文为#x1f517;365天深度学习训练营 中的学习记录博客#x1f356; 原作者#xff1a;K同学啊 目标
具体实现
#xff08;一#xff09;环境
语言环境#xff1a;Python 3.10 编 译 器: PyCharm 框 架: TensorFlow
#xff08;二#xff09;具体… 本文为365天深度学习训练营 中的学习记录博客 原作者K同学啊 目标
具体实现
一环境
语言环境Python 3.10 编 译 器: PyCharm 框 架: TensorFlow
二具体步骤
import numpy as np
import tensorflow as tf
from tensorflow.python.data import AUTOTUNE # 设置GPU
# 获取当前系统中所有可用的物理GPU设备
gpus tf.config.list_physical_devices(GPU) # 如果系统中存在GPU设备
if gpus: # 设置第一个GPU设备的内存增长模式为动态增长以避免一次性占用所有显存 tf.config.experimental.set_memory_growth(gpus[0], True) # 设置当前可见的GPU设备为第一个GPU确保程序仅使用该GPU进行计算 tf.config.set_visible_devices([gpus[0]], GPU) # 导入数据
import matplotlib.pyplot as plt
import os, PIL, pathlib
from tensorflow import keras
from tensorflow.keras import layers, models # 设置matplotlib的字体为SimHei以支持中文显示
plt.rcParams[font.sans-serif] [SimHei]
# 设置matplotlib的负号显示为正常符号避免显示为方块
plt.rcParams[axes.unicode_minus] False # 定义数据目录路径
data_dir ./data/bird_photos
# 将路径转换为pathlib.Path对象方便后续操作
data_dir pathlib.Path(data_dir) # 使用glob方法获取所有子目录下的jpg文件并计算其数量
image_count len(list(data_dir.glob(*/*.jpg)))
# 打印图片数量
print(图片数量,image_count) # 数据预处理
# 定义批量大小和图像尺寸
batch_size 8
img_height 224
img_width 224 # 使用 tf.keras.preprocessing.image_dataset_from_directory 从指定目录加载训练数据集
# 参数说明:
# - data_dir: 包含图像数据的目录路径
# - validation_split: 用于验证集的数据比例此处为20%
# - subset: 指定加载的数据子集此处为训练集
# - seed: 随机种子确保数据分割的可重复性
# - image_size: 图像将被调整到的尺寸此处为224x224
# - batch_size: 每个批次的图像数量此处为8
train_ds tf.keras.preprocessing.image_dataset_from_directory( data_dir, validation_split0.2, subsettraining, seed123, image_size(img_height, img_width), batch_sizebatch_size) # 使用 tf.keras.preprocessing.image_dataset_from_directory 从指定目录加载验证数据集
# 参数说明与训练集相同但 subset 参数指定为验证集
val_ds tf.keras.preprocessing.image_dataset_from_directory( data_dir, validation_split0.2, subsetvalidation, seed123, image_size(img_height, img_width), batch_sizebatch_size) # 从训练数据集中获取类别名称
class_names train_ds.class_names # 打印类别名称
print(类别:, class_names) # 可视化数据
# 可视化训练数据集中的部分图像及其对应的标签
# 该代码块创建一个大小为10x5的图形窗口并在窗口中展示训练数据集中的前8张图像及其标签。 plt.figure(figsize(10, 5)) # 创建一个大小为10x5的图形窗口
plt.suptitle(训练数据集可视化) # 设置图形的标题为训练数据集可视化 # 从训练数据集中取出一批数据images和labels并展示其中的前8张图像
for images, labels in train_ds.take(1): for i in range(8): ax plt.subplot(2, 4, i1) # 在2行4列的网格中创建第i1个子图 plt.imshow(images[i].numpy().astype(uint8)) # 显示第i张图像并将其转换为uint8类型 plt.title(class_names[labels[i]]) # 设置子图的标题为对应的类别名称 plt.axis(off) # 关闭子图的坐标轴显示 # 检查数据 遍历训练数据集中的批次并打印图像批次和标签批次的形状。 该代码片段从训练数据集 train_ds 中获取一个批次的数据并打印该批次中图像和标签的形状。
train_ds 是一个可迭代对象通常包含图像和标签的批次数据。 代码执行流程
1. 从 train_ds 中获取一个批次的图像和标签。
2. 打印图像批次的形状。
3. 打印标签批次的形状。
4. 使用 break 语句提前退出循环仅处理第一个批次。 for image_batch, labels_batch in train_ds: # 打印图像批次的形状通常为 (batch_size, height, width, channels) print(image_batch.shape) # 打印标签批次的形状通常为 (batch_size,) print(labels_batch.shape) # 仅处理第一个批次后退出循环 break # 配置数据集
# 设置自动调优参数用于优化数据加载和预处理性能
AUTOTUNE tf.data.AUTOTUNE # 对训练数据集进行优化处理
# 1. cache(): 将数据集缓存到内存或磁盘避免在每个epoch重复加载数据提高训练效率。
# 2. shuffle(1000): 对数据集进行随机打乱缓冲区大小为1000确保训练数据的随机性。
# 3. prefetch(buffer_sizeAUTOTUNE): 使用自动调优的缓冲区大小预取数据以重叠数据加载和模型训练提高整体性能。
train_ds train_ds.cache().shuffle(1000).prefetch(buffer_sizeAUTOTUNE) # 对验证数据集进行优化处理
# 1. cache(): 将数据集缓存到内存或磁盘避免在每个epoch重复加载数据提高验证效率。
# 2. prefetch(buffer_sizeAUTOTUNE): 使用自动调优的缓冲区大小预取数据以重叠数据加载和模型验证提高整体性能。
val_ds val_ds.cache().prefetch(buffer_sizeAUTOTUNE) # 构建ResNet50网络
from keras import layers
from keras.layers import Input, Activation, BatchNormalization, Flatten
from keras.layers import Dense, Conv2D,MaxPooling2D,ZeroPadding2D,AveragePooling2D
from keras.models import Model def identity_block(input_tensor, kernel_size, filters, stage, block): 实现ResNet中的恒等块Identity Block。 参数: - input_tensor: 输入张量形状为 (batch_size, height, width, channels)。 - kernel_size: 卷积核的大小通常为 (3, 3)。 - filters: 三个整数的列表表示三个卷积层的滤波器数量。 - stage: 当前块的阶段标识用于命名。 - block: 当前块的标识用于命名。 返回: - 输出张量形状与输入张量相同。 filters1, filters2, filters3 filters name_base str(stage) block _identify_block_ # 第一个卷积层1x1卷积用于降维 x Conv2D(filters1, (1,1), name name_base conv1)(input_tensor) x BatchNormalization(name name_base bn1)(x) x Activation(relu, name name_base relu1)(x) # 第二个卷积层使用指定的kernel_size进行卷积 x Conv2D(filters2, kernel_size, padding same, name name_base conv2)(x) x BatchNormalization(name name_base bn2)(x) x Activation(relu, name name_base relu2)(x) # 第三个卷积层1x1卷积用于升维 x Conv2D(filters3, (1,1), name name_base conv3)(x) x BatchNormalization(name name_base bn3)(x) # 将输入张量与卷积结果相加实现残差连接 x layers.add([x, input_tensor], name name_base add) x Activation(relu, name name_base relu4)(x) return x def conv_block(input_tensor, kernel_size, filters, stage, block, strides(2,2)): 实现ResNet中的卷积块Convolutional Block。 参数: - input_tensor: 输入张量形状为 (batch_size, height, width, channels)。 - kernel_size: 卷积核的大小通常为 (3, 3)。 - filters: 三个整数的列表表示三个卷积层的滤波器数量。 - stage: 当前块的阶段标识用于命名。 - block: 当前块的标识用于命名。 - strides: 卷积步幅默认为 (2, 2)。 返回: - 输出张量形状与输入张量相同。 filters1, filters2, filters3 filters res_name_base str(stage) block _conv_block_res_ name_base str(stage) block _conv_block_ # 第一个卷积层1x1卷积用于降维 x Conv2D(filters1, (1,1), strides strides, name name_base conv1)(input_tensor) x BatchNormalization(name name_base bn1)(x) x Activation(relu, name name_base relu1)(x) # 第二个卷积层使用指定的kernel_size进行卷积 x Conv2D(filters2, kernel_size, padding same, name name_base conv2)(x) x BatchNormalization(name name_base bn2)(x) x Activation(relu, name name_base relu2)(x) # 第三个卷积层1x1卷积用于升维 x Conv2D(filters3, (1,1), name name_base conv3)(x) x BatchNormalization(name name_base bn3)(x) # 对输入张量进行1x1卷积以匹配输出张量的维度 shortcut Conv2D(filters3, (1,1), strides strides, name res_name_base conv1)(input_tensor) shortcut BatchNormalization(name res_name_base bn1)(shortcut) # 将卷积结果与输入张量相加实现残差连接 x layers.add([x, shortcut], name res_name_base add) x Activation(relu, name res_name_base relu4)(x) return x def ResNet50(input_shape[224, 224, 3], classes1000): 构建ResNet50模型。 参数: - input_shape: 输入图像的形状默认为 [224, 224, 3]。 - classes: 分类任务的类别数默认为 1000。 返回: - 构建好的ResNet50模型。 img_input Input(shapeinput_shape) x ZeroPadding2D((3,3))(img_input) # 初始卷积层 x Conv2D(64, (7,7), strides (2,2), name conv1)(x) x BatchNormalization(name bn_conv1)(x) x Activation(relu)(x) x MaxPooling2D((3,3), strides (2,2))(x) # 第一阶段包含一个卷积块和两个恒等块 x conv_block(x, 3, [64,64,256], stage2, blocka, strides(1,1)) x identity_block(x, 3, [64,64,256], stage2, blockb) x identity_block(x, 3, [64,64,256], stage2, blockc) # 第二阶段包含一个卷积块和三个恒等块 x conv_block(x, 3, [128,128,512], stage3, blocka) x identity_block(x, 3, [128,128,512], stage3, blockb) x identity_block(x, 3, [128,128,512], stage3, blockc) x identity_block(x, 3, [128,128,512], stage3, blockd) # 第三阶段包含一个卷积块和五个恒等块 x conv_block(x, 3, [256,256,1024], stage4, blocka) x identity_block(x, 3, [256,256,1024], stage4, blockb) x identity_block(x, 3, [256,256,1024], stage4, blockc) x identity_block(x, 3, [256,256,1024], stage4, blockd) x identity_block(x, 3, [256,256,1024], stage4, blocke) x identity_block(x, 3, [256,256,1024], stage4, blockf) # 第四阶段包含一个卷积块和两个恒等块 x conv_block(x, 3, [512,512,2048], stage5, blocka) x identity_block(x, 3, [512,512,2048], stage5, blockb) x identity_block(x, 3, [512,512,2048], stage5, blockc) # 全局平均池化层和全连接层 x AveragePooling2D((7,7), name avg_pool)(x) x Flatten()(x) x Dense(classes, activationsoftmax, namefc1000)(x) model Model(img_input, x, nameresnet50) # 加载预训练权重 model.load_weights(./models/resnet50_weights_tf_dim_ordering_tf_kernels.h5) return model # 初始化一个ResNet50模型实例
# 参数说明:
# - input_shape: 输入图像的形状格式为[height, width, channels]此处为[224, 224, 3]表示224x224像素的RGB图像
# - classes: 分类任务的类别数量此处为class_names列表的长度表示模型将输出对应类别的概率
model ResNet50() # 打印模型的摘要信息包括每一层的名称、输出形状和参数数量
model.summary() model.compile( # 使用Adam优化器学习率初始值为0.001 optimizertf.keras.optimizers.Adam(learning_rate0.001), # 设置损失函数为交叉熵损失函数 losstf.keras.losses.SparseCategoricalCrossentropy(from_logitsTrue), # 设置性能指标列表将在模型训练时监控列表中的指标 metrics[accuracy]
) # 训练模型并记录训练过程中的历史数据
#
# 参数:
# train_ds: 训练数据集通常是一个tf.data.Dataset对象包含训练数据。
# validation_data: 验证数据集通常是一个tf.data.Dataset对象用于在训练过程中评估模型性能。
# epochs: 训练的轮数即模型将遍历整个训练数据集的次数。
#
# 返回值:
# history: 一个History对象包含训练过程中的损失和评估指标的历史记录。 epochs 10
history model.fit( train_ds, validation_dataval_ds, epochsepochs
) # 评估模型
# 该代码块用于绘制模型训练过程中的准确率和损失曲线以便可视化模型在训练集和验证集上的表现。 # 从训练历史记录中提取训练集和验证集的准确率及损失值
acc history.history[accuracy]
val_acc history.history[val_accuracy]
loss history.history[loss]
val_loss history.history[val_loss] # 生成一个范围表示训练的轮数epochs
epochs_range range(epochs) # 创建一个大小为12x4的图形窗口
plt.figure(figsize(12, 4)) # 在图形窗口的第一个子图中绘制训练集和验证集的准确率曲线
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, labelTraining Accuracy)
plt.plot(epochs_range, val_acc, labelValidation Accuracy)
plt.legend(loclower right) # 添加图例位置在右下角
plt.title(Training and Validation Accuracy) # 设置子图标题 # 在图形窗口的第二个子图中绘制训练集和验证集的损失曲线
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, labelTraining Loss)
plt.plot(epochs_range, val_loss, labelValidation Loss)
plt.legend(locupper right) # 添加图例位置在右上角
plt.title(Training and Validation Loss) # 设置子图标题 # 显示绘制的图形
plt.show() # 预测
# 该函数用于展示验证数据集中的图片并使用训练好的模型对图片进行预测显示预测结果。
# 函数的主要步骤包括
# 1. 创建一个大小为10x5的图形窗口。
# 2. 设置图形的总标题为“图片预测”。
# 3. 从验证数据集中取出一批图片和标签。
# 4. 对每张图片进行预测并在子图中显示图片和预测结果。
# 5. 关闭子图的坐标轴显示。 plt.figure(figsize(10, 5)) # 创建一个大小为10x5的图形窗口
plt.suptitle(图片预测) # 设置图形的总标题为“图片预测” # 从验证数据集中取出一批图片和标签
for images, labels in val_ds.take(1): # 遍历前8张图片并在子图中显示图片和预测结果 for i in range(8): ax plt.subplot(2, 4, i1) # 创建2行4列的子图并选择第i1个子图 plt.imshow(images[i].numpy().astype(uint8)) # 显示第i张图片 # 对图片进行预测 img_array tf.expand_dims(images[i], 0) # 扩展图片的维度以适应模型输入 predictions model.predict(img_array) # 使用模型进行预测 # 在子图标题中显示预测结果 plt.title(class_names[np.argmax(predictions)]) plt.axis(off) # 关闭子图的坐标轴显示