深度学习_6_实战_点集最优直线解_代码解析

问题描述: 在这里插入图片描述

上述题目的意思为,人工造出一些数据点,对我们的模型y = Xw + b + ∈进行训练,其中标准模型如下:

在这里插入图片描述
其中W和X都为张量,我们训练的模型越接近题目给出的标准模型越好


训练过程如下:

人造数据集:

说人话,自己利用代码随机创造一些有规律的点,组成点集类似这样:

在这里插入图片描述
上述点集就服从正态分布

正态分布(也被称为高斯分布)是统计学中最常见的概率分布之一。它具有以下特征:

1、均值(Mean):正态分布具有一个均值,通常表示为 μ(mu),它代表分布的中心或平均值。分布的对称轴就是均值。

2、方差(Variance):正态分布的方差,通常表示为 σ^2(sigma
squared),代表数据点分散或离散程度的度量。方差越大,数据点越分散。

3、随机性:正态分布中的随机变量的值可以取任何实数值,但大多数值集中在均值周围,远离均值的值出现的概率逐渐减小。正态分布的概率密度函数呈钟形曲线,这个曲线是对称的。

正态分布的概率密度函数通常由以下公式表示:
在这里插入图片描述
正态分布概率密度函数

4、 正态分布在自然界和科学研究中经常出现,许多现象,如身高、体重、温度测量误差等,都可以近似地用正态分布来描述。正态分布在统计学、机器学习和数据分析中广泛应用,因为它具有许多有用的性质,包括中心极限定理等。

正态分布的特征使得它在各种应用中非常有用,包括假设检验、参数估计、回归分析等。


生成y点实现函数:

下列函数用途是带入真实的w, b再根据随机的x真实的y
这一作用是为了构造人工点集,等会训练模型用

def synthetic_data(w, b, num_examples):"""生成 Y = XW + b + 噪声。"""X = torch.normal(0, 1, (num_examples, len(w)))# 均值为0,方差为1的随机数,n个样本,列数为w的长度y = torch.matmul(X, w) + b # y = x * w + bc = torch.normal(0, 0.01, y.shape)y += c # 加入随机噪音,均值为0.。形状与y的一样return X, y.reshape((-1, 1))# x, y做成列向量返回

最后返回的x, y就是点了

简单的张量运算:

根据矩阵乘法规则,要使这两个矩阵相乘,第一个矩阵的列数必须等于第二个矩阵的行数。

例如:

张量   [[1, 2], [3, 4]] 和张量  [1, 2]可以进行矩阵乘法:
前者一行两列,后者两行两列可乘:
[1*1 + 2*2, 3*1+ 4*2] = [5, 11]
反过来就不成乘了,两者shape分别是(1, 2), (2,)可兼容

张量和向量的区别:

朴素又简单的说,张量能表示任意维度,而向量是一维:
也就是说[1, 2]既可以表示为行向量也可以表示为一行两列的张量
[[1],[2]]这个也既可以表示为列向量或者两行一列的张量
再其他的都是张量了,张量的范围更广泛

代码的拆解分析:

X = torch.normal(0, 1, (num_examples, len(w)))# 均值为0,方差为1的随机

这个是为了更好的与w相乘,最后结果自然与上上述的例子一样,最后得到一个行向量

y.reshape((-1, 1))

作用:

y.reshape((-1, 1)) 是将张量 y 重新塑造(reshape)为一个列向量的操作。这里的 -1 是一个特殊的值,它表示自动计算该维度的大小以保持其他维度的元素数量不变。

假设原始的张量 y 是一个一维行向量,形状为 [n],其中 n 表示元素的数量。通过 y.reshape((-1, 1))
操作,你将其转换为一个列向量,形状为 [n, 1],其中 n 仍然表示元素的数量,但现在它们按列排列,而不是按行排列。

这种操作通常在深度学习和线性代数中用于将数据从一种形状转换为另一种形状,以适应模型的需求。列向量通常用于表示目标值或标签,而行向量通常用于表示特征。通过这种方式,你可以确保数据的形状与模型的期望输入/输出形状相匹配。


数据打乱批量返还函数:

def data_iter(batch_size, features, labels):num_examples = len(features)indices = list(range(num_examples))#转成listrandom.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]#不断返回

这个函数的作用主要就是将上述生成的一堆点,打乱,批量返还,方便下述数据处理,训练模型

代码的拆解分析:

num_examples = len(features)
indices = list(range(num_examples))#转成list

获取features长度,方便后续利用索引取值

batch_indices = torch.tensor(indices[i:min(i + batch_size, num_examples)])#取indices[i:min(i + batch_size, num_examples)//切片取值

切片取值:
例如:

original_list = [0, 1, 2, 3, 4]
sliced_list = original_list[1:3] # 得到 [1, 2]

