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

news2025/4/19 10:56:14

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

  • 前言
  • 一、代码运行
    • 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.coloradmin.cn/o/981177.html

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

相关文章

CUDA小白 - NPP(4) 图像处理 Data Exchange and Initialization(2)

cuda小白 原始API链接 NPP GPU架构近些年也有不少的变化,具体的可以参考别的博主的介绍,都比较详细。还有一些cuda中的专有名词的含义,可以参考《详解CUDA的Context、Stream、Warp、SM、SP、Kernel、Block、Grid》 常见的NppStatus&#xf…

pytorch代码实现之空间通道重组卷积SCConv

空间通道重组卷积SCConv 空间通道重组卷积SCConv,全称Spatial and Channel Reconstruction Convolution,CPR2023年提出,可以即插即用,能够在减少参数的同时提升性能的模块。其核心思想是希望能够实现减少特征冗余从而提高算法的效…

C++信息学奥赛1190:上台阶

#include <iostream> using namespace std;long long arr[80]; // 用于存储斐波那契数列的数组int main() {int n;arr[1]1; // 初始化斐波那契数列的前三个元素arr[2]2;arr[3]4;for(int i4;i<71;i) { // 计算斐波那契数列的第4到第71个元素arr[i]arr[i-1]arr[i-2]…

为XDR扩展威胁检测响应提供响应解决方案

安全层面最本质的问题是检测与响应&#xff0c;而当前的检测与响应&#xff0c;还存在着一些痛点和难点亟需解决&#xff0c;响应运营层面仍存在着一些挑战。 各类安全防护设备每天会产生大量的安全告警&#xff0c;使得安全分析人员绝大部分时间和精力都“消耗”在告警信息中…

win11 使用 QEMU 配置龙芯 3A5000 虚拟环境

01 下载资源 本实验使用资源: 开源模拟器qemu 下载地址, qemu-w64-setup-20230822.exe loongarch 固件下载: QEMU_EFI_8.0.fd loongarch 基本镜像下载: archlinux-loong64.iso qemu安装在D:\install\qemu: D:\install\qemu>dir | findstr "qemu-system-loongarch"…

Qt 5.15集成Crypto++ 8.7.0(MSVC 2019)笔记

一、背景 笔者已介绍过在Qt 5.15.x中使用MinGW&#xff08;8.10版本&#xff09;编译并集成Crypto 8.7.0。 但是该编译出来的库&#xff08;.a和.dll&#xff09;不适用MSVC&#xff08;2019版本&#xff09;构建环境&#xff0c;需要重新编译&#xff08;.lib或和.dll&#xf…

LRTimelapse 6 for Mac(延时摄影视频制作软件)

LRTimelapse 是一款适用于macOS 系统的延时摄影视频制作软件&#xff0c;可以帮助用户创建高质量的延时摄影视频。该软件提供了直观的界面和丰富的功能&#xff0c;支持多种时间轴摄影工具和文件格式&#xff0c;并具有高度的可定制性和扩展性。 LRTimelapse 的主要特点如下&am…

Qt下SVG格式图片应用

SVG格式图片介绍 svg格式图片又称矢量图&#xff0c;该种格式的图片不同于png等格式的图片&#xff0c;采用的并不是位图的形式来组织图片&#xff0c;而是采用线条等组织图片&#xff0c;svg格式是图片的文件格式是xml&#xff0c;可以通过文件编译器打开查看svg格式内容。 …

halcon双目标定双相机标定

halcon双目标定 *取消更新 dev_update_off () *获取窗体句柄 dev_get_window (WindowHandle) *设置窗体字体样式 set_display_font (WindowHandle, 16, mono, true, false) *设置线条粗细 dev_set_line_width (3) *创建空对象 gen_empty_obj (ImageL) *读取指定文件内子集 li…

SpringMvc进阶

