3-7 使用深度学习解决温度即示数问题

news2024/9/21 4:31:21

3-7 使用深度学习解决温度即示数问题

直接上代码

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import torch
torch.set_printoptions(edgeitems=2, linewidth=75)

设置Jupyter Notebook在单元格中内嵌显示图像,导入所需库并设置PyTorch的打印选项。

#%%
t_c = [0.5,  14.0, 15.0, 28.0, 11.0,  8.0,  3.0, -4.0,  6.0, 13.0, 21.0]
t_u = [35.7, 55.9, 58.2, 81.9, 56.3, 48.9, 33.9, 21.8, 48.4, 60.4, 68.4]
t_c = torch.tensor(t_c)
t_u = torch.tensor(t_u)

定义摄氏温度和未知温度的样本数据,并将它们转换为PyTorch张量。

#%%
def model(t_u, w, b):
    return w * t_u + b

定义线性模型:$ t_p = w \times t_u + b $。

#%%
def loss_fn(t_p, t_c):
    squared_diffs = (t_p - t_c) ** 2
    return squared_diffs.mean()

定义损失函数,使用均方误差(MSE)来计算预测值和真实值之间的差异。

#%%
def dloss_fn(t_p, t_c):
    dsq_diffs = 2 * (t_p - t_c) / t_p.size(0)
    return dsq_diffs

def dmodel_dw(t_u, w, b):
    return t_u

def dmodel_db(t_u, w, b):
    return 1.0

定义损失函数对预测值的梯度,以及模型对参数(w和b)的梯度。

#%%
def grad_fn(t_u, t_c, t_p, w, b):
    dloss_dtp = dloss_fn(t_p, t_c)
    dloss_dw = dloss_dtp * dmodel_dw(t_u, w, b)
    dloss_db = dloss_dtp * dmodel_db(t_u, w, b)
    return torch.stack([dloss_dw.sum(), dloss_db.sum()])

计算损失函数对参数w和b的梯度。

#%%
w = torch.zeros(())
b = torch.zeros(())

初始化参数w和b为0。

#%%
delta = 0.1
loss_rate_of_change_w = (loss_fn(model(t_u, w + delta, b), t_c) - loss_fn(model(t_u, w - delta, b), t_c)) / (2.0 * delta)
learning_rate = 1e-2
w = w - learning_rate * loss_rate_of_change_w

loss_rate_of_change_b = (loss_fn(model(t_u, w, b + delta), t_c) - loss_fn(model(t_u, w, b - delta), t_c)) / (2.0 * delta)
b  = b - learning_rate * loss_rate_of_change_b

计算参数w和b的梯度并进行一次梯度下降更新。

#%%
def training_loop(n_epochs, learning_rate, params, t_u, t_c):
    for epoch in range(1, n_epochs+1):
        w, b = params
        t_p = model(t_u, w, b)
        loss = loss_fn(t_p, t_c)
        grad = grad_fn(t_u, t_c, t_p, w, b)
        params = params - learning_rate * grad
        print("Epoch %d, Loss %f" % (epoch, float(loss)))
    return params

定义训练循环函数,通过多个训练周期更新参数。

#%%
training_loop(
    n_epochs = 100,
    learning_rate = 1e-5,
    params = torch.tensor([1.0, 0.0]),
    t_u = t_u,
    t_c = t_c)

调用训练循环函数,执行100个训练周期。

#%%
t_un = 0.1 * t_u
params = training_loop(
    n_epochs = 3000,
    learning_rate = 1e-2,
    params = torch.tensor([1.0, 0.0]),
    t_u = t_un,
    t_c = t_c
)

对输入数据进行缩放并再次训练模型,这次训练3000个周期。

#%%
t_p = model(t_un, *params)
fig = plt.figure(dpi=600)
plt.xlabel("Temperature Fahrenheit")
plt.ylabel("Temperature Celsius")
plt.plot(t_u.numpy(), t_p.detach().numpy())
plt.plot(t_u.numpy(), t_c.numpy(), 'o')
plt.savefig("temp_unknown_plot.png", format='png')

绘制模型预测值与真实值的对比图。

#%%
params = torch.tensor([1.0, 0.0], requires_grad=True)

初始化参数并设置requires_grad=True以允许梯度计算。

#%%
loss = loss_fn(model(t_u, *params), t_c)
loss.backward()
params.grad

计算损失并反向传播以获取梯度。

