【Python代码】以线性模型为例,详解深度学习算法流程,包括数据生成、定义模型、损失函数、优化算法和训练

**使用带有噪声的线性模型构造数据集,并根据有限的数据恢复该线性模型的参数。**其中包括数据集构造、模型参数初始化、损失函数定义、定义优化算法和训练等过程。是大多数算法实现过程的一个缩影,理解此过程有助于在开发或改进算法时更深刻了解其算法的构造和框架。

  • 过程详解
    • 生成数据
    • 小批量划分数据集
    • 模型参数初始化
    • 模型定义
    • 损失函数定义
    • 定义优化算法
    • 模型训练
  • 运行示例
    • 整体代码
  • 示例中部分函数详解
    • torch.normal()
    • .backward()

过程详解

生成数据

此时以简单的线性模型为例,生成1000个2维的数据,作为样本集。每个样本都符合均值为0,标准差为1的正态分布。具体代码如下所示。

import torch

def synthetic_data(w,b,num_examples):
    """生成y=Wx+b+噪声"""
    ##X是一个1000行2列的数据,符合0,1的正态分布
    X=torch.normal(0,1,(num_examples,len(w)))#特征
    y=torch.matmul(X,w)+b
    y+=torch.normal(0,0.01,y.shape)#添加噪声
    return X,y.reshape((-1,1))
true_w=torch.tensor([2,-3.4])
true_b=4.2
features,labels=synthetic_data(true_w,true_b,1000)
print()
print('features',features[0],'\nlabels:',labels[0])
print('features.shape',features.shape,'\nlabels.shape:',labels.shape)

输出:

features tensor([0.1724, 0.8911]) 
labels: tensor([1.5308])
features.shape torch.Size([1000, 2]) 
labels.shape: torch.Size([1000, 1])

可以看出,已经生成了1000个2维的样本集X,大小为1000行2列。添加完噪声的标签labels,为1000行1列,即一个样本对应一个标签。
对生成数据的第一维和标签的结果可视化:

import matplotlib.pyplot as plt
plt.scatter(features[:,0].detach().numpy(),labels.detach().numpy(),1)
plt.savefig('x1000.jpg')
plt.show()

在这里插入图片描述

小批量划分数据集

把生成的数据打乱,并根据设置的批量大小,根据索引提取样本和标签。

def data_iter(batch_size,features,labels):
    num_examples=len(features)
    indices=list(range(num_examples))
    ##这些样本是随机读取的,没有特定顺序
    random.shuffle(indices)
    for i in range(0,num_examples,batch_size):
        batch_indices=torch.tensor(
        indices[i:min(i+batch_size,num_examples)]
        )#确定索引
        ##根据索引值提取相应的特征和标签
        yield features[batch_indices],labels[batch_indices]

选择其中的一个批量样本和标签可视化进行展示。

batch_size=10#批量设置为10
for X,y in data_iter(batch_size,features,labels):
    print(X,'\n',y)
    break##读取一次就退出,即选择其中的一个批量

输出:

tensor([[-0.6141, -0.9904],
        [ 2.2592, -1.2401],
        [ 0.3217, -2.0419],
        [ 2.6761,  1.6293],
        [-0.3886,  1.4958],
        [-1.4074,  0.2157],
        [-1.9986, -0.1091],
        [ 0.3808,  0.3756],
        [-0.6877,  0.3499],
        [ 1.5450, -1.0313]]) 
 tensor([[ 6.3528],
        [12.9585],
        [11.7972],
        [ 4.0089],
        [-1.6630],
        [ 0.6698],
        [ 0.5591],
        [ 3.6852],
        [ 1.6348],
        [10.7883]])

样本是10个1行2列的数据,标签是10个1行1列的数据。

模型参数初始化

这里设置权重w为符合均值为0,标准差为0.01的正态分布的随机生成数据,偏置b设置为0。也可以根据自己情况设置初始参数。

w=torch.normal(0,0.01,size=(2,1),requires_grad=True)
b=torch.zeros(1,requires_grad=True)

输出:

w: tensor([[-0.0164],
        [-0.0022]], requires_grad=True) 
b: tensor([0.], requires_grad=True)

初始参数设置之后,接下来就是更新这些参数,直到这些参数满足我们的数据拟合。
在更新时,需要计算损失函数关于参数的梯度,再根据梯度向减小损失的方向更新参数。

模型定义

定义一个模型,将输入和输出关联起来。前面生成的数据是线性的,所以定义的模型也是一个线性的 y=Wx+b

def linreg(X,w,b):
    """线性回归模型"""
    return torch.matmul(X,w)+b

损失函数定义

这里简单的定义一个损失函数,计算预测结果和真实结果的平均平方差。

def squared_loss(y_hat,y):
    """均方损失"""
    return (y_hat-y.reshape(y_hat.shape))**2/2

