pytorch 实现线性回归(Pytorch 03)

一 从零实现线性回归

1.1 生成训练数据

原始 计算公式, y = 2x_1 - 3.4x_2 + 4.2

我们先使用该公式生成一批数据,然后使用 结果数据去计算 计算 w1, w2 和 b。

%matplotlib inline
import random
import torch
from d2l import torch as d2ldef synthetic_data(w, b, num_examples): #@save"""生成y=Xw+b+噪声"""X = torch.normal(0, 1, (num_examples, len(w)))y = torch.matmul(X, w) + by += torch.normal(0, 0.01, y.shape)return X, y.reshape((-1, 1))
true_w = torch.tensor([2, -3.4])
true_b = 4.2
X, y = synthetic_data(true_w, true_b, 1000)print(f'X:{X[:2, :]}')  # 2 * 1.1020 - 3.4 * 1.0722 + 4.2 = 2.758  y1:2.76
print(f'y: {y[:2]}')
# X:tensor([[ 1.1020,  1.0722],
#         [ 1.0747, -1.3082]])
# y: tensor([[ 2.7678],
#         [10.7949]])

可以看到 结果值y 是 使用 数据 计算得到的。

1.2 数据拆分

将数据输入 数据生成器 中,将数据按批次进行拆分,不要一次全部输入模型中,每次输入10个数据,当我们运行迭代时,我们会连续地获得不同的小批量,直至遍历完整个数据集,在深度学习框架中实现的内置迭代器效率要高得多,它可以处理存储在文件中的 数据和数据流提供的数据。:

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 feature, label in data_iter(batch_size, X, y):print(feature, '\n', label)break

1.3 初始化模型参数

随机初始化 特征权重w1, w2, b, 随机给个初始值才可以让它不断去靠近我们的实际权重值,从均值为0、标准差为0.01的正态分布中采样随机数来初始化权重,并将 偏置初始化为0。:

w = torch.normal(0, 0.01, size=(2,1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)
w, b# (tensor([[-0.0119],
#          [ 0.0133]], requires_grad=True),
#  tensor([0.], requires_grad=True))

1.4 定义模型 

用于前向传播的 模型,通过该模型计算预测值,要计算线性模型的输 出,我们只需计算输入特征X和模型权重w的矩阵‐向量乘法后加上偏置b:

def linreg(X, w, b): #@save"""线性回归模型"""return torch.matmul(X, w) + b  # 用于计算两个张量(tensor)的矩阵乘法。

1.5 定义损失函数

本次使用 平方损失 作为损失函数:

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

1.6 定义优化算法

使用 随机梯度下降作为优化算法,在每一步中,使用从数据集中随机抽取的一个小批量,然后根据参数计算损失的梯度:

def sgd(params, lr, batch_size): #@save # param:w1, w2, b"""小批量随机梯度下降"""with torch.no_grad():for param in params:param -= lr * param.grad / batch_sizeparam.grad.zero_()

1.7 执行训练

查看执行训练的过程,学习率为每次 移动的步长,batch_size 为每次训练输出的数据量,num_epochs 为训练迭代过程:

1 计算每次的损失值。

2 反向传播计算梯度,就是计算权重实时的导数。

3 根据实时的梯度更新权重值。

lr = 0.01  # 学习率
batch_size = 100   # 每次训练数据输出数据量
num_epochs = 1000   # 训练次数for epoch in range(num_epochs):for feature, label in data_iter(batch_size, X, y):l = squared_loss(linreg(feature, w, b), label)   # 计算损失print(f'epoch:{epoch:3}, [w, b]: [{w[0].item():.5f},{w[1].item():.5f},{b.item():.5f}], loss:{l.mean():.5f}')l.sum().backward()   # 反向传播计算 w,b 的实时梯度sgd([w, b], lr, batch_size)   # 更新w,b

原始公式:

y = 2x_1 - 3.4x_2 + 4.2

可以看出 训练到后期,w1,w2,b的值和原始生成数据的公式基本吻合

二 简洁实现线性回归(调包)

数据集生成:

import numpy as np
import torch
from torch.utils import data
from d2l import torch as d2ltrue_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = d2l.synthetic_data(true_w, true_b, 1000)def load_array(data_arrays, batch_size, is_train=True): #@save"""构造一个PyTorch数据迭代器"""dataset = data.TensorDataset(*data_arrays)return data.DataLoader(dataset, batch_size, shuffle=is_train)batch_size = 10
data_iter = load_array((features, labels), batch_size)

 查看下数据,注意这里数据加载使用了 load_array

next(iter(data_iter))

a 定义模型

# nn是神经网络的缩写
from torch import nn
net = nn.Sequential(nn.Linear(2, 1))
net
# Sequential(
#   (0): Linear(in_features=2, out_features=1, bias=True)
# )

b 初始化权重

net[0].weight.data.normal_(0, 0.01)
net[0].bias.data.fill_(0)
# tensor([0.])

c 定义损失函数

loss = nn.MSELoss()

d 定义优化算法

trainer = torch.optim.SGD(net.parameters(), lr=0.03)
trainer

f 执行训练

num_epochs = 3
for epoch in range(num_epochs):for X, y in data_iter:l = loss(net(X) ,y)trainer.zero_grad()  # 用于将模型中所有参数的梯度清零。l.backward()trainer.step()l = loss(net(features), labels)print(f'epoch {epoch + 1}, loss {l:f}')

查看计算的最后结果:

w = net[0].weight.data
print(f'w: {w.reshape(true_w.shape)},w误差:', true_w-w.reshape(true_w.shape))
b = net[0].bias.data
print(f'b: {b.item():.5f}, b的误差:', true_b - b)# w: tensor([ 2.0003, -3.3999]),w误差: tensor([-3.0398e-04, -7.4625e-05])
# b: 4.19952, b的误差: tensor([0.0005])

原始公式:

y = 2x_1 - 3.4x_2 + 4.2


三 线性回归 其他相关知识

线性模型的四个模块:训练数据,线性模型,损失函数,优化算法

a. 数据集

使用房价预测数据集,我们希望根据房屋的面积和房龄等来估算房屋价格。

b. 线性模型

预测公式, 价格 = 权重1 * 面积 + 权重2 * 房龄 + 截距:

c. 损失函数

拟合最小二乘法,使用平方误差:

在训练模型时,我们希望寻找一组参数(w∗ , b∗),这组参数能 最小化在所有训练样本上的总损失 

线性回归的解可以用一个公式简单地表达出来,这类解叫作解析解(analytical solution)。

        w^* = (X^TX)^{-1}X^Ty

d. 优化算法

梯度下降最简单的用法是 计算损失函数(数据集中所有样本的损失均值)关于模型参数的导数(在这里也可 以称为梯度)。但实际中的执行可能会非常慢:因为在每一次更新参数之前,我们必须遍历整个数据集。因此, 我们通常会在 每次需要计算更新的时候随机抽取一小批样本,这种变体叫做小批量随机梯度下降(minibatch stochastic gradient descent)。

给定特征估计目标的过程通常称为预测(prediction)或推断(inference)

3.1 矢量化加速

定义计时器,用来 查看算法运行时间:

%matplotlib inline
import mathimport time
import numpy as np
import torch
from d2l import torch as d2l
class Timer: #@save"""记录多次运行时间"""def __init__(self):self.times = []self.start()def start(self):"""启动计时器"""self.tik = time.time()def stop(self):"""停止计时器并将时间记录在列表中"""self.times.append(time.time() - self.tik)return self.times[-1]def avg(self):"""返回平均时间"""return sum(self.times) / len(self.times)def sum(self):"""返回时间总和"""return sum(self.times)def cumsum(self):"""返回累计时间"""return np.array(self.times).cumsum().tolist()

查看 for 循环时长:

n = 100000
a = torch.ones([n])
b = torch.ones([n])c = torch.zeros(n)  # 初始化
timer = Timer()
for i in range(n):c[i] = a[i] + b[i]
print(f'{timer.stop():.5f} 秒')  # 0.51397 秒

查看 直接计算 时长:

timer.start()
d = a + b
print(f'{timer.stop():.5f} 秒')  # 0.00100 秒

使用向量计算,本次计算优化了 500倍。for 循环画了0.5 秒,而直接计算 只花了 0.001秒!!!

3.2 正态分布

查看 不同均值和方差的正态分布 情况:

def normal(x, mu, sigma):p = 1 / math.sqrt(2 * math.pi * sigma**2)return p * np.exp(-0.5 / sigma**2 * (x - mu)**2)
# 再次使用numpy进行可视化
x = np.arange(-8, 8, 0.01)
# 均值和标准差对
params = [(0, 1), (0, 2), (3, 1)]
d2l.plot(x, [normal(x, mu, sigma) for mu, sigma in params], xlabel='x',ylabel='p(x)', figsize=(6, 4),legend=[f'mean {mu}, std {sigma}' for mu, sigma in params])

尽管神经网络涵盖了更多更为丰富的模型,我们依然可以用描述神经网络的方式来描述线性模型,从而把 线性模型看作一个神经网络。其实深度神经网络就是成千上万个线性模型组成的一个整体,神经网络里面我们会把输入的每一个特征都去计算一个权重。

对于线性回归,每个输入都与每个输出相连,我们将这种变换称为 全连接层(fully‐connected layer)或称为稠密层(dense layer)。

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

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

相关文章

[蓝桥杯 2015 省 B] 生命之树

水一水的入门树形DP #include<iostream> #include<algorithm> #include<vector> using namespace std; using ll long long; #define int long long const int N 2e610; const int inf 0x3f3f3f3f; const int mod 1e97;int n; int w[N]; vector<vecto…

播下代码的种子,收获应用的果实

春分时节&#xff0c;大地回暖&#xff0c;万物复苏&#xff0c;生机勃勃。这是一个充满活力和希望的季节&#xff0c;也是启动新计划和项目的绝佳时机。在这个充满希望的季节里&#xff0c;Codigger作为一款强大的工具&#xff0c;正等待着为您的项目和计划提供坚实的支持。 C…

【Python循环6/6】循环的综合运用

目录 回顾 for循环遍历列表 for循环进行累加/累乘的计算 复杂的条件判断 嵌套 嵌套循环 练习 遍历整数列表 总结 回顾 在之前的博文中&#xff0c;我们学习了for计数循环&#xff1b;while条件循环&#xff1b;以及跳出循环的两种方法break&#xff0c;continu…

相机拍照与摄影学基础

1.相机拍照 相机可能形状和大小不同&#xff0c;但基本功能相同&#xff0c;包括快门速度、光圈和感光度&#xff0c;这些是摄影的通用概念。即使是一次性相机也是基于这三个理念工作的。不同类型相机在这三个概念上的唯一区别是你可以控制这些功能的程度。这三个参数被称为相…

爬虫Day3

用到的网页--豆瓣电影Top250 需要爬取信息&#xff1a; 数据保存在网页源代码中&#xff0c;是服务加载方式。先拿到网页源代码--request。再通过re提取想要的信息---re。 新知识&#xff1a;用csv存数据&#xff0c;可以用excel表格展示数据 import csv result obj.findite…

外包干了28天,技术退步明显......

说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入深圳某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&a…

[项目设计]基于websocket实现网络对战五子棋

项目介绍 该项目旨在实现一个网页端的在线五子棋&#xff0c;将实现登陆、好友、房间、对战、观战、聊天等功能 完成该项目需要了解C、数据库MySQL、基础前端HTML/CSS/JS/Ajax、网络协议WebSocket 项目源码&#xff1a;azhe1/online_gobang - 码云 - 开源中国 (gitee.com) …

【Spring Cloud Gateway】路由配置uri三种方式及区别

websocket配置方式 ws:// 或 wss:// 开头的 URI&#xff0c;表示配置的是支持 Websocket 协议的目标地址。 这种方式适用于需要与客户端建立长连接、实现双向通信的场景&#xff0c;比如实时消息推送、即时聊天等。 使用 Websocket 配置方式可以让 Spring Cloud Gateway 能够…

day14-SpringBoot 原理篇

一、配置优先级 SpringBoot 中支持三种格式的配置文件&#xff1a; 注意事项 虽然 springboot 支持多种格式配置文件&#xff0c;但是在项目开发时&#xff0c;推荐统一使用一种格式的配置 &#xff08;yml 是主流&#xff09;。 配置文件优先级排名&#xff08;从高到低&…

R语言实现多要素偏相关分析

偏相关分析是指当两个变量同时与第三个变量相关时&#xff0c;将第三个变量的影响剔除&#xff0c;只分析另外两个变量之间相关程度的过程&#xff0c;判定指标是相关系数的R值。 在GIS中&#xff0c;偏相关分析也十分常见&#xff0c;我们经常需要分析某一个指数与相关环境参…

clickhouse突然启动不起来问题排查

场景&#xff1a; 在实现postgreql数据迁移到clickhouse中&#xff0c;想使用MaterializedPostgreSQL的功能实现&#xff0c;但是中途clickhouse突然挂了&#xff0c;就再启动不了了。 现象&#xff1a; systemctl start clcikhouse-server启动报错 [rootlocalhost clickhous…

理清大数据技术与架构

大数据并不是一个系统软件&#xff0c;更不是一个单一的软件&#xff0c;它实际上是一种技术体系、一种数据处理方法&#xff0c;甚至可以说是一个服务平台。在这个技术体系中&#xff0c;涵盖了许多不同的部件&#xff0c;比如Hadoop服务平台。这一服务平台可以根据具体情况自…

HarmonyOS ArkTS 通用事件(二十三)

通用事件目录 点击事件事件ClickEvent对象说明EventTarget8对象说明示例 触摸事件事件TouchEvent对象说明TouchObject对象说明示例 挂载卸载事件事件示例 点击事件 组件被点击时触发的事件。 事件 ClickEvent对象说明 从API version 9开始&#xff0c;该接口支持在ArkTS卡片中…

02、JS实现:使用二分查找实现两数相除的算法(要求:不使⽤乘法、除法和 mod 运算符)

二分查找实现两数相除的算法 Ⅰ、两数相除&#xff1a;1、题目描述&#xff1a;2、解题思路&#xff1a;3、实现代码&#xff1a; Ⅱ、小结&#xff1a; Ⅰ、两数相除&#xff1a; 1、题目描述&#xff1a; 给定两个整数&#xff0c;被除数 dividend 和除数 divisor。将两数相…

Oracle 部署及基础使用

1. Oracle 简介 Oracle Database&#xff0c;又名 Oracle RDBMS&#xff0c;简称 Oracle Oracle系统&#xff0c;即是以Oracle关系数据库为数据存储和管理作为构架基础&#xff0c;构建出的数据库管理系统。是目前最流行的客户/服务器&#xff08;client/server&#xff09;或…

8种Kubernetes集群中Pod处于 Pending状态的故障排除方法

文章目录 一、Pod与容器二、Pod的阶段&#xff08;状态&#xff09;三、Pod 状态故障排除3.1 检查 Pod 事件3.2 检查资源可用性3.3 检查污点和容忍度3.4 检查节点亲和性设置3.5 检查持久卷声明3.6 检查配额和限制3.7 验证 Pod 和容器映像3.8 分析调度程序日志 四、用于排查 Pen…

html中如何让网页禁用右键禁止查看源代码

在网页中&#xff0c;辛辛苦苦写的文章&#xff0c;被别人复制粘贴给盗用去另很多站长感到非常无奈&#xff0c;通常大家复制都会使用选取右键复制&#xff0c;或CTRLC等方式&#xff0c;下面介绍几种禁止鼠标右键代码&#xff0c;可减少网页上文章被抄袭的几率&#xff0c;当然…

机器学习——终身学习

终身学习 AI不断学习新的任务&#xff0c;最终进化成天网控制人类终身学习&#xff08;LLL&#xff09;&#xff0c;持续学习&#xff0c;永不停止的学习&#xff0c;增量学习 用线上收集的资料不断的训练模型 问题就是对之前的任务进行遗忘&#xff0c;在之前的任务上表现不好…

用C语言打造自己的Unix风格ls命令

在Unix或类Unix操作系统中&#xff0c;ls是一个非常基础且实用的命令&#xff0c;它用于列出当前目录或指定目录下的文件和子目录。下面&#xff0c;我们将通过C语言编写一个简化的ls命令&#xff0c;展示如何利用dirent.h头文件提供的函数接口实现这一功能。 #include "…

发布镜像到阿里云仓库

发布上一篇Dockerfile实战-自定义的centos镜像。 1、登录阿里云 2、找到容器镜像服务 3、创建命令空间 4、创建镜像仓库 5、点击进入这个镜像仓库&#xff0c;可以看到所有的信息 6、根据操作指南测试推送发布 6.1登录阿里云 [rootzhoujunru home]# docker login --usernam…