20242120 实验四 Python综合实践实验报告

Python综合实践实验报告
课程:《Python程序设计》
班级: 2421
姓名: 庞耀
学号:20242120
实验教师:王志强
实验日期:2025年5月14日
必修/选修: 公选课

一、课程总结

Python应该是我最早接触的编程语言,高中时期就已经在学校机房打印过"hello world",然而当时并没有用心学习。本学期,有幸抢到了王老师的Python公选课,十分高兴,一方面是早就从学长口中了解到王老师是一个优秀,幽默的老师;另一方面,能够通过这门课拓宽自己的编程能力,学到更多东西。本学期的课程可以说是干货满满,从最基础的语法到较为高阶的数据库和爬虫,我渐渐领悟到Python作为一种面向对象的编程语言的真正魅力。再次感谢王老师!如果可以提出一些建议,我希望王老师放慢一些课程节奏。下面来说说最后一次综合实践的具体内容吧。当下人工智能崛起迅速,我是计算机科学与技术专业的学生,刚刚加入了网空系卓越班,学习智能工程方向,想借着这个契机,先简单地实现一个单层线性人工神经网络,完成天气预测的任务。

二、需求分析与实验思路

每日最高气温一般由三个因素决定:前一日的最高温,前一日的降水量,以及前一日的风速。因此,在已知今日三个天气数据的情况下,能够采取一些手段,预测第二天的最高气温。在这里,我采用人工神经网络中最简单的线性回归模型实现这个功能。本次实验的大致纲要如下:
1.配置虚拟环境
2.获取一个城市的历史天气情况,作为训练数据
3.构建模型并训练模型
4.利用训练好的模型实现最高气温预测
下面是对线性回归模型的简要介绍:
线性模型:单层神经网络

优化方法-梯度下降

三. 实验过程与实验结果

1.配置虚拟环境
目前主流的研究人工智能模型的工具有很多,我选择应用最为广泛的PyTorch完成本次实验。
(1)安装annaconda
访问 anaconda官网,注册账号后下载最新版本anaconda
(2)配置虚拟环境pytorch_env
打开Anaconda Prompt,输入以下命令
conda create -n pytorch_env python=3.12
(选择Python版本为3.12,创建虚拟环境名为pytorch_env)
创建成功后激活环境
conda activate pytorch_env
(3)安装PyTorch的CPU和GPU版本
CPU:
conda install pytorch torchvision torchaudio cpuonly -c pytorch
GPU:
conda install pytorch torchvision torchaudio pytorch-cuda=12.6 -c pytorch -c nvidia
由于本次训练量较小,因此后续代码放入CPU中计算
安装完成后通过下面代码检查是否成功:

import torch
print(torch.__version__)
print(torch.cuda.is_available())
print(torch.cuda.get_device_name(0))

检查结果如下:

(4)安装其他需要的python库
本实验中后续还涉及文件处理,绘制散点图,绘制GUI图形界面等内容,统一在终端中使用pip安装
(5)在Pycharm中配置conda解释器
设置中搜索Python解释器,点击"添加新的解释器",选择添加本地解释器,选择现有。找到conda路径,生成新的环境即可,配置过程如下:

环境配置成功!

2.获取历史天气情况作为训练数据
进入网址Seattle Weather Dataset,下载csv文件到Pycharm项目目录下(命名为synthetic_weather_data.csv)
后续通过pandas库处理csv文件

至此准备工作完成

3.构建模型并训练模型
(1)导入必要的库

import torch
import pandas as pd            #c处理csv文件
import matplotlib.pyplot as plt#数据可视化
from torch import nn           #借助已有模型
import tkinter as tk           #应用端可视化
from tkinter import messagebox

(2)准备数据,利用pd库读取已有的csv文件

data=pd.read_csv('synthetic_weather_data.csv')
features=data[['tmax','precipitation','wind']].values
labels=data['tmax_next_day'].values