SpringMvc进阶 SpringMVC引言一、常用注解二、参数传递三、返回值 SpringMVC引言 在Web应用程序开发中&#xff0c;Spring MVC是一种常用的框架&#xff0c;它基于MVC&#xff08;Model-View-Controller&#xff09;模式&#xff0c;提供了一种结构化的方式来构建可维护和可扩…

python报错ModuleNotFoundError: No module named ‘XXX‘

记录一下改神经网络过程中遇到的小bug 在对网络结构进行更改时&#xff0c;不可避免要把别人的文件copy到自己的项目里。这时可能会遇到包导入的错误。正常情况下&#xff0c;导入的包应该大致包括三种方式&#xff1a; 1、导入外部包&#xff0c;如果这里错了就自己去pip ins…

Hadoop的第二个核心组件:MapReduce框架第四节

Hadoop的第二个核心组件&#xff1a;MapReduce框架 十、MapReduce的特殊应用场景1、使用MapReduce进行join操作2、使用MapReduce的计数器3、MapReduce做数据清洗 十一、MapReduce的工作流程&#xff1a;详细的工作流程第一步&#xff1a;提交MR作业资源第二步&#xff1a;运行M…

(二十三)大数据实战——Flume数据采集之采集数据聚合案例实战

前言 本节内容我们主要介绍一下Flume数据采集过程中&#xff0c;如何把多个数据采集点的数据聚合到一个地方供分析使用。我们使用hadoop101服务器采集nc数据&#xff0c;hadoop102采集文件数据&#xff0c;将hadoop101和hadoop102服务器采集的数据聚合到hadoop103服务器输出到…

【算法】选择排序

选择排序 选择排序代码实现代码优化 排序&#xff1a; 排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a; 假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&…

苍穹外卖 day12 Echats 营业台数据可视化整合

苍穹外卖-day12 课程内容 工作台Apache POI导出运营数据Excel报表 功能实现&#xff1a;工作台、数据导出 工作台效果图&#xff1a; 数据导出效果图&#xff1a; 在数据统计页面点击数据导出&#xff1a;生成Excel报表 1. 工作台 1.1 需求分析和设计 1.1.1 产品原型 工作台是系…

GuLi商城-前端基础Vue-整合ElementUI快速开发

npm安装 启动项目&#xff1a;npm run dev http://localhost:8082/#/hello

强大易用的开源 建站工具Halo

特点 可插拔架构 Halo 采用可插拔架构&#xff0c;功能模块之间耦合度低、灵活性提高。支持用户按需安装、卸载插件&#xff0c;操作便捷。同时提供插件开发接口以确保较高扩展性和可维护性。 ☑ 支持在运行时安装和卸载插件 ☑ 更加方便地集成三方平台 ☑ 统一的可配置设置表…

Python UI自动化 —— 关键字+excel表格数据驱动

步骤&#xff1a; 1. 对selenium进行二次封装&#xff0c;创建关键字的库 2. 准备一个表格文件来写入所有测试用例步骤 3. 对表格内容进行读取&#xff0c;使用映射关系来对用例进行调用执行 4. 执行用例 1. 对selenium进行二次封装&#xff0c;创建关键字的库 from time imp…

RabbitMQ原理和界面操作

参考 ## 原理 https://zhuanlan.zhihu.com/p/344298279### https://blog.csdn.net/qq_53263107/article/details/127844208 界面操作 界面术语 Channels 通道的属性&#xff1a; channel&#xff1a;名称。 Virtual host&#xff1a;所属的虚拟主机。 User name&#xff1a…

机器人任务挖掘与智能超级自动化技术解析

本文为上海财经大学教授、安徽财经大学学术副校长何贤杰出席“会计科技Acctech应对不确定性挑战”高峰论坛时的演讲内容整理。何贤杰详细介绍了机器人任务挖掘与智能超级自动化技术的发展背景、关键技术和应用场景。 从本质来说&#xff0c;会计是非常适合智能化、自动化的。会…