定义优化算法

使用小批量随机梯度下降算法作为优化算法。这里要确定超参数批量大小和学习率。

def sgd(params,lr,batch_size):
    """小批量随机梯度下降优化法"""
    with torch.no_grad():
        for param in params:
            param-=lr*param.grad/batch_size
            param.grad.zero_()

模型训练

有了数据、损失函数、初始参数和优化算法,我们就可以开始训练,更新参数。

lr=0.01
num_epochs=10
net=linreg
loss=squared_loss

for epoch in range(num_epochs):
    for X,y in data_iter(batch_size,features,labels):
        y_pred=net(X,w,b)
        l=loss(y_pred,y)
        l.sum().backward()
        sgd([w,b],lr,batch_size)
    with torch.no_grad():
        train_l=loss(net(features,w,b),labels)#使用更新后的参数计算损失

运行示例

整体代码


import torch
import random

##生成数据
def synthetic_data(w,b,num_examples):
    """生成y=Wx+b+噪声"""
    ##X是一个1000行2列的数据,符合0,1的正态分布
    X=torch.normal(0,1,(num_examples,len(w)))
    y=torch.matmul(X,w)+b
    y+=torch.normal(0,0.01,y.shape)
    return X,y.reshape((-1,1))
#真实的权重和偏置
true_w=torch.tensor([2,-3.4])
true_b=4.2
##调用生成数据函数,生成数据
features,labels=synthetic_data(true_w,true_b,1000)
# print('features',features[0],'\nlabels:',labels[0])
# print('features.shape',features.shape,'\nlabels.shape:',labels.shape)

# import matplotlib.pyplot as plt
# #set_figsize()
# plt.scatter(features[:,0].detach().numpy(),labels.detach().numpy(),1)
# plt.savefig('x1000.jpg')
# plt.show()

##读取数据,根据设置的批量大小
def data_iter(batch_size,features,labels):
    num_examples=len(features)
    indices=list(range(num_examples))
    ##这些样本是随机读取的,没有特定顺序
    random.shuffle(indices)
    for i in range(0,num_examples,batch_size):
        batch_indices=torch.tensor(
        indices[i:min(i+batch_size,num_examples)]
        )
        yield features[batch_indices],labels[batch_indices]
batch_size=10
# for X,y in data_iter(batch_size,features,labels):
#     print(X,'\n',y)
#     break

##初始化参数
w=torch.normal(0,0.01,size=(2,1),requires_grad=True)
b=torch.zeros(1,requires_grad=True)

##定义模型、损失函数和优化算法
def linreg(X,w,b):
    """线性回归模型"""
    return torch.matmul(X,w)+b
def squared_loss(y_hat,y):
    """均方损失"""
    return (y_hat-y.reshape(y_hat.shape))**2/2

def sgd(params,lr,batch_size):
    """小批量随机梯度下降优化法"""
    with torch.no_grad():
        for param in params:
            param-=lr*param.grad/batch_size
            param.grad.zero_()
#设置参数
lr=0.01
num_epochs=10
net=linreg
loss=squared_loss
##开始训练
for epoch in range(num_epochs):
    for X,y in data_iter(batch_size,features,labels):
        y_pred=net(X,w,b)
        l=loss(y_pred,y)
        l.sum().backward()
        sgd([w,b],lr,batch_size)
    with torch.no_grad():
        train_l=loss(net(features,w,b),labels)#使用更新后的参数计算损失
        print('w:',w,'\nb',b)
        print(f'epoch{epoch+1},loss{float(train_l.mean()):f}')

输出结果:

w: tensor([[ 1.1745],
        [-2.1489]], requires_grad=True) 
b tensor([2.6504], requires_grad=True)
epoch1,loss2.268522
w: tensor([[ 1.6670],
        [-2.9392]], requires_grad=True) 
b tensor([3.6257], requires_grad=True)
epoch2,loss0.318115
w: tensor([[ 1.8670],
        [-3.2300]], requires_grad=True) 
b tensor([3.9866], requires_grad=True)
epoch3,loss0.044844
w: tensor([[ 1.9472],
        [-3.3373]], requires_grad=True) 
b tensor([4.1204], requires_grad=True)
epoch4,loss0.006389
w: tensor([[ 1.9793],
        [-3.3768]], requires_grad=True) 
b tensor([4.1701], requires_grad=True)
epoch5,loss0.000951
w: tensor([[ 1.9920],
        [-3.3914]], requires_grad=True) 
b tensor([4.1888], requires_grad=True)
epoch6,loss0.000178
w: tensor([[ 1.9970],
        [-3.3968]], requires_grad=True) 
b tensor([4.1958], requires_grad=True)
epoch7,loss0.000069
w: tensor([[ 1.9991],
        [-3.3988]], requires_grad=True) 
