第T3周:CNN实现天气识别

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

目标
搭建CNN网络模型实现多云、下雨、晴、日出四种天气状态的识别,并用真实天气做预测
具体实现
(一)环境
语言环境:Python 3.10
编 译 器: PyCharm
框 架: Tensorflow
**(二)具体步骤:

1. 使用GPU

之前的GPU一直没检测出来 ,今天参考windows安装tensorflow-gpu / CUDA / cuDNN - 前端大兵 - 博客园和 Build from source on Windows | TensorFlow,主要的就是保证python版本、cuda版本, cuDNN以及Tensorflow版本一致。我的Python版本是3.8,cuda安装的是11.2,查看如下:
image.png
那么cudnn和tensowflow-gpu的版本也找到了,直接下载安装就成。看成果:

import os  
import PIL  
import pathlib  
import matplotlib.pyplot as plt  
import numpy as np  
import tensorflow as tf  
from tensorflow import keras  
from tensorflow.keras import layers, models 
  
gpus = tf.config.list_physical_devices("GPU")  
print(gpus)  
if gpus:  
    gpu0 = gpus[0]  
    # print(gpu0)  
    tf.config.experimental.set_memory_growth(gpu0, True)  
    tf.config.set_visible_devices([gpu0], "GPU")

image.png
解决。

2.查看数据

在工程根目录下创建了一个datasets目录,然后下面有一个weather_photos的子目录,再下面分为cloudy(多云)、rain(雨天)、shine(晴天)和sunrise(日出)4种天气类型。
image.png

# 导入数据集  
data_dir = "datasets/weather_photos/"  
data_dir = pathlib.Path(data_dir)   # 将目录转换成pathlib.Path类对象,以便使用Path的各种方法  
print(data_dir)  
  
# 查看数据  
# 查看目录下所在.jpg文件的数据。glob方法是按.jpg去匹配所有文件。要能够使用glob方法,需要上当是pathlib.Path类的对象。  
image_count = len(list(data_dir.glob('*/*.jpg')))  
print("图片总数为:", image_count)  
# 看一下shine目录下的图片  
shine = list(data_dir.glob('sunrise/*.jpg'))  
print("shine目录共有:%d 个图片" % len(shine))  
im = PIL.Image.open(str(shine[0]))  
im.show()

image.png
image.png

3.加载数据

使用image_dataset_from_directory方法将文件目录中的数据加载到tf.data.Dataset中.

# 加载数据  
batch_size = 32  
image_height = 180  
image_width = 180  
  
train_ds = tf.keras.preprocessing.image_dataset_from_directory(  
    data_dir,       # 文件所在目录  
    validation_split=0.2,  
    subset="training",  
    seed=123,  
    image_size=(image_height, image_width),  
    batch_size=batch_size  
)  
  
val_ds = tf.keras.preprocessing.image_dataset_from_directory(  
    data_dir,  
    validation_split=0.2,  
    subset="validation",  
    seed=123,  
    image_size=(image_height, image_width),  
    batch_size=batch_size  
)  
#print(train_ds, val_ds)  
class_names = train_ds.class_names  
print(class_names)

image.png

4.配置数据集

# 预提取数据,加速运行  
AUTOTUNE = tf.data.AUTOTUNE  
  
# cache():将数据加载到内存中,加速运行  
# shuffle():打乱数据,参考:https://zhuanlan.zhihu.com/p/42417456  
# prefetch():预取数据,加速运行  
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)  
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)

5.构建CNN网络

image.png

# 构建CNN网络  
num_classes = 4  
model = models.Sequential([  
    layers.experimental.preprocessing.Rescaling(1./255, input_shape=(image_height, image_width, 3)),  
    layers.Conv2D(16, (3, 3), activation='relu', input_shape=(image_height, image_width, 3)),  
    layers.AveragePooling2D((2, 2)), # 池化层1,2*2采样  
    layers.Conv2D(32, (3, 3), activation='relu'),   # 卷积层2,卷积核3*3  
    layers.AveragePooling2D((2, 2)), # 池化层2,2*2采样  
    layers.Conv2D(64, (3, 3), activation='relu'),    # 卷积层3,卷积核3*3  
    layers.Dropout(0.3),    # 让神经元以一定的概率停止工作,防止过拟合,提高模型的泛化能力。  
  
    layers.Flatten(),   # Flatten层,连接卷积层与全连接层  
    layers.Dense(128, activation='relu'),   # 全连接层,特征进一步提取  
    layers.Dense(num_classes)    # 输出层,输出预期结果  
])  
  
