365天深度学习训练营-第T3周:天气识别

 我的环境:

  • 语言环境:Python3.10.7
  • 编译器:VScode
  • 深度学习环境:TensorFlow2

 一、前期工作:

 

import PIL,pathlib
import matplotlib.pyplot as plt,numpy as np
from tensorflow.keras import layers,models
from tensorflow import keras
 
path = 'D:\weather\weather_photos'
data = pathlib.Path(path)

‘data = pathlib.Path(path)’代码中Path对象是pathlib模块的核心对象,它提供了一种面向对象的方式来处理文件和目录路径。使用Path对象可以执行各种与路径相关的操作,如访问文件、目录,获取文件属性,创建、移动、删除文件或目录,以及执行路径操作等。

pathlib.Path()函数接受一个路径字符串作为参数,并返回一个对应的Path对象。可以使用这个对象来执行各种路径操作,如路径拼接、路径解析、判断路径是否存在、访问路径的各个部分(文件名、父目录、扩展名等),以及进行路径的文件操作(读取、写入、复制等)。

查看图片张数 

#查看图片张数
image = len(list(data.glob('*\*.jpg')))
print(image)

上述代码的作用是统计指定路径下('D:\weather\weather_photos')所有扩展名为.jpg的图片的数量,并将结果打印出来。

 查看sunrise文件夹的第一张图片

#查看sunrise文件夹的第一张图片
sunrise = list(data.glob('sunrise\\*.jpg'))
firstPic = PIL.Image.open(str(sunrise[0]))
firstPic.show()

 运行结果:

 二、 数据预处理 

`image_dataset_from_directory`是TensorFlow中的一个函数,用于从文件夹中加载图像数据集。

它的用法如下:

tf.keras.preprocessing.image_dataset_from_directory(
    directory,
    labels='inferred',
    label_mode='int',
    class_names=None,
    color_mode='rgb',
    batch_size=32,
    image_size=(256, 256),
    shuffle=True,
    seed=None,
    validation_split=None,
    subset=None,
    interpolation='bilinear',
    follow_links=False
)


参数说明:
 `directory`:字符串,表示数据集所在的文件夹路径。
 `labels`:可选参数,用于指定标签的生成方式。默认为`'inferred'`,根据文件夹的结构自动推断标签。也可以传递一个包含标签的字典。
 `label_mode`:可选参数,指定标签的数据类型。默认为`'int'`,表示标签将被编码为整数。可以设置为`'categorical'`,表示标签将被编码为独热编码。
 `class_names`:可选参数,用于指定类别的名称。默认为`None`,表示类别名称将从文件夹的名称中推断。
 `color_mode`:可选参数,指定图像的颜色模式。默认为`'rgb'`,表示彩色图像。可以设置为`'grayscale'`,表示灰度图像。
 `batch_size`:可选参数,指定每个批次中的图像数量。默认为32。
 `image_size`:可选参数,指定图像的大小。默认为`(256, 256)`,表示图像将被调整为256x256的大小。
 `shuffle`:可选参数,指定是否对数据进行洗牌。默认为`True`。
 `seed`:可选参数,指定洗牌的随机种子。
 `validation_split`:可选参数,用于指定在拆分数据集时保留作为验证集的比例。
 `subset`:可选参数,用于指定要加载的数据子集。可以是`'training'`、`'validation'`或`None`。
 `interpolation`:可选参数,用于指定图像的插值方法。默认为`'bilinear'`。
 `follow_links`:可选参数,指定是否跟随符号链接。

函数返回一个`tf.data.Dataset`对象,该对象包含了从文件夹中加载的图像数据集。可以使用这个数据集对象进行模型的训练和评估。

使用image_ dataset_ from_ directory 方法将磁盘中的数据加载到tf . data . Dataset中

#定义图片格式
batch_size = 32
img_height = 180
img_width = 180
 
#将数据导入tf.data.Dataset
train_ds = keras.preprocessing.image_dataset_from_directory(
    #数据所在目录
    data,
    #指定在拆分数据集时保留作为验证集的比例
    validation_split=0.2,
    #加载训练集
    subset='training',
    #选择随机数种子
    seed=123,
    #图片格式
    image_size=(img_height,img_width),
    #设置处理批次的大小
    batch_size=batch_size
    )