b tensor([4.1984], requires_grad=True)
epoch8,loss0.000053
w: tensor([[ 1.9997],
        [-3.3995]], requires_grad=True) 
b tensor([4.1993], requires_grad=True)
epoch9,loss0.000051
w: tensor([[ 1.9999],
        [-3.3998]], requires_grad=True) 
b tensor([4.1997], requires_grad=True)
epoch10,loss0.000051

示例中部分函数详解

此部分,对代码中的部分函数进行解释和说明,以帮助大家理解和使用。

torch.normal()

torch.normal 是 PyTorch 中的一个函数,用于从正态分布(也称为高斯分布)中生成随机数。返回一个与输入张量形状相同的张量,其中的元素是从均值为 mean,标准差为 std 的正态分布中随机采样的

import torch

x = torch.normal(0, 1, (3, 3))
print(x)

输出:

tensor([[-1.5393,  0.2281,  1.2181],
        [ 0.7260, -1.4805,  0.5720],
        [ 0.0170, -0.9961, -0.2761]])

.backward()

在PyTorch中,a.backward() 是一个用于自动微分的方法。它通常用于计算一个张量(tensor)相对于其操作数(即输入和参数)的梯度。当你使用 PyTorch 的 autograd 模块时,可以通过调用 backward() 方法来自动计算梯度。

import torch

# 创建一个张量并设置requires_grad=True来跟踪其计算历史
a = torch.tensor([5.0], requires_grad=True)
print('a:',a)
# 定义一个简单的操作
b = a * 2

# 调用backward()来自动计算梯度
b.backward()

# 输出梯度
print(a.grad)  

输出:

a: tensor([5.], requires_grad=True)
tensor([2.])

其中,requires_grad属性是为了使PyTorch跟踪张量的计算历史并自动计算梯度。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Oracle】收集Oracle数据库内存相关的信息

文章目录 【Oracle】收集Oracle数据库内存相关的信息收集Oracle数据库内存命令例各命令的解释输出结果例参考 【声明】文章仅供学习交流,观点代表个人,与任何公司无关。 编辑|SQL和数据库技术(ID:SQLplusDB) 【Oracle】收集Oracle数据库内存相关的信息 …

受电端协议芯片是如何让Type-C接口设备实现快充?

随着科技的不断进步,USB Type-C接口在电子产品中越来越普及。而在这个接口中,Type-c受电端协议芯片起着至关重要的作用。那么,什么是Type-c受电端协议芯片?它又是如何工作的呢?本文将为您揭开Type-c受电端协议芯片的神…

pip安装之后还是无法使用问题处理

最近由于需要使用到Python 相关功能, 记录下一些入门小技巧 1 python 下载安装 在window10 环境下载免安装版本, 并解压 安装包下载地址: https://www.python.org/ftp/python/3.12.1/python-3.12.1-embed-amd64.zip 2. 安装pip, 由于是内嵌…

QQ数据包解密

Windows版qq数据包格式&#xff1a; android版qq数据包格式&#xff1a; 密钥&#xff1a;16个0 算法&#xff1a;tea_crypt算法 pc版qq 0825数据包解密源码&#xff1a; #include "qq.h" #include "qqcrypt.h" #include <WinSock2.h> #include…

【php】php去除excel导入时的空格

背景 PHPExcel_1.8.0导入excel&#xff0c;遇到trim无法处理的空格。 解决方案 $excelVal preg_replace(“/(\s| | |\xc2\xa0)/”, ‘’, $excelVal); 完整代码 thinkphp5代码 function readExcel($file) {require_once EXTEND_PATH . PHPExcel_1.8.0/Classes/PHPExcel.p…

汽车制动器行业调查:市场将继续呈现稳中向好发展态势

汽车制动器是汽车的制动装置&#xff0c;汽车所用的制动器几乎都是摩擦式的&#xff0c;可分为鼓式和盘式两大类。鼓式制动器摩擦副中的旋转元件为制动鼓&#xff0c;其工作表面为圆柱面;盘式制动器的旋转元件则为旋转的制动盘&#xff0c;以端面为工作表面。 目前市场上主流的…

WebSocket-黑马好客租房

文章目录 网站中的消息功能如何实现&#xff1f;什么是WebSocket&#xff1f;http与websocket的区别httpwebsocket 浏览器支持情况快速入门创建itcast-websocket工程websocket的相关注解说明实现websocket服务测试编写js客户端 SpringBoot整合WebSocket导入依赖编写WebSocketHa…

全网最高质量文章:重新学习Java中的HashMap!!

前言 本文参考了美团技术团队的科普文章Java 8系列之重新认识HashMap - 知乎 (zhihu.com) 这篇文章的质量极其高&#xff0c;高到很有可能是全网介绍HashMap这个知识点最优秀的文章&#xff0c;没有之一&#xff01;&#xff01;&#xff01;因此&#xff0c;我决定在我自己的…