print(model.summary())
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 rescaling (Rescaling)       (None, 180, 180, 3)       0         
                                                                 
 conv2d (Conv2D)             (None, 178, 178, 16)      448       
                                                                 
 average_pooling2d (AverageP  (None, 89, 89, 16)       0         
 ooling2D)                                                       
                                                                 
 conv2d_1 (Conv2D)           (None, 87, 87, 32)        4640      
                                                                 
 average_pooling2d_1 (Averag  (None, 43, 43, 32)       0         
 ePooling2D)                                                     
                                                                 
 conv2d_2 (Conv2D)           (None, 41, 41, 64)        18496     
                                                                 
 dropout (Dropout)           (None, 41, 41, 64)        0         
                                                                 
 flatten (Flatten)           (None, 107584)            0         
                                                                 
 dense (Dense)               (None, 128)               13770880  
                                                                 
 dense_1 (Dense)             (None, 4)                 516       
                                                                 
=================================================================
Total params: 13,794,980
Trainable params: 13,794,980
Non-trainable params: 0
_________________________________________________________________

6.编译

# 编译  
# 设置优化器  
opt = tf.keras.optimizers.Adam(learning_rate=0.001)  
# 设置损失函数  
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)  
model.compile(optimizer=opt,  
              loss=loss,  
              metrics=['accuracy'])

7.训练模型

# 训练模型  
epochs = 10  
history = model.fit(  
    train_ds,  
    validation_data=val_ds,  
    epochs=epochs  
)
Epoch 1/10
29/29 [==============================] - 7s 34ms/step - loss: 1.3898 - accuracy: 0.5567 - val_loss: 0.7499 - val_accuracy: 0.6311
Epoch 2/10
29/29 [==============================] - 0s 17ms/step - loss: 0.4811 - accuracy: 0.8222 - val_loss: 0.4955 - val_accuracy: 0.8089
Epoch 3/10
29/29 [==============================] - 1s 18ms/step - loss: 0.3696 - accuracy: 0.8644 - val_loss: 0.4990 - val_accuracy: 0.8044
Epoch 4/10
29/29 [==============================] - 0s 17ms/step - loss: 0.2541 - accuracy: 0.8967 - val_loss: 0.5235 - val_accuracy: 0.8089
Epoch 5/10
29/29 [==============================] - 0s 17ms/step - loss: 0.3015 - accuracy: 0.8911 - val_loss: 0.5760 - val_accuracy: 0.7822
Epoch 6/10
29/29 [==============================] - 0s 17ms/step - loss: 0.2394 - accuracy: 0.9122 - val_loss: 0.6048 - val_accuracy: 0.8044
Epoch 7/10
29/29 [==============================] - 0s 17ms/step - loss: 0.2118 - accuracy: 0.9311 - val_loss: 0.4987 - val_accuracy: 0.8000
Epoch 8/10
29/29 [==============================] - 0s 17ms/step - loss: 0.1307 - accuracy: 0.9544 - val_loss: 0.4711 - val_accuracy: 0.8311
Epoch 9/10
29/29 [==============================] - 0s 17ms/step - loss: 0.0958 - accuracy: 0.9667 - val_loss: 0.6813 - val_accuracy: 0.8000
Epoch 10/10
29/29 [==============================] - 0s 17ms/step - loss: 0.1063 - accuracy: 0.9678 - val_loss: 0.4737 - val_accuracy: 0.8489

8.模型评估

# 模型评估  
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()

image.png

9.数据增强

从上面的模型评估上看,训练准确率远高于验证准确率。是不是就是传说中的过拟合现象,查阅资料发现,过拟合的情况有很多,其中数据量不足也是其中一种原因,可以通过数据增加的方式,将原有的数据变换不同的形式加入到数据集中。比如一张图片,通过放大,缩小、旋转等数据增强,一同加入训练(加入训练的过程是自动的,不用额外处理,只需要处理怎么做数据增强就行)。参考: 数据增强 | TensorFlow Core

# 数据增强  
data_augmentation = keras.Sequential([  
    layers.RandomFlip("horizontal", input_shape=(image_height, image_width, 3)),    # 随机翻转  
    layers.RandomRotation(0.1),     # 随机旋转  
    layers.RandomZoom(0.1),         # 随机缩放  
])

应用数据增强,直接加到model的Sequential里面:

model = models.Sequential([  
    data_augmentation,  # 数据增强  
    layers.experimental.preprocessing.Rescaling(1./255, input_shape=(image_height, image_width, 3)),  
    layers.Conv2D(16, (3, 3), activation='relu', input_shape=(image_height, image_width, 3)),  
    layers.AveragePooling2D((2, 2)), # 池化层1,2*2采样  
    layers.Conv2D(32, (3, 3), activation='relu'),   # 卷积层2,卷积核3*3  
    layers.AveragePooling2D((2, 2)), # 池化层2,2*2采样  
    layers.Conv2D(64, (3, 3), activation='relu'),    # 卷积层3,卷积核3*3  
    layers.Dropout(0.3),    # 让神经元以一定的概率停止工作,防止过拟合,提高模型的泛化能力。  
  
    layers.Flatten(),   # Flatten层,连接卷积层与全连接层  
    layers.Dense(128, activation='relu'),   # 全连接层,特征进一步提取  
    layers.Dense(num_classes)    # 输出层,输出预期结果  
])

