基于神经网络结合紫外差分光谱的二氧化硫浓度定量预测

基于神经网络结合紫外差分光谱的二氧化硫浓度定量预测

  • 前言
  • 一、代码运行
    • 1. 解压数据
    • 2. 导包
    • 3. 读取数据
    • 4. 构建网络
    • 5. 设置优化器
    • 6. 模型训练
    • 7. 可视化loss
    • 8. 模型验证
  • 二、结果展示
  • 三、总结
  • 作者简介

前言

二氧化硫(SO2)是一种常见的环境污染物,对大气、水体和土壤等环境有着广泛的影响。因此,准确监测和预测大气中的二氧化硫浓度对于环境管理和污染控制具有重要意义。紫外差分光谱是一种常用于二氧化硫浓度监测的方法,通过测量大气中SO2在紫外光波段的吸收特性来进行定量分析。
本项目旨在通过应用神经网络技术,结合紫外差分光谱数据,实现对二氧化硫浓度的准确定量预测。项目将采用从不同环境中收集的紫外差分光谱数据,包括大气中SO2的光谱吸收特性以及环境参数(如温度、湿度等),作为输入特征。基于这些输入特征,将建立一个神经网络模型,通过对历史数据的学习和训练,实现对二氧化硫浓度的预测。

项目计划包括以下步骤:

  1. 数据采集和准备:从不同环境中采集紫外差分光谱数据,包括SO2的光谱吸收特性以及环境参数。对采集到的数据进行处理和准备,包括数据清洗、特征提取和特征工程等。
  2. 模型选择和设计:根据项目需求,选择合适的神经网络模型,并进行模型的设计。可以考虑使用常见的神经网络模型,如多层感知器(MLP)、卷积神经网络(CNN)或循环神经网络(RNN)等。
  3. 模型训练和调优:使用采集到的紫外差分光谱数据,对选定的神经网络模型进行训练和调优。包括将数据集划分为训练集和验证集,进行模型参数的优化和调整,以获得最佳的预测性能。
  4. 模型评估和验证:通过对模型进行评估和验证,包括使用测试数据集进行性能测试,评估模型的预测准确性、稳定性和可靠性。根据评估结果进行模型的调整和优化。
  5. 结果解释和应用:根据训练好的神经网络模型,实现对二氧化硫的浓度预测

在这里插入图片描述

一、代码运行

本文的代码是基于百度的BML Codelab编写,项目地址:基于神经网络结合紫外差分光谱的二氧化硫浓度定量预测,数据在项目中被提供。

1. 解压数据

# 运行完一次记得注释掉
!unzip /home/aistudio/data/data208645/Data.zip -d ./data

2. 导包

import pandas as pd
import paddle
import numpy as np
from sklearn.model_selection import cross_val_score, train_test_split
import matplotlib.pyplot as plt

3. 读取数据

train_data = pd.read_excel("./data/Data/train.xlsx", header=None)
val_data = pd.read_excel("./data/Data/val.xlsx", header=None)
test_data = pd.read_excel("./data/Data/test.xlsx", header=None)
print("加载数据完成!")print("train_data:",train_data)
print("val_data:",val_data)
print("test_data:",test_data)

4. 构建网络

class Regressor(paddle.nn.Layer):# self代表类的实例自身def __init__(self):# 初始化父类中的一些参数super(Regressor, self).__init__()self.fc1 = paddle.nn.Linear(in_features=423, out_features=40)self.fc2 = paddle.nn.Linear(in_features=40, out_features=20)self.fc3 = paddle.nn.Linear(in_features=20, out_features=1)self.relu = paddle.nn.ReLU()# 网络的前向计算def forward(self, inputs):x = self.fc1(inputs)x = self.relu(x)x = self.fc2(x)x = self.relu(x)x = self.fc3(x)x = self.relu(x)return x

5. 设置优化器

# 声明定义好的线性回归模型
model = Regressor()# 开启模型训练模式
model.train()# 定义优化算法,使用随机梯度下降SGD
opt = paddle.optimizer.SGD(learning_rate=0.01, parameters=model.parameters())