#%%
def training_loop(n_epochs, learning_rate, params, t_u, t_c): 
    for epoch in range(1, n_epochs + 1): 
        if params.grad is not None: 
            params.grad.zero_() 
        t_p = model(t_u, *params) 
        loss = loss_fn(t_p, t_c)
        loss.backward() 
        with torch.no_grad(): 
            params -= learning_rate * params.grad
        if epoch % 500 == 0: 
            print('Epoch %d, Loss %f' % (epoch, float(loss))) 
    return params

更新训练循环以在每个周期中清零梯度,并在没有梯度计算的上下文中更新参数。

#%%
params = training_loop(
    n_epochs = 3000,
    learning_rate = 1e-2,
    params = params,
    t_u = t_un,
    t_c = t_c
)

使用新的训练循环进行训练。

#%%
import torch.optim as optim
params = torch.tensor([1.0, 0.0], requires_grad=True)
learning_rate = 1e-5
optimizer = optim.SGD([params], lr=learning_rate)

t_p = model(t_u, *params)
loss = loss_fn(t_p, t_c)
loss.backward()

optimizer.step()
params

使用PyTorch的优化器(SGD)进行参数更新。

#%%
def training_loop(n_epochs, optimizer, params, t_u, t_c):
    for epoch in range(1, n_epochs + 1):
        t_p = model(t_u, *params)
        loss = loss_fn(t_p,t_c)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        if epoch % 500 == 0:
            print("Epoch %d, Loss %f" % (epoch, float(loss)))
    return params

更新训练循环以使用优化器进行参数更新。

#%%
params = torch.tensor([1.0, 0.0], requires_grad=True)
learning_rate = 1e-2
optimizer = optim.SGD([params], lr=learning_rate)

training_loop(
    n_epochs = 5000,
    optimizer = optimizer,
    params = params,
    t_u = t_un,
    t_c = t_c
)

调用更新后的训练循环。

#%%
t_c = torch.tensor(t_c).unsqueeze(1)
t_u = torch.tensor(t_u).unsqueeze(1)

调整数据的形状,使其成为二维张量。

#%%
t_u.shape

检查数据的形状。

#%%
n_samples = t_u.shape[0]
n_val = int(0.2 * n_samples)

shuffled_indices = torch.randperm(n_samples)

train_indices = shuffled_indices[:-n_val]
val_indices = shuffled_indices[-n_val:]

t_u_train = t_u[train_indices]
t_c_train = t_c[train_indices]

t_u_val = t_u[val_indices]
t_c_val = t_c[val_indices]

t_un_train = 0.1 * t_u_train
t_un_val = 0.1 * t_u_val

将数据划分为训练集和验证集,并对训练数据进行缩放。

#%%
import torch.nn as nn

linear_model = nn.Linear(1,1)
linear_model(t_un_val)

定义一个线性模型并进行前向传播。

#%%
x = torch.ones(10,1)
linear_model(x)

测试线性模型的前向传播。

#%%
optimizer = optim.SGD(linear_model.parameters(), lr=1e-2)
list(linear_model.parameters())

定义优化器并查看模型参数。

#%%
def train_loop(n_epochs, optimizer, model, loss_fn,

 t_u_train, t_u_val, t_c_train, t_c_val):
    for epoch in range(1, n_epochs + 1):
        t_p_train = model(t_u_train)
        loss_train = loss_fn(t_p_train, t_c_train)
        
        t_p_val = model(t_u_val)
        loss_val = loss_fn(t_p_val, t_c_val)
        
        optimizer.zero_grad()
        loss_train.backward()
        optimizer.step()
        
        if epoch == 1 or epoch % 1000 == 0:
            print(f"Epoch {epoch}, Training loss {loss_train.item():.4f},"
                f"Validation loss {loss_val.item():.4f}")

定义训练循环函数,包括训练和验证集的损失计算和模型更新。

#%%
def loss_fn(t_p, t_c):
    squared_diffs = (t_p - t_c)**2
    return squared_diffs.mean()

linear_model = nn.Linear(1,1)
optimizer = optim.SGD(linear_model.parameters(), lr=1e-2)

train_loop(
    n_epochs = 3000,
    optimizer = optimizer,
    model = linear_model,
    loss_fn = loss_fn,
    t_u_train = t_un_train,
    t_u_val = t_un_val,
    t_c_train = t_c_train,
    t_c_val = t_c_val)

定义损失函数并调用训练循环函数。

#%%
seq_model = nn.Sequential(
            nn.Linear(1,13),
            nn.Tanh(),
            nn.Linear(13,1))
seq_model

定义一个顺序模型,包含一个隐藏层和一个输出层。