再次训练:
image.png
从结果来看,不是太理想,似乎也没有解决过拟合的问题,本次主要学习方式方法,后面慢慢学习研究。

10.保存模型

# 保存模型  
model.save('models/weatherModel.pth')

image.png

11.加载保存的模型,并进行图片预测

准备预测的图片如下(晴天):
image.png

新建立一个python文件,代码如下:

import tensorflow as tf  
import numpy as np  
  
image_height = 180  
image_width = 180  
  
class_names = ['cloudy', 'rain', 'shine', 'sunrise']  
# 加载天气识别模型  
model = tf.keras.models.load_model('models/weatherModel.pth')  
# 预测一下真实照片  
image_path = 'data/laker.jpg'  
image = tf.keras.utils.load_img(image_path, target_size=(image_height, image_width))  
image_array = tf.keras.utils.img_to_array(image)  # 将PIL对象转换成numpy数组  
# print(image_array.shape)  
# 在image_array的第0位置增加一个维度即batch。(batch, height, width, channel)  
image_array = tf.expand_dims(image_array, 0)  
  
pre = model.predict(image_array)  
# print(pre)  
score = tf.nn.softmax(pre[0])  
print(  
    "当前图片预测有{:.2f}%概率为{}天气 ".format(100 * np.max(score), class_names[np.argmax(score)])  
)

结果:
image.png
预测是晴天,结果是正确的。
(三)总结
1.如何检测GPU并使用GPU进行大模型训练与预测
2.与之前不一样的数据集的加载与处理方式
3.不同的损失函数,池化层函数,学习率和准确率之间有什么关系?需要继续了解
4.怎么解决过拟合的问题呢,后续学习研究。
5.学习数据增加的方式方法
6.每次模型训练完,进行真实图片的预测,应该模型能够保存后直接调用才对,不可能每次使用都需要重新训练一遍。学习模型的保存与加载使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2192734.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Win10照片查看器不见了怎么办?

刚换了电脑,发现查看图片默认打开是window画图工具,看图竟然需要一张一张打开,超级不方便。右键图片选择打开方式也不见照片查看器,window自带的看图工具去哪儿了? 不要着急,我们可以把它找回来&#xff0…

windows下DockerDesktop命令行方式指定目录安装

windows下DockerDesktop指定目录安装(重新安装) 因为DcokerDesktop占用内存较大, 并且拉去镜像后占用本地空间较多,所以建议安装时就更改默认安装路径和镜像存储路径 这里,展示了从下载到安装的过程: 首先下载DcokerDesktop;找到Docker Desktop Installer.exe 并重命名为 do…

万界星空科技MES数据集成平台

制造执行系统MES作为连接企业上层ERP系统和现场控制系统的桥梁,承担了实时数据采集、处理、分析和传递的重要任务。MES数据集成平台是一个集成各类数据源,将数据进行整合和统一管理的系统,通过提供标准化接口和协议,实现数据的无缝…

上海交通大学《2022年+2023年816自动控制原理真题》 (完整版)

本文内容,全部选自自动化考研联盟的:《上海交通大学816自控考研资料》的真题篇。后续会持续更新更多学校,更多年份的真题,记得关注哦~ 目录 2022年真题 2023年真题 Part1:2022年2023年完整版真题 2022年真题 2023年…

强大的JVM监控工具

介绍 在生产环境中,经常会遇到各种各样奇葩的性能问题,所以掌握最基本的JVM命令行监控工具还是很有必要的 名称主要作用jps查看正在运行的Java进程jstack打印线程快照jmap导出堆内存映像文件jstat查看jvm统计信息jinfo实时查看和修改jvm配置参数jhat用…

github上下载ultralytics代码报错

1.在GitHub上下载ultralytics的yolo源代码使用,报错提示找不到ultralytics 2.主要原因引用的路径不对 3.解决的办法,只复制ultralytics中ultralytics文件夹到项目中,其他的文件夹是不需要的。

【电路】1.1 实际电路和电路模型