6. 模型训练

EPOCH_NUM = 20   # 设置外层循环次数
BATCH_SIZE =32  # 设置batch大小
loss_train = []
loss_val = []
training_data = train_data.values.astype(np.float32)
val_data = val_data.values.astype(np.float32)
# 定义外层循环
for epoch_id in range(EPOCH_NUM):# 在每轮迭代开始之前,将训练数据的顺序随机的打乱np.random.shuffle(training_data)# 将训练数据进行拆分,每个batch包含10条数据mini_batches = [training_data[k:k+BATCH_SIZE] for k in range(0, len(training_data), BATCH_SIZE)]train_loss = []for iter_id, mini_batch in enumerate(mini_batches):# 清空梯度变量,以备下一轮计算opt.clear_grad()x = np.array(mini_batch[:, :-1])y = np.array(mini_batch[:, -1:])# 将numpy数据转为飞桨动态图tensor的格式features = paddle.to_tensor(x)y = paddle.to_tensor(y)# 前向计算predicts = model(features)# 计算损失loss = paddle.nn.functional.l1_loss(predicts, label=y)avg_loss = paddle.mean(loss)train_loss.append(avg_loss.numpy())# 反向传播,计算每层参数的梯度值avg_loss.backward()# 更新参数,根据设置好的学习率迭代一步opt.step()mini_batches = [val_data[k:k+BATCH_SIZE] for k in range(0, len(val_data), BATCH_SIZE)]val_loss = []for iter_id, mini_batch in enumerate(mini_batches):x = np.array(mini_batch[:, :-1])y = np.array(mini_batch[:, -1:])features = paddle.to_tensor(x)y = paddle.to_tensor(y)predicts = model(features)loss = paddle.nn.functional.l1_loss(predicts, label=y)avg_loss = paddle.mean(loss)val_loss.append(avg_loss.numpy())loss_train.append(np.mean(train_loss))loss_val.append(np.mean(val_loss))print(f'Epoch {epoch_id}, train MAE {np.mean(train_loss)}, val MAE {np.mean(val_loss)}')

7. 可视化loss

# loss
x = np.linspace(0, EPOCH_NUM+1, EPOCH_NUM)plt.figure()
plt.plot(x, loss_train, color='red', linewidth=1.0, linestyle='--', label='line')
plt.plot(x, loss_val, color='y', linewidth=1.0, label='line')
plt.savefig('loss.png', dpi=600, bbox_inches='tight', transparent=False)
plt.legend(["train MAE", "val MAE"])
plt.title("Loss")
plt.xlabel('epoch_num')
plt.ylabel('loss value')

在这里插入图片描述

8. 模型验证

model.eval()
test_data = paddle.to_tensor(test_data.values.astype(np.float32))
test_predict = model(test_data)
test_predict = test_predict.numpy().flatten()
test_predict = test_predict.round().astype(int)
print("test_predict:",test_predict)

在这里插入图片描述

二、结果展示

x = np.linspace(0, 10, 9)
Y_test = [4,9,5,6,7,14,12,13,15]
Y_test = np.array(Y_test)predicted = test_predict
plt.figure()
plt.scatter(x, predicted, color='red')  # 画点
plt.scatter(x, Y_test, color='y')  # 画点
plt.plot(x, predicted, color='red', linewidth=1.0, linestyle='--', label='line')
plt.plot(x, Y_test, color='y', linewidth=1.0, label='line')
plt.savefig('result.png', dpi=600, bbox_inches='tight', transparent=False)
plt.legend(["predict value", "true value"])
plt.title("SO2")
plt.xlabel('X')
plt.ylabel('Absorption intensity')

在这里插入图片描述
在这里插入图片描述