将csv文件中所有数据读取到data中,.values()将数据转为numpy格式,便于后续处理,区分features(特征)和labels(标签)

X=torch.tensor(features,dtype=torch.float32)
y=torch.tensor(labels,dtype=torch.float32).view(-1,1)

将特征和标签转换为tensor张量,准备放入CPU中计算
转换完成后,X形状为(100,3);y形状为(100,1),为列向量

(3)打乱数据,划分训练数据与测试数据

indices=torch.randperm(len(X))
X=X[indices]
y=y[indices]
train_size=int(0.8*len(X))
X_train,X_test=X[:train_size],X[train_size:]
y_train,y_test=y[:train_size],y[train_size:]

这里创建了一个乱序一维张量indices(0--len(X)-1),打乱原本的X,y的顺序,但保证X,y对应关系不变;取总数据中80%作为训练数据,剩余20%作为训练完成后的测试数据

(4)数据归一化

mean = X_train.mean(dim=0)#均值
std = X_train.std(dim=0)#方差
X_train = (X_train - mean) / std
X_test = (X_test - mean) / std

作用是将数据转化为均值为0,标准差为1d的分布

(5)模型构建

class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.linear = nn.Linear(in_features=X_train.shape[1],out_features=1)
    #前向传播
    def forward(self,x):
        return self.linear(x)
#实例化模型
model=Net()
#采用均方损失
Loss=nn.MSELoss()
#采用sgd梯度下降优化参数,学习率定为0.01
trainer = torch.optim.SGD(model.parameters(),lr=0.01)

定义了一个Net类,作为实验模型框架,继承nn.Module的方法,便于后续简化操作。其中super(Net,self).__init__()为固定语法,作用为调用父类nn.Module的构造函数,确保模型正确初始化。
模型的核心是线性层self.linear,作用是线性回归,计算XW+b并返回

(6)训练模型

#训练次数500次
epochs=500
#记录损失
loss_history=[]

for epoch in range(epochs):
    outputs=model(X_train)
    loss=Loss(outputs,y_train)
    #清空过往梯度
    trainer.zero_grad()
    #反向传播
    loss.backward()
    #更新参数
    trainer.step()
    loss_history.append(loss.item())
    #每五十轮打印一次损失
    if (epoch+1)%50==0:
        print(f"epoch:{epoch+1},loss:{loss.item():.4f}")

清空过往梯度意义在于防止模型自动运作,参数更新时污染相应计算图
更新参数可替换为手写,代码如下:

with torch.no_grad():
  for param in net.parameters():
    param-=lr*param.grad

(7)绘制损失函数,验证模型并绘制预测结果与实际值对比图

plt.plot(loss_history)
#设置x,y轴标签
plt.xlabel('epoch')
plt.ylabel('loss')
plt.title('Train_loss')
plt.show()

model.eval()

with torch.no_grad():
    y_pred=model(X_test)


y_true_np=y_test.numpy()
y_pred_np=y_pred.numpy()
#创建散点图
plt.scatter(x=y_true_np,
            y=y_pred_np,
            alpha=0.5,
            )
plt.plot([min(y_true_np), max(y_true_np)],
         [min(y_true_np), max(y_true_np)],
         'r--', lw=2)#红色虚线,线宽为2
plt.xlabel('True Values')
plt.ylabel('Predictions') 
plt.title('Prediction vs True Value')
plt.show()

model.eval()目的在于切换为评估模式,不改变模型参数,将X_test放入模型中运算得到y_pred,即测试数据的预测值;使用plt库绘制图像

模型已经搭建完毕

(8)绘制用户使用的图形界面

def create_gui():
    window=tk.Tk()
    window.title("天气预测")
    window.geometry("300x200")
    window.iconbitmap("test.ico")
    window_labels=["今日最高气温(°C):","降水量(mm):","风速(km/h):"]
    entries=[]