智能安全帽定制_基于联发科MT6762平台的智能安全帽方案

智能安全帽是一种具备多项功能的高科技产品&#xff0c;其功能集成了视频通话监控、高清图像采集、无线数据传输、语音广播对讲、定位轨迹回放、静默报警、危险救援报警、脱帽报警、碰撞报警、近电报警以及智能调度系统等&#xff0c;同时还支持多功能模块的自由添加&#xff0…

设计模式-责任链

之前写代码的时候看到过有审批场景使用了责任链&#xff0c;当时大概看了一下代码实现&#xff0c;今天终于有时间抽出来梳理一下&#xff0c;下面是本文的大纲&#xff1a; 使用场景 审批场景的普遍应用 实际案例&#xff1a;HttpClient中的责任链模式 责任链模式在事件处理、…

RocketMQ学习总结

一、架构 1、NameServer&#xff1a;注册中心。Broker信息注册到NameServer&#xff1b;producer/consumer根据某个topic通过NameServer获取对应broker的路由信息 &#xff1b; 2、Broker&#xff1a;负责存储、拉取、转发消息&#xff1b; 3、Producer&#xff1a;消息生产者…

creature_summon_groups

字段介绍 这个表保存了关于临时召唤生物的数据 creature_summon_groups summonerId&#xff08;召唤者ID&#xff09; summonerType 0 时&#xff0c;此处为 creature 的 entrysummonerType 1 时&#xff0c;此处为 gameobject 的 entrysummonerType 2 时&#xff0c;此处…

从设备维修到机器视觉:我的职业发展之路

大家好&#xff01;我是学员向工&#xff0c;今天很高兴有机会与大家分享我的职业经历。十年前&#xff0c;18岁中专毕业的那年&#xff0c;我踏入社会&#xff0c;至今已经过去了十年。一开始&#xff0c;我主要从事设备的维修、装配、钳工和电工等多岗位工作。 然而&#xff…

大数据关联规则挖掘:Apriori算法的深度探讨

文章目录 大数据关联规则挖掘&#xff1a;Apriori算法的深度探讨一、简介什么是关联规则挖掘&#xff1f;什么是频繁项集&#xff1f;什么是支持度与置信度&#xff1f;Apriori算法的重要性应用场景 二、理论基础项和项集支持度&#xff08;Support&#xff09;置信度&#xff…

༺༽༾ཊ—Unity之-02-简单工厂模式—ཏ༿༼༻

首先我们打开一个项目 在这个初始界面我们需要做一些准备工作 建基础通用包 创建一个Plane 重置后 缩放100倍 加一个颜色 任务&#xff1a;使用【简单工厂模式】生成四种不同怪物 【按不同路径移动】 首先资源商店下载四个怪物模型 接下来我们选取四个怪物作为预制体并分别起名…

【Java并发】聊聊concurrentHashMap扩容核心流程

扩容 什么时候扩容 链表转红黑树。需要判断数组长度&#xff0c;触发扩容调用putAll() , 触发tryPresize() 方法数据量达到阈值 tryPresize-初始化数组 // 扩容前操作&#xff0c;putAll or 链表转红黑树 // size是原数组长度 * 2private final void tryPresize(int size) {…

如何在Servlet中获取请求参数的值

看看这个大佬做的动图吧&#xff01; 在Servlet中&#xff0c;你可以使用HttpServletRequest对象来获取请求参数的值。HttpServletRequest对象提供了一些方法&#xff0c;允许你访问从客户端发送的请求信息。以下是一些获取请求参数的常用方法&#xff1a; getParameter(String…

《SPSS统计学基础与实证研究应用精解》视频讲解:变量和样本观测值基本操作

《SPSS统计学基础与实证研究应用精解》4.1 视频讲解 视频为《SPSS统计学基础与实证研究应用精解》张甜 杨维忠著 清华大学出版社 一书的随书赠送视频讲解4.1节内容。本书已正式出版上市&#xff0c;当当、京东、淘宝等平台热销中&#xff0c;搜索书名即可。本书旨在手把手教会使…

k8s-ingress一

Comfigmap&#xff1a;存储数据 Date&#xff1a; Key&#xff1a;value 挂载的方式&#xff0c;把配置信息传给容器 生产当中的yml文件很长&#xff1a; 有deployment 容器的探针 资源限制 Configmap 存储卷 Service Ingress K8s的对外服务&#xff0c;ingress Se…

2023年总结我所经历的技术大变革

&#x1f4e2;欢迎点赞 &#xff1a;&#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff0c;赐人玫瑰&#xff0c;手留余香&#xff01;&#x1f4e2;本文作者&#xff1a;由webmote 原创&#x1f4e2;作者格言&#xff1a;新的征程&#xff0c;我们面对的不仅…
最新文章