三、总结

  • 从图中我们可以看出,在SO2高浓度的时候,预测的不是很准确,这大概率是因为非线性的影响。
  • 在气体浓度定量分析中,如何去除非线性的影响,是一直研究的课题。
  • 可以加入光谱预处理来提高模型的准确性
  • 例如可以对数据进行差分拟合、小波变换、傅里叶变换等来改进

作者简介

CSDN 人工智能领域新星创作者

百度飞桨开发者技术专家

腾讯云开发初级工程师认证

我在AI Studio上获得钻石等级,点亮9个徽章,来互关呀~

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

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

相关文章

Spring系列文章3:基于注解方式依赖注入

和XML 配置文件一样,注解本身并不能执行,注解本身仅仅只是做一个标记,具体的功能是框架检测 到注解标记的位置,然后针对这个位置按照注解标记的功能来执行具体操作,本质上所有操作都是Java代码来完成的,XML…

<九> objectARX开发:读写Excel、json与txt格式文件

一、功能描述 在实际应用中,有时候我们需要通过文本格式或者表格等格式来传递数据,例如*.txt、Excel表格或者*.json文件。此时我们就需要想办法来读写这些数据。本节我们来说一下如何读写读写Excel、json与txt格式文件。 二、不同文件格式读写 2.1 读写Excel excel文件的读…

SpringBoot项目防止接口重复提交(简单拦截器实现方案)

基于SpringBoot框架来开发业务后台项目时,接口重复提交是一个常见的问题。为了避免这个问题,我们可以通过自定义拦截器实现一个后台拦截接口重复提交的功能,本文将介绍如何使用基于SpringBoot实现这个功能。 首先,我们需要引入一…

macOS - 安装使用 SQLite

文章目录 关于 SQLite安装 使用 关于 SQLite 官网:https://sqlite.org/index.html 安装 https://formulae.brew.sh/formula/sqlite brew install sqlite包被安装在了:/usr/local/Cellar/sqlite/3.43.0_1 查看已安装版本信息 $ brew info sqlite >…

【Hive-小文件合并】Hive外部分区表利用Insert overwrite的暴力方式进行小文件合并

这里我们直接用实例来讲解,Hive外部分区表有单分区多分区的不同情况,这里我们针对不同情况进行不同的方式处理。 利用overwrite合并单独日期的小文件 1、单分区 # 开启此表达式:(sample_date)?. set hive.support.quoted.identifiersnon…

CSS 中的 display 和 visibility

CSS 中的 display 和 visibility 都可以设置一个元素在浏览器中的显示或隐藏效果。 display: 隐藏某个元素时,不会占用任何空间。换句话讲,不会影响布局。visibility: 隐藏某个元素时,仍需占用与未隐藏之前一样的空间。换句话讲,…

在VR全景中嵌入3D模型有哪些优势?

现阶段,很多商企都会引入VR全景展示来宣传推广自己的产品、服务以及环境,但是环境展示凸显的沉浸式体验只是 VR全景一部分的价值所在,商企使用VR全景还有一个优势就是互动性,通过丰富多样的互动性,让用户同VR场景中的物…

Ab3d.DXEngine 6.0 Crack 2023

Ab3d.DXEngine 不是另一个游戏引擎(如Unity),它强迫您使用其游戏编辑器、其架构,并且需要许多技巧和窍门才能在标准 .Net 应用程序中使用。Ab3d.DXEngine 是一个新的渲染引擎,它是从头开始构建的,旨在用于标…

汽车信息安全导图

尊敬的读者们,欢迎来到我的信息安全专栏。在这个专栏中,我将结合我在信息安全领域的开发经验,为大家深入浅出地讲解信息安全的重要性和相关知识点。 在数字化时代,信息成为了我们生活中不可或缺的一部分。我们的个人信息、交易数据、社交网络、公司机密等都以电子形式存储…

力扣(LeetCode)算法_C++——两个列表的最小索引总和

假设 Andy 和 Doris 想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。 你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。 如果答案不止一个,则输出所有答案并且不考虑顺序。 你可以假设答案…

vue和h5如何设置网页端和窗口大小同步缩放

