
我的环境语言环境Python 3.12.7编译器jupyter notebook深度学习环境TensorFlow 2.18.0一、设置GPUimport tensorflow as tf gpus tf.config.list_physical_devices(GPU) if gpus: gpu0 gpus[0] tf.config.experimental.set_memory_growth(gpu0, True) tf.config.set_visible_devices([gpu0],GPU)二、使用步骤1.导入数据PIL- Python Imaging LibraryPython图像库用于图像处理。通常与from PIL import Image一起使用来导入图像。pathlib- 一个内置库提供了面向对象的文件系统路径操作。matplotlib.pyplot as plt-matplotlib库的pyplot模块用于创建静态、交互式和动画可视化图表。numpy库提供多维数组对象和一系列操作这些数组的函数通常以np别名导入。keras 导入TensorFlow库中的keras模块keras是TensorFlow的高级API用于构建和训练深度学习模型。layers, models从tensorflow.keras模块中导入layers和models这些是构建神经网络所需的基础组件。import os,PIL,pathlib import matplotlib.pyplot as plt import numpy as np from tensorflow import keras from tensorflow.keras import layers,models import pathlib data_dir xxx/weather_photos/ data_dir pathlib.Path(data_dir) image_count len(list(data_dir.glob(*/*.jpg))) print(图片总数为,image_count)导入成功后输出2.查看数据导入模块导入PIL和Image用于图像处理导入Path用于路径操作。设置目录路径data_dir应该是一个Path对象指向包含图像的目录。获取文件列表使用glob方法获取所有匹配的文件路径。检查文件列表确保至少有一个文件被找到然后打开第一个文件。打开和显示图像使用Image.open打开图像并使用show方法显示图像。import PIL from PIL import Image roses list(data_dir.glob(sunrise/*.jpg)) PIL.Image.open(str(roses[0]))输出设置参数batch_size 32每个批次包含 32 张图像。img_height 180和img_width 180所有图像将被调整为 180x180 像素的大小。加载数据集data_dir这是一个包含图像的目录路径该目录应该按类别组织每个类别一个子目录。validation_split0.220%的数据将被用作验证集。subsettraining指定加载训练子集。seed123随机种子确保数据分割的可重复性。image_size(img_height, img_width)所有图像将被调整为 180x180 像素的大小。batch_sizebatch_size设置批次大小为 32。batch_size 32 img_height 180 img_width 180 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) class_names train_ds.class_names print(class_names)输出3.可视化数据从训练数据集train_ds中取出一个批次batch的图像然后显示这个批次中的前20张图像设置图形大小plt.figure(figsize(20, 10))创建一个新的图形并设置图形的大小为宽20英寸、高10英寸。从数据集中取出一批图像train_ds.take(1)从训练数据集中取出一个批次的图像和标签。遍历图像和标签for images, labels in train_ds.take(1)遍历取出的图像批次和对应的标签。for i in range(20)由于每个批次包含32张图像这里只遍历前20张图像。显示图像和标签ax plt.subplot(5, 10, i 1)创建一个5行10列的子图布局并定位到当前的子图位置。plt.imshow(images[i].numpy().astype(uint8))将图像数据转换为NumPy数组并显示在子图上。.astype(uint8)确保图像数据类型正确。plt.title(class_names[labels[i]])设置子图的标题为对应的类别名称。plt.axis(off)关闭子图的坐标轴。plt.figure(figsize(20, 10)) for images, labels in train_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[labels[i]]) plt.axis(off)4.检查数据在训练机器学习模型之前检查和验证数据集的格式和结构是否正确。具体来说迭代数据集的目的是为了验证批次大小确认每个批次中图像的数量batch_size是否符合预期。检查图像尺寸确保所有图像都被正确地调整到了指定的尺寸img_height和img_width。确认图像通道检查图像的通道数是否正确例如RGB图像应该有3个通道。检查标签形状确认标签的形状是否正确标签通常是一个一维数组每个元素对应一个批次中的图像。for image_batch, labels_batch in train_ds: print(image_batch.shape) print(labels_batch.shape) breakImage_batch是形状的张量32,180,180,3。这是一批形状180x180x3的32张图片最后一维指的是彩色通道RGB。Label_batch是形状32的张量这些标签对应32张图片5.配置数据集shuffle()打乱数据prefetch()预取数据加速运行prefetch()将训练步骤的预处理和模型执行过程重叠到一起。当加速器正在执行第 N 个训练步时CPU 正在准备第 N1 步的数据。这样做不仅可以最大限度地缩短训练的单步用时而不是总用时而且可以缩短提取和转换数据所需的时间。如果不使用prefetch()CPU 和 GPU/TPU 在大部分时间都处于空闲状态cache()将数据集缓存到内存当中加速运行段代码是在使用 TensorFlow 的tf.dataAPI 来优化数据加载和预处理的性能。以下是每个步骤的详细解释设置 AUTOTUNEAUTOTUNE tf.data.AUTOTUNE这是一个特殊的参数值用于指示 TensorFlow 自动调整以优化性能。在prefetch和其他方法中使用时TensorFlow 会动态调整内部缓冲区的大小和行为以达到最佳性能。缓存数据集train_ds train_ds.cache()这行代码将训练数据集的完整内容缓存到内存中。这意味着数据集将被加载一次然后存储在内存中后续的迭代将直接从内存中读取数据而不是每次都从磁盘加载。这可以显著提高数据读取的速度特别是在处理大型数据集时。打乱数据集shuffle(1000)这行代码将训练数据集打乱。参数1000指定了打乱操作的缓冲区大小即 TensorFlow 会预先加载1000个元素到内存中然后从这个缓冲区中随机选择元素。这有助于确保数据的随机性减少模型训练中的偏差。预取数据prefetch(buffer_sizeAUTOTUNE)这行代码使数据集在训练过程中预取数据。这意味着当模型正在处理当前批次的数据时下一个批次的数据已经在后台被加载和预处理。这样可以减少 CPU 和 GPU 之间的空闲时间提高训练效率。对验证数据集应用缓存和预取val_dsval_ds.cache().prefetch(buffer_sizeAUTOTUNE)这行代码对验证数据集应用了缓存和预取操作。由于验证数据集通常比训练数据集小所以这里没有打乱操作。缓存可以减少从磁盘读取数据的时间预取可以确保在模型评估时数据已经准备好减少等待时间。AUTOTUNE tf.data.AUTOTUNE train_ds train_ds.cache().shuffle(1000).prefetch(buffer_sizeAUTOTUNE) val_ds val_ds.cache().prefetch(buffer_sizeAUTOTUNE)6.构建CNN网络layers.Rescaling(1./255, input_shape(img_height, img_width, 3))这一层将输入图像的像素值从[0, 255]缩放到[0, 1]。layers.Conv2D(16, (3, 3), activationrelu, input_shape(img_height, img_width, 3))第一层卷积层有16个过滤器或卷积核每个大小为3x3使用ReLU激活函数。layers.AveragePooling2D((2, 2))平均池化层池化窗口大小为2x2用于降低特征图的空间尺寸。layers.Conv2D(32, (3, 3), activationrelu)第二层卷积层有32个过滤器每个大小为3x3使用ReLU激活函数。layers.AveragePooling2D((2, 2))第二层平均池化层。layers.Conv2D(64, (3, 3), activationrelu)第三层卷积层有64个过滤器每个大小为3x3使用ReLU激活函数。layers.Dropout(0.3)Dropout层随机丢弃30%的神经元以减少过拟合。layers.Flatten()Flatten层将多维的特征图展平成一维以便输入到全连接层。layers.Dense(128, activationrelu)全连接层有128个神经元使用ReLU激活函数。layers.Dense(num_classes)输出层神经元数量等于类别数通常使用softmax激活函数进行多类分类。import tensorflow as tf from tensorflow.keras import models, layers num_classes 4 img_height 180 # 假设您已经定义了 img_height 和 img_width img_width 180 # 定义模型 model models.Sequential([ layers.Rescaling(1./255, input_shape(img_height, img_width, 3)), layers.Conv2D(16, (3, 3), activationrelu, input_shape(img_height, img_width, 3)), # 卷积层1卷积核3*3 layers.AveragePooling2D((2, 2)), # 池化层12*2采样 layers.Conv2D(32, (3, 3), activationrelu), # 卷积层2卷积核3*3 layers.AveragePooling2D((2, 2)), # 池化层22*2采样 layers.Conv2D(64, (3, 3), activationrelu), # 卷积层3卷积核3*3 layers.Dropout(0.3), # 防止过拟合提高模型的泛化能力 layers.Flatten(), # Flatten层连接卷积层与全连接层 layers.Dense(128, activationrelu), # 全连接层特征进一步提取 layers.Dense(num_classes) # 输出层输出预期结果 ]) model.summary() # 打印网络结构7.编译训练模型model.compile方法用于配置模型的训练参数包括优化器、损失函数和评估指标optimizeropt指定模型使用的优化器为上面创建的Adam优化器。losstf.keras.losses.SparseCategoricalCrossentropy(from_logitsTrue)指定损失函数为SparseCategoricalCrossentropy。这个损失函数适用于多类分类问题特别是当标签以整数形式提供时即标签是类别的索引。参数from_logitsTrue告诉损失函数模型的输出是未经激活函数处理的原始分数即logits因此损失函数内部会应用softmax激活函数来计算损失。如果模型的最后一层使用了softmax激活函数那么应该将from_logits设置为False。metrics[accuracy]指定在训练和评估过程中要计算的指标是准确率。这意味着除了损失值之外还会跟踪模型的准确率以评估模型的性能。opt tf.keras.optimizers.Adam(learning_rate0.001) model.compile(optimizeropt, losstf.keras.losses.SparseCategoricalCrossentropy(from_logitsTrue), metrics[accuracy])这里定义了一个变量epochs它指定了训练过程中将完整遍历训练数据集的次数。每个epoch都会使模型看到整个训练数据集一次。在深度学习中训练模型通常需要多个epoch以便模型有足够的时间学习数据中的复杂模式。这里使用model.fit方法来训练模型。这个方法执行模型的训练过程并监控模型在训练数据和验证数据上的性能。参数如下train_ds这是训练数据集是一个tf.data.Dataset对象包含了输入图像和对应的标签。validation_dataval_ds这是验证数据集也是一个tf.data.Dataset对象用于在每个epoch结束后评估模型的性能。这有助于检测模型是否过拟合即在训练数据上表现很好但在未见过的验证数据上表现差。epochsepochs这指定了训练过程中的epoch数量这里设置为10。historymodel.fit方法返回一个History对象它记录了训练过程中的重要信息包括每个epoch的损失值、准确率以及在验证集上的损失值和准确率。这个对象可以用来分析模型的训练过程比如通过绘制训练和验证的损失和准确率曲线来观察模型的学习进度。epochs 10 history model.fit( train_ds, validation_dataval_ds, epochsepochs )8.模型评估这部分代码创建了一个图表并在第一个子图中绘制了训练和验证的准确率曲线。plt.subplot(1, 2, 1)表示创建一个1行2列的子图布局并在第一个位置绘制。plt.plot用于绘制曲线plt.legend添加图例plt.title添加标题。acc history.history[accuracy] val_acc history.history[val_accuracy] loss history.history[loss] val_loss history.history[val_loss] epochs_range range(epochs) 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()