深度学习-Pytorch张量tensor详解(线性回归实战)

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站

在这里插入图片描述

张量(tensor)是Pytorch中最基本的操作对象,表示一个多维矩阵,类似numpy中的ndarrays,是可以在GPU上使用以加速运算。

创建


直接创建张量:

函数功能
ones(*sizes)全1Tensor
zeros(*sizes)全0Tensor
eye(*sizes)对⻆线为1,其他为0
arange(s,e,step)从s到e,步⻓为step
linspace(s,e,steps)从s到e,均分成steps份
rand/randn(*sizes)均匀/标准分布
normal(mean,std)正态分布
randperm(m)随机排列
import torch

x1 = torch.rand(2, 3)  # 2×3的随机矩阵
print(x1)

x2 = torch.ones(2, 3, 4)  # 2×3×4的全1矩阵
print(x2)

x3 = torch.arange(1, 10, 2)  # 1-10步长2
print(x3)

print(x1.numel())  # 查看元素数量
print(x2.shape[0])  # 查看第0个维度大小
print(x3.data)  # 查看数据

在这里插入图片描述

通过数据创建张量:torch.tensor()

import torch
import numpy as np

x1 = torch.tensor(666)  # 可以是一个数
print(x1)
print(x1.type())  # 查看数据类型

x2 = torch.tensor([1, 2, 3], dtype=torch.float)  # 创建时指定类型
print(x2)

a = np.random.rand(2, 2)
x3 = torch.from_numpy(a)  # 从numpy创建
print(x3)
print(x3.numpy())  # 转为numpy

在这里插入图片描述

运算


基本上各种运算都支持,用的时候查一下文档即可,不再赘述。

  • 基本运算: add、abs、sqrt、div、exp、fmod、pow、sum、means等
  • 三角函数:cos、sin、asin、atan2、cosh等
  • 布尔运算: gt、lt、ge、le、eq、ne、topk、sort、max、min等
  • 线性计算: trace、diag、mm、bmm、t、dot、cross、inverse、svd等

比如加法就有很多写法:

import torch

x = torch.zeros(2, 2)  #全0
y = torch.ones(2, 2)  #全1
print(x+3)  # 全部+3
print(x+y)  # x+y
print(x.add(y))  # x+y
x.add_(y)  # 改变原x
print(x)

在这里插入图片描述

其他一些运算举例:

import torch

x = torch.rand(2, 2)
print(x)
print("求和:", x.sum(), x.sum().item())  # item打印具体值
print("cos(x):", x.cos())
print("最大值:", x.t())
print("转置:", x.t())
print("逆矩阵:", x.inverse())

在这里插入图片描述

使用view()改变张量形状。

import torch

x = torch.randn(2, 3)  # 2×3
print(x)
print(x.view(3, 2))  # 改成3×2
print(x.view(-1, 1))  # 改成6×1(-1是自动的意思,1是大小)

在这里插入图片描述

上述运算中,如果矩阵大小不相同,则会触发广播机制,如:

import torch

x = torch.ones(1, 2)
y = torch.zeros(3, 1)
print(x+y)

在这里插入图片描述
由于x是1行2列,而y是3行1列,在运行加法计算时两者大小不一致。此时触发广播机制,将x的第1行广播(复制)到第2行和第3行,扩容成3行2列;同理,y的第1列广播到第2列,也扩容成3行2列。使得大小一致,得以相加,如答案所见。

插播反爬信息 )博主CSDN地址:https://wzlodq.blog.csdn.net/

微分


若将Torch.Tensor属性requires_ grad设置为True,则Pytorch将开始跟踪对此张量的所有操作。当完成计算后,可以调用backward()并自动计算所有梯度,该张量的梯度将累加到grad属性中。

其实tensor包含了三个属性:data(数据)、grad(梯度)、grad_fn(梯度函数,怎么计算得到的梯度)。

out是一个标量, o u t = d ( o u t ) d x out=\frac{d(out)}{dx} out=dxd(out),调用out.backward()便可直接计算,不用指定求导变量。

import torch

x = torch.tensor([1., 2.], requires_grad=True)
print(x.data)  # 数据
print(x.grad)  # 梯度(创建为None
print(x.grad_fn)  # 梯度函数(创建为None
y = x * x
print("y=x*x:", y)
z = y * 3
print("z=y+3:", z)
out = z.mean()  # 求均值
print(out)
out.backward()  # 反向传播
print(x.grad)  # x梯度

在这里插入图片描述