在HTML文件中加入以下代码 <body style"transform-origin: top left; -moz-transform-origin: top left; font-family: Microsoft YaHei; width: 100%; height: 100%; margin: 0px; overflow: hidden; background-color: rgb(0,42,77);" οnresize"resize();…

Docker技术入门 | Part01:Docker简介

文章目录 1 虚拟化技术2 Docker概述2.1 Docker能解决的问题2.2 Docker介绍2.3 为什么使用Docker2.4 Docker特点2.5 Docker应用场景 3 Docker与虚拟机对比3.1 Docker和虚拟机组成结构3.2 Docker和虚拟机的不同点 4 Docker基本概念4.1 Docker引擎4.2 Docker基本架构4.3 Docker容器…

使用llvm 编译最新的linux 内核(LoongArch)

1. 准备交叉工具链 llvm 使用了最新的llvm-17, 编译方法见:编译LoongArch的llvm交叉工具链 gcc 从linux 官方下载&#xff1a;http://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.2.0/x86_64-gcc-13.2.0-nolibc-loongarch64-linux.tar.xz 发布llvm和g…

css中flex和flex-grow的区别

设置了1个class为parent且宽度为700px的div父级元素&#xff1b; 它有3个子元素&#xff0c;分别宽高为100px&#xff1b; 其中item2的元素flex值为1&#xff0c;item3的元素flex值为2 <!DOCTYPE html> <html lang"en"> <head><style>.pare…

glibc2.35-通过tls_dtor_list劫持exit执行流程

前言 glibc2.35删除了malloc_hook、free_hook以及realloc_hook&#xff0c;通过劫持这三个hook函数执行system已经不可行了。 传统堆漏洞利用是利用任意地址写改上上述几个hook从而执行system&#xff0c;在移除之后则需要找到同样只需要修改某个地址值并且能够造成程序流劫持…

【解决】多卡服务器GPU不能多用户同时使用的问题

一台多卡服务器&#xff0c;为提高利用效率&#xff0c;通常有多个用户使用。 假设有一台服务器A&#xff0c;分别有0&#xff0c;1&#xff0c;2&#xff0c;3四张卡&#xff0c;我们有两个用户&#xff1a;甲和乙。 当甲启动卡0时&#xff0c;乙想用卡1&#xff0c;2&#…

基于网络表示学习的 新闻推荐算法研究与系统实现

摘要 第1章绪论 新闻推荐通常是利用用户的阅读行为和习惯、阅读选择和爱好等信息,为 用户推荐新闻内容。新闻推荐能够减少用户在数量庞大数据信息中获取信息的 时间消耗,从而能够缓解“信息过载[7]”的难题。以文本为内容的新闻,和商品、 电影、短视频等推荐系统相比,新闻推…

Navicat使用HTTP通道服务器进行连接mysql数据库(超简单三分钟完成),centos安装nginx和php,docker安装nginx+php合并版

序言 因为数据库服务器在外网是不能直接连接访问的&#xff0c;但是可以访问网站&#xff0c;网站后台就能访问数据库&#xff0c;所以在此之前&#xff0c;访问数据库的数据是一件非常麻烦的事情&#xff0c;在平时和运维的交流中发现&#xff0c;他们会使用ssh通道进行连接访…

整车电子电器架构和自动驾驶架构的区别

整车电子电器架构和自动驾驶架构的区别&#xff1a; 范围不同&#xff1a; 整车电子电器架构是面向整车电子电器部件的通信、网络和诊断&#xff0c;包含车身、动力、底盘、娱乐和电器等系统&#xff1b;自动驾驶架构是面向智能网联的驾驶辅助功能或高度自动驾驶功能系统的功…

c语言练习41:深入理解字符串函数strlen strcpy strcat

深入理解字符串函数strlen strcpy strcat 模拟实现&#xff1a;”strlen strcpy strcat strlen strcat: #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<assert.h> strlen 1.通过指针移动模拟 //int my_strlen(char* str) { // size_t c…