yield features[batch_indices], labels[batch_indices]#不断返回,y整理形状的用途就体现出来了

索引取值:

若二维张量a = [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]
那么a[[0, 1]]:
a[[0, 1]] 表示对二维张量 a 进行行的索引操作,同时获取第 0 行和第 1 行的元素子集。它返回的是一个包含所选择的行的新的二维张量,其中包含了多个元素。
例如:
a = torch.tensor([[1, 2],
[3, 4],
[5, 6],
[7, 8],
[9, 10]])
那么:
a[[1, 3, 4]就是:
tensor([[3, 4],
[7, 8],
[9, 10]])

yield可以迭代返还,不像retrurn只返回一次,后续会在模型学习里继续补充


计算y值函数:

主要作用就是对我们的模型进行计算,我们的模型的有效值就是w,b它带入上述产生的x得到Y,这个Y是我们的模型计算出来的

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 / batch_size 

梯度下降篇章讲的很详细不再赘述


梯度下降函数:

def sgd(params, lr, batch_size):"""小批量随梯度下降"""with torch.no_grad():#节省内存和计算资源。for param in params:param -= lr * param.gradparam.grad.zero_()#用于清空张量param的梯度信息。

详情:深度学习_5_模型拟合_梯度下降原理
同上不再赘述


主函数:

true_w = torch.tensor([2, -3.4])
true_b = 4.2#真正的答案features, labels = synthetic_data(true_w, true_b, 100)#产生的数据集|点集batch_size = 10#每次取的数据量#模型
w = torch.normal(0, 0.01, size=(2, 1), requires_grad=True)
b = torch.zeros(1, requires_grad = True)lr = 0.03 #学习率
num_ecopchs = 30 #数据扫描三遍
net = linreg #指定模型
loss = squared_loss #损失for epoch in range(num_ecopchs):#扫描数据for x, y in data_iter(batch_size, features, labels): #拿出x, yl = loss(net(x, w, b), y)#求损失,预测net,真实yl.sum().backward()#算梯度sgd([w, b], lr, batch_size)#使用参数的梯度更新参数with torch.no_grad():train_l = loss(net(features, w, b), labels)#print(train_l)print(f'epoch {epoch + 1},loss {float(train_l.mean()):f}')#print(f'W {w}, B {b}')

拆解理解:

true_w = torch.tensor([2, -3.4])
true_b = 4.2#真正的答案features, labels = synthetic_data(true_w, true_b, 100)#产生的数据集|点集

上述代码为了产生数据用来训练模型

#模型
w = torch.normal(0, 0.01, size=(2, 1), requires_grad=True)
b = torch.zeros(1, requires_grad = True)#b是[0]

上述代码为我们的模型w是均值为0方差为0.001的随机数,

注意一下这里生成的模型w和上述true_w的维度可就不同了,这里w的shape是(2, 1)产生的张量案例为[[1], [2]]

与模型相乘的x还与上述一致(batch_size,2)

由于x的列数为2,w的行数为2相同,所以两者仍然可相乘!且最后生成(batch_size, 1)的二维张量

汗流浃背了吧?

上运行结果:

求真实y:在这里插入图片描述
上述三个张量分别为:x, true_w, true_y
求模型y:
在这里插入图片描述

上述三个张量分别为X, w, X*w

lr = 0.03 #学习率
num_ecopchs = 30 #数据扫描三遍
net = linreg #指定模型
loss = squared_loss #损失

下述循环执行三十次,也就是对整个数据循环学习三十次

for epoch in range(num_ecopchs):#扫描数据

因为学习率0.03大小适中,学习次数在[1, 30]随次数增加,模型w会越来越接近true_w,学习次数再多起来,可能就会产生无效学习浪费时间,当然学习率也要适中,详情可看上篇博客

net = linreg #指定模型
loss = squared_loss #损失

上述俩语句只是为了方便后续更改模型,所以直接调用模型名字

for x, y in data_iter(batch_size, features, labels): #拿出x, yl = loss(net(x, w, b), y)#求损失,预测net,真实yl.sum().backward()#算梯度sgd([w, b], lr, batch_size)#使用参数的梯度更新参数

此for循环配合data_iter函数内的yield语句可以把整个点集合分批次取出,实质是for循环调用了迭代器,此for循环是否结束和data_iter函数内的for循环相关

l.sum().backward()#算梯度

至于为什么要求和算梯度,这就是上篇博客梯度下降原理的作用了

requires_grad=True

上述代码标记了,某个变量在后续梯度计算中会用到,系统会跟踪,至于具体是用求偏导,还是别的算法,就不是我们该管的了,计算机帮你求

with torch.no_grad():train_l = loss(net(features, w, b), labels)#print(train_l)print(f'epoch {epoch + 1},loss {float(train_l.mean()):f}')#print(f'W {w}, B {b}')

==下列语句是,就是不让进行梯度跟踪 ==

 with torch.no_grad():

因为就是想打印一下模型训练结果

train_l = loss(net(features, w, b), labels)

上述代码,测试一下测试好的模型的损失值

print(f'epoch {epoch + 1},loss {float(train_l.mean()):f}')

打印格式,打印训练次数,与损失值

train_l.mean()

平均损失值

以上全部代码细节分析完毕

完整代码:

import random
import torchdef synthetic_data(w, b, num_examples):"""生成 Y = XW + b + 噪声。"""X = torch.normal(0, 1, (num_examples, len(w)))# 均值为0,方差为1的随机数,n个样本,列数为w的长度y = torch.matmul(X, w) + b # y = x * w + bc = torch.normal(0, 0.01, y.shape)y += c # 加入随机噪音,均值为0.。形状与y的一样return X, y.reshape((-1, 1))# x, y做成列向量返回
def data_iter(batch_size, features, labels):num_examples = len(features)indices = list(range(num_examples))#转成listrandom.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]#不断返回def linreg(x, w, b):return torch.matmul(x, w) + bdef squared_loss(y_hat, y):return (y_hat - y.reshape(y_hat.shape))**2 / 2 / batch_sizedef sgd(params, lr, batch_size):"""小批量随梯度下降"""with torch.no_grad():#节省内存和计算资源。for param in params:param -= lr * param.gradparam.grad.zero_()#用于清空张量param的梯度信息。true_w = torch.tensor([2, -3.4])
true_b = 4.2features, labels = synthetic_data(true_w, true_b, 100)batch_size = 10w = torch.normal(0, 0.01, size=(2, 1), requires_grad=True)
b = torch.zeros(1, requires_grad = True)lr = 0.03 #学习率
num_ecopchs = 30 #数据扫描三遍
net = linreg #指定模型
loss = squared_loss #损失for epoch in range(num_ecopchs):#扫描数据for x, y in data_iter(batch_size, features, labels): #拿出x, yl = loss(net(x, w, b), y)#求损失,预测net,真实yl.sum().backward()#算梯度sgd([w, b], lr, batch_size)#使用参数的梯度更新参数with torch.no_grad():train_l = loss(net(features, w, b), labels)print(f'epoch {epoch + 1},loss {float(train_l.mean()):f}')#print(f'W {w}, B {b}')

运行效果:

在这里插入图片描述
可以看出随着学习次数的增加,误差也在逐渐减小

如果还觉得抽象,可以是输出我们训练的模型w和b

效果:
在这里插入图片描述

可以看出随着训练的次数增加我们训练的模型w与b和标准答案也越加趋近

在这里插入图片描述

到此完结梯度下降原理博客如下:

深度学习_5_模型拟合_梯度下降原理

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

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

相关文章

用傲梅分区软件分割分区重启系统蓝屏BAD_SYSTEM_CONFIG_INFO,八个解决参考方案

环境: Win11 专业版 HP 笔记本 傲梅分区软件 闪迪16G U盘 Win10 官方镜像文件 Win11PE 系统安装U盘 USB固态硬盘盒 问题描述: 起因 开始使用windows自动磁盘管理工具压缩不了磁盘,提示无法将卷压缩到超出任何不可移动的文件所在点,关闭系统保护还原,删除系统创建…

VSCode C/C++ 分目录+多文件编译配置2

前言:介绍 task.json 和 launch.json 文件 task.json 和 launch.json 是用于配置 VS Code 编辑器中的任务 和 调试功能的两个重要文件。 task.json 文件用于配置任务,它定义了执行特定操作的任务,并提供了相应的命令和参数。以下是 task.js…

2、Linux权限理解

个人主页:Lei宝啊 愿所有美好如期而遇 目录 前言 Linux权限的概念 1.文件访问者的分(人) 2.文件类型和访问权限(事物属性) 3.文件权限值的表示方法 4.文件访问权限的相关设置方法 file指令 目录的权限 粘滞位 关于权限的总结 前言 在开始Linux权限理…

excel常用的几个函数

1、MID函数 通常用来返回返回指定字符串中的子串。 函数公式: MID(string, starting_at, extract_length) String(必填):包含要提取字符的文本字符串 starting_at(必填):文本中要提取的第一个字…

YOLO目标检测——行人数据集【含对应voc、coco和yolo三种格式标签+划分脚本】

实际项目应用:智能监控、人机交互、行为分析、安全防护数据集说明:行人检测数据集,真实场景的高质量图片数据,数据场景丰富标签说明:使用lableimg标注软件标注,标注框质量高,含voc(xml)、coco(j…

docker-compose安装ES7.14和Kibana7.14(有账号密码)

一、docker-compose安装ES7.14.0和kibana7.14.0 1、下载镜像 1.1、ES镜像 docker pull elasticsearch:7.14.0 1.2、kibana镜像 docker pull kibana:7.14.0 2、docker-compose安装ES和kibana 2.1、创建配置文件目录和文件 #创建目录 mkdir -p /home/es-kibana/config mkdir…

音视频技术开发周刊 | 316

每周一期,纵览音视频技术领域的干货。 新闻投稿:contributelivevideostack.com。 日程揭晓!速览深圳站大会专题议程详解 LiveVideoStackCon 2023 音视频技术大会深圳站,保持着往届强大的讲师阵容以及高水准的演讲质量。两天的参会…

【解锁未来】探索Web3的无限可能性-01

文章目录 前言什么是Web3? 前言 还记得你第一次听说比特币吗?也许那只是一个关于新技术将改变一切的微弱嗡嗡声。也许你会有一种 "FOMO "的感觉,因为那些早早入场的人突然积累了一大笔财富–尽管你并不清楚这些 "钱 "可…

flutter开发的一个小小小问题,内网依赖下不来

问题 由于众所周知的原因,flutter编译时,经常出现Could not get resource https://storage.googleapis.com/download.flutter.io…的问题,如下: * What went wrong: Could not determine the dependencies of task :app:lintVit…

ip报头和ip报文切片组装问题

在tcp层将数据打包封装向下传递后,网络层将其整个看为一个数据,然后对其数据加网络报头操作,在网络层最具有代表的协议就是ip协议。在这里我们探究ipv4的报头。 ip报头 4位版本:指定ip的版本号,对于ipv4来说就是4。 …

asp.net文档管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net文档管理系统是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言开发 asp.net文档管理系统 二、功能介绍 (1…

C++ list 的使用

目录 1. 构造函数 1.1 list () 1.2 list (size_t n, const T& val T()) 1.3 list (InputIterator first, InputIterator last) 2. bool empty() const 3. size_type size() const 4. T& front() 4. T& back() 5. void push_front (const T& val) 6.…

FL Studio 21 for Mac中文破解版百度网盘免费下载安装激活

FL Studio 21 for Mac中文破解版是Mac系统中的一款水果音乐编辑软件,提供多种插件,包括采样器、合成器和效果器,可编辑不同风格的音乐作品,Pattern/Song双模式,可兼容第三方插件和音效包,为您的创意插上翅膀…

java _JDBC 开发

目录 一.封装JDBCUtiles 二.事务 三.批处理 四.数据库连接池 C3P0 Druidf(德鲁伊)阿里 五.Apache-DBUtiles 六.Apache-DBUtils 七.DAO 和增删改查 通用方法 - BasicDao 一.封装JDBCUtiles 说明:在jdbc操作中,获取连接和释放资源&#…

设计模式:代理模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

上一篇《组合模式》 下一篇《命令模式》 简介: 代理模式,它是一种结构型设计模式,它通过引入一个代理对象来控制对原始对象的访问。代理模式的主要目的是在保持原始对象…

《动手学深度学习 Pytorch版》 10.4 Bahdanau注意力

10.4.1 模型 Bahdanau 等人提出了一个没有严格单向对齐限制的可微注意力模型。在预测词元时,如果不是所有输入词元都相关,模型将仅对齐(或参与)输入序列中与当前预测相关的部分。这是通过将上下文变量视为注意力集中的输出来实现…

【Elasticsearch】es脚本编程使用详解

目录 一、es脚本语言介绍 1.1 什么是es脚本 1.2 es脚本支持的语言 1.3 es脚本语言特点 1.4 es脚本使用场景 二、环境准备 2.1 docker搭建es过程 2.1.1 拉取es镜像 2.1.2 启动容器 2.1.3 配置es参数 2.1.4 重启es容器并访问 2.2 docker搭建kibana过程 2.2.1 拉取ki…

LSKA(大可分离核注意力):重新思考CNN大核注意力设计

文章目录 摘要1、简介2、相关工作3、方法4、实验5、消融研究6、与最先进方法的比较7、ViTs和CNNs的鲁棒性评估基准比较8、结论 摘要 https://arxiv.org/pdf/2309.01439.pdf 大型可分离核注意力(LSKA)模块的视觉注意力网络(VAN)已…

Linux CentOS 8(firewalld的配置与管理)

Linux CentOS 8(firewalld的配置与管理) 目录 一、firewalld 简介二、firewalld 工作概念1、预定义区域(管理员可以自定义修改)2、预定义服务 三、firewalld 配置方法1、通过firewall-cmd配置2、通过firewall图形界面配置 四、配置…

利用Jpom在线构建Spring Boot项目

1 简介 前面介绍了运用Jpom构建部署Vue项目,最近研究了怎么部署Spring Boot项目,至此,一套简单的前后端项目就搞定了。 2 基本步骤 因为就是一个简单的自研测试项目,所以构建没有使用docker容器,直接用java -jar命令…