x [ 1 , 2 ] , x 0 = 1 , x 1 = 2 x[1,2],x_0=1,x_1=2 x[1,2]x0=1x1=2
y = x 2 = [ x 0 2 , x 1 2 ] = [ 1 , 4 ] , y 0 = 1 , y 1 = 4 y=x^2=[x_0^2,x_1^2]=[1,4],y_0=1,y_1=4 y=x2=[x02,x12]=[1,4]y0=1y1=4
z = 3 y = [ 3 y 0 , 3 y 1 ] = [ 3 , 12 ] , z 0 = 3 , z 1 = 12 z=3y=[3y_0,3y_1]=[3,12],z_0=3,z_1=12 z=3y=[3y0,3y1]=[3,12]z0=3z1=12
o u t = 3 x 0 2 + 3 x 1 2 2 = 3 + 12 2 = 7.5 out=\frac{3x_0^2+3x_1^2}{2}=\frac{3+12}{2}=7.5 out=23x02+3x12=23+12=7.5
∂ o u t ∂ x = [ ∂ o u t ∂ x 0 , ∂ o u t ∂ x 1 ] = [ 3 x 0 , 3 x 1 ] = [ 3 , 6 ] \frac{\partial out}{\partial x}=[\frac{\partial out}{\partial x_0},\frac{\partial out}{\partial x_1}]=[3x_0,3x_1]=[3,6] xout=[x0out,x1out]=[3x0,3x1]=[3,6]
手算验证与运行结果一致。

需要特别注意得是,grad是一直累加的,也就是说我们在多轮训练中,每轮调用反向传播后,应把梯度清零,不然影响下一轮求梯度。

x.grad.data.zero_()  # 清理梯度

如果要中断梯度追踪,使用with torch.no_grad():用于调试追踪等,后续需要继续追踪时加下划线设置true即可。

import torch

x = torch.tensor([1., 2.], requires_grad=True)
y1 = x * x
print("y1:", y1.requires_grad)
with torch.no_grad():
    y2 = y1 / 3
    print("y2:", y2.requires_grad)
y3 = y2.sqrt()
print("y3:", y3.requires_grad)
y3.requires_grad_(True)
print("y3:", y3.requires_grad)

在这里插入图片描述

实战


手动调参和调用模型求解线性回归模型。

import matplotlib.pyplot as plt
import numpy as np
import torch
from torch import nn

# 数据
X = np.linspace(0, 20, 30, dtype=np.float32)
Y = 3 * X + 10 + np.random.rand(30) * 8
Y = Y.astype(np.float32)
plt.scatter(X, Y)
X = torch.from_numpy(X.reshape(-1, 1))
Y = torch.from_numpy(Y.reshape(-1, 1))

# 1.手动调参
w = torch.randn(1, requires_grad=True)  # 权重w
b = torch.randn(1, requires_grad=True)  # 偏置b
learning_rate = 0.001  # 学习率
for epoch in range(1000):
    for x, y in zip(X, Y):
        y_pre = torch.matmul(x, w) + b
        loss = (y - y_pre).pow(2).mean()
        if not w.grad is None:
            w.grad.data.zero_()  # 梯度清零
        if not b.grad is None:
            b.grad.data.zero_()
        loss.backward()  # 反向传播求解梯度
        with torch.no_grad():  # 优化参数
            w.data -= w.grad.data * learning_rate
            b.data -= b.grad.data * learning_rate
print("手动调参:", w, b)
x = X.numpy()
w = w.detach().numpy()
b = b.detach().numpy()
plt.plot(x, w * x + b, color="red", label="手动调参", alpha=0.8)

# 1.调用调参
model = nn.Linear(1, 1)  # 调用线性模型
loss_fn = nn.MSELoss()  # 损失函数均方误差
opt = torch.optim.SGD(model.parameters(), lr=0.001)  # 随机梯度下降
for epoch in range(1000):
    for x, y in zip(X, Y):
        y_pred = model(x)  # 使用模型预测
        loss = loss_fn(y, y_pred)  # 计算损失
        opt.zero_grad()  # 梯度清零
        loss.backward()  # 反向传播求解梯度
        opt.step()  # 优化参数
print("调用模型:", model.weight, model.bias)
plt.plot(X.numpy(), model(X).data.numpy(), color="green", label="调用模型", alpha=0.8)
plt.legend()
plt.show()

在这里插入图片描述
在这里插入图片描述

使用机器学习-sklearn库求解,可查看另一篇博客回归-线性回归算法(房价预测项目)

原创不易,请勿转载本不富裕的访问量雪上加霜
博主首页:https://wzlodq.blog.csdn.net/
来都来了,不评论两句吗👀
如果文章对你有帮助,记得一键三连❤

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吾仄lo咚锵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值