运行结果: 

 输出数据集标签

class_name = train_ds.class_names
print(class_name)

 运行结果:

三、可视化数据

   将图片可视化

plt.figure(figsize=(20,10))
 
for image,labels in train_ds.take(1):
    for i in range(20):
        plt.subplot(2,10,i+1)
        plt.imshow(image[i].numpy().astype('uint8'))
        plt.title(train_ds.class_names[labels[i]])
        plt.axis('off')
plt.show()

 运行结果:

 四、次检测数据 

for image_batch,labels_batch in train_ds:
    print(image_batch.shape)
    print(labels_batch.shape)
    break
  • print(image_batch.shape):打印当前批次的图像张量的形状。image_batch 是一个包含多个图像的张量,其形状为 (batch_size, img_height, img_width, num_channels),其中 batch_size 是批次大小,img_heightimg_width 是图像的高度和宽度,num_channels 是图像的通道数。

  • print(labels_batch.shape):打印当前批次的标签张量的形状。labels_batch 是一个包含多个标签的张量,其形状为 (batch_size,),表示每个图像对应的单个标签。批次大小与图像张量的第一维大小一致。

运行结果 : 

 五、  配置数据集

AUTOTUNE = tf.data.AUTOTUNE
 
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
shuffle():打乱数据

具体来说,shuffle(1000) 的作用是将数据集中的样本顺序进行随机打乱,以增加样本之间的独立性,并减少模型训练时对数据的记忆性。

参数 1000 表示要在数据集中创建一个缓冲区,其中包含 1000 个样本。在进行数据读取时,会从缓冲区中随机选择样本,并将其作为当前的批次。每个样本在缓冲区中的位置是随机的,并且会随着每个批次的读取而不断更新。

prefetch():预取数据,加速执行

prefetch()功能详细介绍: CPU正在准备数据时,加速器处于空闲状态。相反,当加速器正在训练模型时,CPU处于空闲状态。因此,训练所用的时间是CPU预处理时间和加速器训练时间的总和。
prefetch()将训练步骤的预处理和模型执行过程重叠到一起。当加速器正在执行第N个训练步时,CPU正在准备第N+1步的数据。这样做不仅可以最大限度地缩短训练的单步用时(而不是总用时),而且可以缩短提取和转换数据所需的时间。如果不使用prefetch() ,CPU和GPU/TPU在大部分时间都处于空闲状态。

cache():将数据缓存到内存当中

运行结果:

 

 六、构建cnn网络

#设置Sequential模型,创建神经网络
model = models.Sequential([
    layers.experimental.preprocessing.Rescaling(1./255,input_shape=(img_height,img_width,3)),
    #设置二维卷积层1,设置32个3*3卷积核,activation参数将激活函数设置为ReLU函数
    #input_shape设置图形的输入形状
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(img_height, img_width, 3)),
    #池化层1,2*2采样
    layers.AveragePooling2D(2*2),
    #设置二维卷积层2,设置64个3*3卷积核,激活函数设置为ReLU函数
    layers.Conv2D(64, (3, 3), activation='relu'),
    #池化层2,2*2采样
    layers.AveragePooling2D((2, 2)),
    #设置停止工作概率,防止过拟合
    layers.Dropout(0.3),
 
    #Flatten层,用于连接卷积层与全连接层
    layers.Flatten(),
    #全连接层,特征进一步提取,64为输出空间的维数(神经元),激活函数为ReLU函数
    layers.Dense(128,activation='relu'),
    #输出层,4为输出空间的维数
    layers.Dense(4)
])
#打印网络结构
model.summary()

运行结果:

七、编译 

#设置优化器
opt = keras.optimizers.Adam(learning_rate=0.001)
model.compile(
    #设置优化器为Adam优化器
    optimizer = opt,
    #设置损失函数为交叉熵损失函数
    #from_logits为True时,会将y_pred转化为概率
    loss = keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    #设置性能指标列表,将在模型训练时对列表中的指标进行监控
    metrics = ['accuracy']
)

运行结果:

 

 八、训练模型 