1.1 实际电路和电路模型 科学理论的研究对象是现实世界背后的抽象世界,如: 数学中的 ∞ \infty ∞,经典力学中“质点”的概念,牛顿运动定律(如惯性定律,如果一个物体不受外力情况下,一直保持匀…

虚拟机ip突然看不了了

打印大致如下: 解决办法 如果您发现虚拟机的IP地址与主机不在同一网段,可以采取的措施之一是调整网络设置。将虚拟机的网络模式更改为桥接模式,这样它就会获得与主机相同的IP地址,从而处于同一网段。或者,您可以使用…

主播齐聚 “崆峒好物 国庆有礼” 直播活动

2024 年 10 月,一场充满活力与意义的 “崆峒好物 国庆有礼” 直播活动盛大开启,吸引了多位知名主播的积极参与,其中甘肃耀龙、会宁马千、老杨助农、零零发、农民助农等主播的加入,更是为这场活动增添了绚丽的色彩。 甘肃耀龙&…

Python异常处理中的9个常见错误及其解决办法,建议收藏

在Python编程中,异常处理是确保程序健壮性和可靠性的重要部分。然而,在使用异常处理时,开发者可能会犯一些常见的错误。以下是9个常见的异常处理错误及其解决办法: 1. 语法错误 (SyntaxError) 语法错误是最常见的错误之一。它通…

知识竞赛活动直播应如何搞呢?流程是怎样的?

很多知识竞赛活动选择通过直播的方式进行传播。直播都为观众带来了更加便捷和丰富的观看体验。那么,知识竞赛活动直播流程究竟是怎样进行的呢? 1、前期筹备 在知识竞赛活动开始之前,策划团队需要对整个直播过程进行详细的规划和筹备。 这包…

选择最佳HR系统_6款产品评测与推荐

本文盘点了ZohoPeople、SAPSuccessFactors等六款主流HRMS,各系统各具特色,如ZohoPeople的全球化云管理、SAP的高定制化、Workday的实时数据分析等,适合不同规模企业需求,建议企业试用后决策。 一、Zoho People Zoho People 是一个…

海贝音乐 4.3.1 完全免费,手机本地无损,支持在线获取歌词和封面

海贝音乐是一款专为HiFi用户设计的本地音乐播放器,支持在线获取封面和歌词,支持均衡器,完全免费,界面优美,无任何广告。 大小:43M 百度网盘:https://pan.baidu.com/s/1efDXtD62hoxVxx3R9ENwDA?…

DNABERT: 一个基于 Transformer 双向编码器表征的预训练 DNA 语言模型

本文结合 DNABERT 的原文,主要介绍了: Overview of DNABERT 开发 DNABERT 的背景 DNABERT 的 tokenization DNABERT 的模型架构 DNABERT 的预训练 基于微调 DNABERT 的应用 1. Overview of DNABERT 我们之前介绍了 BERT,它是一个基于 Transfo…

【ssh-xorg】SSH远程配置X11窗口回传

前言 我们通常在进行远程配置板端的时候往往会出现一个问题,在不连接显示屏或者启用VNC服务的前提下(或者使用其他软件提供的功能),我们无法在远程终端看到板端的新窗口,本文提供一种方式,在进行ssh远程连接时候制定参数-CX&…

SpringIoC容器的初识

一、SpringIoC容器的介绍 Spring IoC 容器,负责实例化、配置和组装 bean(组件)。容器通过读取配置元数据来获取有关要实例化、配置和组装组件的指令。配置元数据以 XML、Java 注解或 Java 代码形式表现。它允许表达组成应用程序的组件以及这…

Vueron引领未来出行:2026年ADAS激光雷达解决方案上市路线图深度剖析

Vueron ADAS激光雷达解决方案路线图分析:2026年上市展望 Vueron近期发布的ADAS激光雷达解决方案路线图,标志着该公司在自动驾驶技术领域迈出了重要一步。该路线图以2026年上市为目标,彰显了Vueron对未来市场趋势的精准把握和对技术创新的坚定…

如何实现 C/C++ 与 Python 的通信?

在现代编程中,C/C与Python的通信已经成为一种趋势,尤其是在需要高性能和灵活性的场景中。本文将深入探讨如何实现这两者之间的互通,包括基础和高级方法,帮助大家在混合编程中游刃有余。 C/C 调用 Python(基础篇&#…

AI 时代:产品经理不“AI”就出局?

即便你没想去做“AI 产品经理”,那你也不能成为一个不会用 AI 的产品经理。 产品经理肯定是所有互联网从业者中,最先捕捉到 AI 趋势的岗位。 但只知道 AI、关注 AI 还不够,仔细审视一下:你自己的工作,被 AI 提效了么…

打造自己的RAG解析大模型:Windows部署OCR服务(可商业应用)

在上一篇文章中,我们介绍了如何在 Windows 环境中配置 OCR 相关模型,并完成了模型验证。本篇文章将基于之前的内容,进一步讲解如何将文本检测、方向分类和文本识别模型进行串联,最终搭建一个基础的 OCR 应用服务。通过这些模型的串…