#%%
from collections import OrderedDict

seq_model = nn.Sequential(OrderedDict([
    ('hidden_linear', nn.Linear(1, 8)),
    ('hidden_activation', nn.Tanh()),
    ('output_linear', nn.Linear(8,1))
]))

seq_model

使用OrderedDict重新定义顺序模型。

#%%
optimizer = optim.SGD(seq_model.parameters(), lr = 1e-4)
train_loop(
        n_epochs = 10000,
        optimizer = optimizer,
        model = seq_model,
        loss_fn = nn.MSELoss(),
        t_u_train = t_un_train,
        t_u_val = t_un_val,
        t_c_train = t_c_train,
        t_c_val = t_c_val
)

使用新的顺序模型 seq_model 和均方误差损失函数(MSELoss),初始化优化器并运行训练循环,训练 10000 个周期。

#%%
print("output", seq_model(t_un_val))
print("answer", t_c_val)
print("hidden", seq_model.hidden_linear.weight.grad)

打印顺序模型在验证集上的预测输出和真实值,查看隐藏层线性变换的权重梯度。

#%%
import matplotlib.pyplot as plt

t_range = torch.arange(20.,90.).unsqueeze(1)

fig = plt.figure(dpi=600)
plt.xlabel("Fahrenheit")
plt.ylabel("Celsius")
plt.plot(t_u.numpy(), t_c.numpy(), 'o')
plt.plot(t_range.numpy(), seq_model(0.1 * t_range).detach().numpy(), 'c-')
plt.plot(t_u.numpy(), seq_model(0.1 * t_u).detach().numpy(), 'kx')
plt.show()

绘制图形来显示模型预测值与真实值的对比。
在这里插入图片描述
在这里插入图片描述

图中有三个部分:

  1. 圆点表示原始数据点。
  2. 青蓝色的线表示顺序模型在指定范围内的预测。
  3. 叉号表示模型在训练数据上的预测。

这个代码通过训练简单的线性模型和顺序模型(包含隐藏层)来预测摄氏温度。并展示了如何使用PyTorch的自动微分功能和优化器来更新模型参数。

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

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

相关文章

实时温湿度监测系统:Micropython编码ESP32与DHT22模块的无线数据传输与PC端接收项目

实时温湿度监测系统 前言项目目的项目材料项目步骤模拟ESP32接线连接测试搭建PC端ESP32拷录环境对ESP32进行拷录PC端搭建桌面组件本地数据接收桌面小组件部分 实验总结 前言 人生苦短,我用Python。 由于我在日常工作中经常使用Python,因此在进行该项目…

物流工业三防平板实时跟踪货物位置和状态

在当今全球化和高度数字化的商业环境中,物流行业的高效运作对于企业的成功和经济的繁荣至关重要。货物的准确、实时跟踪不仅能提高物流效率,还能增强客户满意度,降低运营成本。物流工业三防平板的出现,为实现货物位置和状态的实时…

使用redis进行短信登录验证(验证码打印在控制台)