#设置训练数据集、验证数据集以及迭代次数
history = model.fit(
    train_ds,
    validation_data=val_ds,
    #迭代次数,每个epoch都会将所有数据输入模型完成一次训练
    epochs=10)

代码运行结果: 

 

 

 

九、完整代码及总结

import PIL,pathlib
import matplotlib.pyplot as plt,numpy as np
from tensorflow.keras import layers,models
from tensorflow import keras
import tensorflow as tf
 
path = 'D:\weather\weather_photos'
data = pathlib.Path(path)

#定义图片格式
batch_size = 32
img_height = 180
img_width = 180
 
train_ds = keras.preprocessing.image_dataset_from_directory(
    data,
    validation_split=0.2,
    subset='training',
    seed=123,
    image_size=(img_height,img_width),

    batch_size=batch_size
    )


val_ds = keras.preprocessing.image_dataset_from_directory(
    data,
    validation_split=0.2,
    subset='validation',
    seed=123,
    image_size=(img_height,img_width),
    batch_size=batch_size
    )

AUTOTUNE = tf.data.AUTOTUNE
 
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)


model = models.Sequential([
    layers.experimental.preprocessing.Rescaling(1./255,input_shape=(img_height,img_width,3)),
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(img_height, img_width, 3)),
    layers.AveragePooling2D(2*2),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.AveragePooling2D((2, 2)),
    layers.Dropout(0.3),
    layers.Flatten(),
    layers.Dense(128,activation='relu'),
    layers.Dense(4)
])


opt = keras.optimizers.Adam(learning_rate=0.001)
model.compile(
    optimizer = opt,
    loss = keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics = ['accuracy']
)


history = model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=10)

        代码实现了基于 TensorFlow 的图像分类任务的基本流程。它包括了数据加载、预处理和模型训练的步骤。

1. 通过 `keras.preprocessing.image_dataset_from_directory` 函数,从指定目录加载图像数据集。这个函数会自动解析数据集文件夹的结构,并创建一个 `tf.data.Dataset` 对象用于存储数据。

2. 定义了图像的批处理大小 `batch_size`,以及图像的高度 `img_height` 和宽度 `img_width`。

3. 使用 `image_dataset_from_directory` 函数加载数据集,并设置了一些参数,如 `validation_split`(指定验证集比例)、`subset`(选择训练集或验证集)和 `seed`(随机数种子),以及图像的大小。

4. 通过遍历 `train_ds` 数据集,获取第一个批次的图像和标签,并使用 `matplotlib.pyplot` 进行可视化展示。这个过程用于检查数据加载和预处理的正确性。

5. 使用 `train_ds.cache()` 对训练数据集进行缓存操作,加快数据读取速度。

6. 使用 `train_ds.shuffle(1000)` 对训练数据集进行随机打乱操作,增加样本之间的独立性。

7. 使用 `train_ds.prefetch(buffer_size=AUTOTUNE)` 对训练数据集进行预取操作,以在训练模型时减少数据的等待时间。

总的来说,该代码实现了以下功能:加载图像数据集、进行数据预处理(包括图像大小调整和随机打乱)、创建数据集对象、进行数据可视化、缓存数据、设置数据预取以及模型训练。

十、模型评估

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

上述代码是用于绘制训练和验证准确率以及训练和验证损失随着训练周期的变化趋势的图表。

 `acc = history.history['accuracy']`:从训练历史记录中获取训练准确率的数值列表。
 `val_acc = history.history['val_accuracy']`:从训练历史记录中获取验证准确率的数值列表。
 `loss = history.history['loss']`:从训练历史记录中获取训练损失的数值列表。
 `val_loss = history.history['val_loss']`:从训练历史记录中获取验证损失的数值列表。
 `epochs_range = range(epochs)`:创建一个表示训练周期范围的迭代器,其中 `epochs` 是训练周期的总数。

接下来,使用 `matplotlib.pyplot` 绘制图表:
 `plt.figure(figsize=(12, 4))`:创建一个图表对象,设置图表的大小为 (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')`:设置子图的标题为 "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')`:设置子图的标题为 "Training and Validation Loss"。
 `plt.show()`:显示图表。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值