创建主窗口windows,将窗口命名为“天气预测”,大小为300×200像素,图标换为自己喜欢的火影角色自来也;将窗口中所有将要用到的标签存入labels中。创建一个空列表用于存储后续用户输入的数据

    for i,text in enumerate(window_labels):
        tk.Label(window,text=text).grid(row=i,column=0,padx=5,pady=5)
        entry=tk.Entry(window)
        entry.grid(row=i,column=1,padx=5,pady=5)
        entries.append(entry)

    result_label=tk.Label(window,text="预测明日最高温:")
    result_label.grid(row=4,columnspan=2,pady=10)

将标签文本依次布局在窗口中,在其后依次增加输入框(entries)

 def predict():
        try:
            inputs=[e.get() for e in entries]
            new_data=[float(x) for x in inputs]
            if len(new_data)!=3:
                raise ValueError('需要三个数值')
            input_tensor=torch.tensor(new_data,dtype=torch.float32)
            norm_input_tensor=(input_tensor-mean)/std

            with torch.no_grad():
                prediction=model(norm_input_tensor)
            result_label.config(text=f"预测明日最高气温{prediction.item():.1f}°C")
        except ValueError as e:
            messagebox.showerror("输入错误",str(e))
            for item in entries:
                item.delete(0,tk.END)

读取输入框中输入的数据,将其转化为tensor格式,如果用户输入数据不完全,则报错,并清除输入框中所有数据,如果成功,调用模型,计算第二日最高气温并打印在界面中。

tk.Button(window,text="开始预测",command=predict).grid(row=3,columnspan=2)
    window.mainloop()

if __name__=="__main__":
    create_gui()

最后增加按钮,输入所有数据后按下即可执行代码开始预测,开启界面主循环

实验结果
1.终端

实现了预定的每训练50次打印依次损失值,最后损失值趋于稳定,达到了这个简单模型能够实现的最优解
2.损失函数图与预测结果,真实值对比图


可以看到预测结果散点基本位于标准线两侧,距离标准线较近,经判断可以初步达到预测目的。
3.用户使用界面

在此界面中依次输入相关数据,点击“开始预测”按钮即可开始预测第二日最高气温

四、实验问题及解决

1.下载完PyTorchGPU版本后无法正常使用
在配置虚拟环境时,我最初下载的是CUDA118版本,然而运行测试代码时发生报错。询问DeepSeek后得知,报错的原因是CUDA版本与PyTorch版本不匹配。查询NVIDIA官网查询后得知,需要下载CUDA126版本。通过清除环境,重新安装的操作后,配置成功
2.模型训练时终端中的损失值发生较大幅度波动
初次训练模型时,观察终端中打印的损失值发现,训练前期损失值快速下降,接近后期时发生波动,最终没有达到最小值。查询了李沐老师书籍《动手学深度学习》及观看相关视频后,认为应该是学习率过大导致的。多次重新训练模型,逐渐降低学习率,将其调整到合适值,最终损失值趋于稳定。

五、思考与感悟

本次结课实验是对这学期公选课内容的一个很好的结束,一方面,我在这次实验中复习了几乎所有Python的基础知识,从最简单的print,到类,方法的创建;从Python的下载,到机器学习环境的搭建和各种库的下载,导入,运用,我真正实现了“Python编程从入门到实践”,而非“Python编程从入门到放弃”。另一方面,当下人工智能正以一种革命般的状态席卷全球,改变着我们的生活,学习Python,研究人工智能的底层逻辑能让我更好的理解和运用人工智能。虽然受到时间限制,在本次实验中我仅仅实现了最为基础的单层线性人工神经网络,但日后我会继续学习深度学习,了解CNN,RNN等更深层次的内容,在大创项目中将人工智能与其他领域进行结合,学以致用,我相信这是最好的学习路径。最后,再次感谢王老师一学期的引导和栽培!!!

六 、参考资料

posted @ 2025-06-07 09:00  light-py  阅读(196)  评论(0)    收藏  举报