使用redis进行短信登录验证 一、流程1. 总体流程图2. 流程文字讲解:3.代码3.1 UserServiceImpl:(难点)3.2 拦截器LoginInterceptor:3.3 拦截器配置类: 4 功能实现,成功存入redis (黑…

2017年,我成为了技术博主

2017年9月,我已经大三了。 >>上一篇(爪哇,我初窥门径) 我大二学了很多java技术,看似我一会就把javaweb/ssh/ssm这些技术栈给学了。 这些技术确实不难,即便是我,我都能学会,…

深入理解 LXC (Linux Containers)

目录 引言LXC 的定义LXC 的架构LXC 的工作原理LXC 的应用场景LXC 在 CentOS 上的常见命令实验场景模拟总结 1. 引言 在现代 IT 基础设施中,容器技术已经成为一种重要的应用和部署方式。与虚拟机相比,容器具有更高的效率、更轻量的特性和更快的启动速度…

MySQL GROUP_CONCAT 函数详解与实战应用

提示:在需要将多个值组合成一个列表时,GROUP_CONCAT() 函数为 MySQL 提供了一种强大的方式来处理数据 文章目录 前言什么是 GROUP_CONCAT()基本语法 示例使用 GROUP_CONCAT()去除重复值排序结果 前言 提示:这里可以添加本文要记录的大概内容…

第一次作业--数据库-搭建MySQL环境

一、下载 二、进入安装向导 1.选择Custom ,然后点击next 2.选择安装地址 点击第一个MySQL Servers然后依次点击打开到MySQL Server 8.0.37-X64 点击向右的绿色箭头 点击MySQL Server 8.0.37-X64 然后看到下面的蓝色Advanced Options 更改安装路径 然后点击next …

刷题(day02)

1、leetcode136.删除链表的结点 给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。 返回删除后的链表的头节点。 示例 1: 输入: head [4,5,1,9], val 5 输出: [4,1,9] 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数…

说说iOS苹果的“开发者模式”什么时候需要打开 需不需要提前打开

在 iOS 开发过程中,开发者模式(Developer Mode)是一个非常重要的功能,它允许开发者在设备上运行和调试自己的应用程序。 经常有人私信或在群里问到,“我没有开发者模式,怎么办”,“开发者模式是…

优秀策划人必逛的地方,你不会还不知道吧?

道叔今天依然记得当初刚入行的时候,每天为完成策划任务,焦虑的整晚睡不着觉的痛苦。 但其实……很多时候,选择比努力更重要 优秀的策划和文案,也从来不是天生,你要走的路,前人都已经走过,你要做的仅仅是整…

windows JDK11 与JDK1.8自动切换,以及切换后失效的问题

1.windows安装不同环境的jdk 2.切换jdk 3.切换失败 原因:这是因为当我们安装并配置好JDK11之后它会自动生成一个环境变量(此变量我们看不到),此环境变量优先级较高,导致我们在切换回JDK8后系统会先读取到JDK11生成的…

Windows11配置WSL2支持代理上网

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、安装WSL2分发版二、配置步骤三、测试总结 前言 说起来本来这个功能我也不需要的,只是最近突然有个需求就顺便研究了下,WSL2默认的网…

【漏洞复现】29网课交单平台 SQL注入

声明:本文档或演示材料仅用于教育和教学目的。如果任何个人或组织利用本文档中的信息进行非法活动,将与本文档的作者或发布者无关。 一、漏洞描述 29网课交单平台是一个在线学习平台,用于帮助学生完成网络课程的学习任务。这个平台提供了包括…

泛微E9开发 控制Radio框字段打印是否仅显示选中项文字

控制Radio框字段打印是否仅显示选中项文字 1、需求说明2、实现方法3、扩展知识点控制Radio框字段打印是否仅显示选中项文字格式参数说明样例 1、需求说明 当我们对单选框进行打印时,往往会把所有的选项一起打印出来(如下图所示),现…

【Linux进阶】文件系统4——文件系统特性

1.磁盘组成与分区的复习 首先说明一下磁盘的物理组成,整块磁盘的组成主要有: 圆形的碟片(主要记录数据的部分);机械手臂,与在机械手臂上的磁头(可擦写碟片上的数据);主轴马达,可以…

Redis学习 - 基础篇

Redis学习 - 基础篇 一. 简介 Redis 是一个高性能的key-value数据库,常用的数据类型如下:string,list,set,zset,hash 二. 安装 Widows和Linux下如何安装Redis-CSDN博客 三. 常用命令 配置及数据库操作…

[ TOOLS ] JFLASH 使用说明

一、使用everything查找JFLASH everything是指这个软件,使用这个方便查找想要的文件 二、创建一个工程并配置 创建完后进行配置: Target devic: 板子的芯片型号,比如R7FA6M4Target interface: 一般是SWDSpeed: 一般是4000kHz, 不能下载则将Sp…

数学建模美赛入门

数学建模需要的学科知识 高等数学线性代数 有很多算法的掌握是需要高等数学和线代的相关知识 如:灰色预测模型需要微积分知识;神经网络需要用到导数知识;图论和层次分析法等都需要用到矩阵计算的相关知识等; 概率论与数理统计&am…

基于SpringBoot构造超简易QQ邮件服务发送 第二版

目录 追加 邮箱附件 添加依赖 编码 测试 第二版的更新点是追加了 邮箱附件功能 ( 后期追加定时任务 ) 基于SpringBoot构造超简易QQ邮件服务发送(分离-图解-新手) 第一版 追加 邮箱附件 添加依赖 <!-- 电子邮件 --><dependency><groupId>org.spri…

后端登录校验——Filter过滤器和Interceptor拦截器

一、Filter过滤器 前面我们学会了最先进的会话跟踪技术jwt令牌&#xff0c;那么我们要让用户使用某些功能时就要根据jwt令牌来验证用户身份&#xff0c;来决定他是否登陆了、让不让用户访问这个页面&#xff08;或功能&#xff09; 但是这样一来&#xff0c;没发一个请求&…