深度学习_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 + b
    c = 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))#转成list
    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]#不断返回

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

代码的拆解分析:

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.grad
            param.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, y
      l = loss(net(x, w, b), y)#求损失,预测net,真实y
      l.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, y
      l = loss(net(x, w, b), y)#求损失,预测net,真实y
      l.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 torch

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 + b
    c = 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))#转成list
    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]#不断返回


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.grad
            param.grad.zero_()#用于清空张量param的梯度信息。



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, y

      l = loss(net(x, w, b), y)#求损失,预测net,真实y

      l.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_模型拟合_梯度下降原理

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

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

相关文章

SCSS动态生成类

前言 在项目开发中,为了方便样式的复用和规范化,通常都会统一一些公共的样式类,如果用传统的css来写就会显得很臃肿。 最近看了看接手的项目的公共css文件,发现很多重复的样式声明,还有全局的样式使用不统一问题。 例…

80.每日一练:移除元素(力扣)

问题描述 代码解决以及思想 解法一 class Solution { public:int removeElement(vector<int>& nums, int val) {int len 0; // 初始化一个用于记录非目标值个数的变量// 创建一个迭代器 it&#xff0c;指向 nums 的开头vector<int>::iterator it nums.beg…

Ubuntu22.04 交叉编译阿里oss c-sdk

一、交叉编译openssl Ubuntu20.04 交叉编译openssl 1.0.1f_编译前去除 makefile 中所有的"-m64"字段_qq76211822的博客-CSDN博客文章浏览阅读319次。Ubuntu20.04 交叉编译openssl_编译前去除 makefile 中所有的"-m64"字段https://blog.csdn.net/sz7621182…

【码银送书第九期】《ChatGPT 驱动软件开发:AI 在软件研发全流程中的革新与实践》

计算机技术的发展和互联网的普及&#xff0c;使信息处理和传输变得更加高效&#xff0c;极大地改变了金融、商业、教育、娱乐等领域的运作方式。数据分析、人工智能和云计算等新兴技术&#xff0c;也在不断地影响和改变着各个行业。 如今&#xff0c;我们正在见证人工智能技术的…

Hadoop3教程(三十四):(生产调优篇)MapReduce生产经验汇总

文章目录 &#xff08;164&#xff09;MR跑得慢的原因&#xff08;165&#xff09;MR常用调优参数Map阶段Reduce阶段 &#xff08;166&#xff09;MR数据倾斜问题参考文献 &#xff08;164&#xff09;MR跑得慢的原因 MR程序执行效率的瓶颈&#xff0c;或者说当你觉得你的MR程…

在 Mac M1 上运行 Llama 2 并进行训练

在 Mac M1 上运行 Llama 2 并进行训练 Llama 2 是由领先的人工智能研究公司 Meta &#xff08;前Facebook&#xff09;开发并发布的下一代大型语言模型 (LLM)。 它基于 2 万亿个公共数据 token 进行了预训练&#xff0c;旨在帮助开发人员和企业组织构建基于人工智能的生成工具和…

Spring Boot + EasyUI 创建第一个项目(一)

创建一个Spring Boot和EasyUI相结合的项目。 一、构建一个Spring Boot项目 Spring Boot之创建一个Spring Boot项目&#xff08;一&#xff09;-CSDN博客 二、配置Thymeleaf Spring Boot Thymeleaf&#xff08;十一&#xff09;_thymeleaf 设置字体_人……杰的博客-CSDN博客…

程序员们平时都喜欢逛什么论坛呢?

网站不在多&#xff0c;好用就行&#xff1b;技术不求精&#xff0c;好摸鱼就行。是时候祭出我收藏夹里的这15个网站了&#xff01; 求职必备&#xff1a;牛客网 https://www.nowcoder.com/ 年少不知牛客好&#xff0c;等到要面试的时候才发现是神器。 你可以在牛客上搜索到一…

NetCore IIS Redis JMeter 登录压力测试

近期&#xff0c;由于某项目验收需要&#xff0c;需要登录接口同时满足至少400个账号同时并发登录&#xff0c;于是开始编写测试代码&#xff0c;以满足项目业务需要。首先&#xff0c;安装jdk&#xff0c;由于本机已安装jdk8&#xff1a; 如果你机器上没有安装jdk&#xff0c;…

第6周 .NET

好嘛&#xff01;本来以为上周SQL Server环境配置等已经够恶心了&#xff0c;没想到这周又得去搞所谓的Microsoft Visual Studio 2005了。 首先非常离谱的是&#xff0c;这个Microsoft Visual Studio 2005如果就是指Visual Studio 2005&#xff0c;那么已经是8年前的老的不行的…

SpringCloud复习:(2)@LoadBalanced注解的工作原理

LoadBalanced注解标记了一个RestTemplate或WebClient bean使用LoadBalancerClient来进行负载均衡。 LoadBalancerAutoConfiguration类给带注解的RestTemplate添加了拦截器&#xff1a;LoadBalancerInterceptor. 具体流程如下&#xff1a; 首先定义一个LoadBalancerInterceptor…

大语言模型(LLM)综述(三):大语言模型预训练的进展

A Survey of Large Language Models 前言4. PRE-TRAINING4.1数据收集4.1.1 数据源4.1.2 数据预处理4.1.3 预训练数据对LLM的影响 4.2 模型架构4.2.1 典型架构4.2.2 详细配置4.2.3 预训练任务4.2.4 解码策略4.2.5 总结和讨论 4.3 模型训练4.3.1 优化设置4.3.2 可扩展的训练技术 …

SpringMVC Day 03 : 处理静态资源

前言 欢迎来到第三天的 SpringMVC 学习系列&#xff01;在前两天的教程中&#xff0c;我们已经学习了如何搭建 SpringMVC 环境、创建控制器和处理请求等基础知识。今天&#xff0c;我们将继续探索 SpringMVC 的功能&#xff0c;并学习如何处理静态资源。 在现代 Web 应用程序…

Apifox创建团队 项目 接口 邀请成员步骤演示

我们打开Apifox 找到 个人空间 然后 点击新建团队 然后这里 我们输入名字 点击确定 我们的团队就出来了 然后 我们点击新建项目 然后肯定是 http 项目名称输入一下 然后 语言 我们中国肯定是中文的 然后点击确定 建好之后 我们就会进入自己的项目啦 然后 我们可以新建个接…

【机器学习合集】人脸表情分类任务Pytorch实现TensorBoardX的使用 ->(个人学习记录笔记)

人脸表情分类任务 注意&#xff1a;整个项目来自阿里云天池&#xff0c;下面是开发人员的联系方式&#xff0c;本人仅作为学习记录&#xff01;&#xff01;&#xff01;该文章原因&#xff0c;学习该项目&#xff0c;完善注释内容&#xff0c;针对新版本的Pytorch进行部分代码…

R与Python结合,在安装tensorflow时遇到了报错--尚未解决

在服务器上安装tensorflow时&#xff0c;遇到了一个报错信息&#xff1a; 在网上找到一个类似的错误&#xff08;TensorFlow_error&#xff09;,见下图&#xff0c;但是博主没有给出解决办法。

解决javascript报错:SyntaxError: Invalid Unicode escape sequence

在处理cookie时报这个错&#xff1a; 网上搜了一圈都说是反斜杠问题&#xff0c;要把\替换成/ 但是试了网上的replace替换&#xff1a; replace(/\\/g, /) 结果没有用&#xff01;&#xff01;&#xff01; 然后我干脆直接做了一个最简单字符串赋值&#xff0c;再打印出来。…

macOS鼠标管理操作增强BetterMouse简体中文

BetterMouse是一款专为Mac用户设计的鼠标增强工具&#xff0c;旨在帮助用户更好地掌握和管理鼠标操作。它提供了全局鼠标手势、高度可定制的鼠标设置选项以及一些有用的鼠标增强功能&#xff0c;如鼠标放大镜、鼠标轨迹和应用程序切换功能。这些功能可以大大提高用户的工作效率…

单例模式及其使用场景

单例模式&#xff08;Singleton&#xff09;&#xff1a;指在一个系统中某个类只存在一个实例&#xff0c;类中自行实例化&#xff0c;实例向该系统提供统一的访问接口。 单例模式有两种表现形式&#xff0c;饿汉式&#xff1a;类加载时&#xff0c;就进行实例化&#xff1b;懒…

23款奔驰E300L升级几何多光束大灯 车辆自检等功能

奔驰几何多光束大灯核心特点就是通过内部的84颗可独立控制的LED光源&#xff0c;行车远光灯会甄别对向驶来的车辆或者行人&#xff0c;并且动态的跟随目标&#xff0c;之后阴影话该区域&#xff0c;避免晃到车辆和行人。 奔驰升级几何多光束 LED 大灯&#xff08;MULTIBEAM LED…