当前位置: 首页 > news >正文

重生归来,我要成功 Python 高手--day35 深度学习 Pytorch

PyTorch:基于python语言的深度学习框架,将数据封装为张量

下载包:pip istall 报名 -i 镜像

特点

1.类似于numpyd 的张量计算

2.自动微分模块

3.深度学习库

4.动态学习库 

5.GPU加速

6.支持多种应用场景

7.支持跨平台

张量的创建:张量:元素为同一数据类型的多维矩阵

0维:标量   1维:向量/矢量   2维:矩阵  3维:矩阵数组(2维张量的堆叠)

3,h, w:         3:通道数      h:高度    w:宽度

【3,4,5】三个四行五列的数组的堆叠

API:

torch.tensor:根据指定形状创建张量

torch.Tensor:根据形状创建张量(未初始化),其也可以用来创建指定数据类型的张量

torch.IntTensor  torch.FloatTensor  torch.DounbleTensor   创建指定类型的张量

import torch
import numpy as np
# 数据类型创建张量【标量,list,numpy】
def f01():out=torch.tensor(5,)print(type(out))out2=torch.tensor([4,3,2])print(type(out2))out3=torch.tensor(np.array([1,2,3]))print(type(out3))
# 根据数据形状来创建没有初始化
def f02():# 通过指定维度大小创建张量out=torch.Tensor(2,3)print(out,out.shape,type(out),out.dtype)# 将numpy数组转化为张量out2 = torch.Tensor(np.array([5,6,7]))print(out2, out2.shape, type(out2), out2.dtype)# 创建指定类型的张量没有数值,所有只创建了形状
def f03():# 创建整型out=torch.IntTensor(2,3)print(out,out.shape,type(out),out.dtype)# 创建单精度浮点型out2 = torch.FloatTensor(2,3)*0print(out2, out2.shape, type(out2), out2.dtype)# 创建双精度浮点型out3 = torch.DoubleTensor(2,3)print(out3, out3.shape, type(out3), out3.dtype)if __name__ == '__main__':# f01()# f02()f03()

torch 运行时数据类型要求一致

线性张量和随机张量:

API:

torch.arange(1,10,2)   起始元素,终止元素,步长 包左不包右

torch.linspace(1,20,5)   起始元素,终止元素,几个元素   都包

torch.rand(300,500)  创建均匀分布的浮点型张量

torch.randn(300,500) 创建正态分布的浮点型张量

torch.initial_seed()  查看随机种子

torch.manual_seed(18)  固定随机种子

import torch
import matplotlib.pyplot as plt# 线性张量,arange   linspace
def f01():out=torch.arange(1,10,2)print(out,type(out),out.dtype)out2=torch.linspace(1,20,5)print(out2,type(out2),out2.dtype)'''
随机张量
0-1之间的  rand
标准高斯正态分布 randn
randint 整型
initial_seed 返回随机数种子
manual_seed(v) 随机数种子的设置'''# rand
def f02():out=torch.rand(300,500)print(out,type(out),out.dtype)# 将高维降到低维out=out.flatten()plt.hist(out)plt.show()# randn
def f03():out=torch.randn(300,500)# print(out,type(out),out.dtype)# 将高维降到低维out=out.flatten()plt.hist(out)plt.show()# print(f'输出随机数种子{torch.initial_seed()}')
# 固定随机数种子
torch.manual_seed(18)
print(torch.initial_seed())
# randint 随机整型
def f04():out=torch.randint(0,100,(10,10))print(out,type(out),out.dtype)# 将高维降到低维out=out.flatten()# plt.hist(out)# plt.show()if __name__ == '__main__':# f01()# f02()# f03()f04()

创建全零或者全一的张量

torch.zeros(5,5)  创建五乘五的全零张量

torch.ones(5,5)   创建五乘五的全一张量

torch.full((5,5),100) 创建每个值为100的五乘五张量

torch.zeros_like 根据传入的张量形状创建全零张量

torch.ones_like 根据传入的张量形状创建全一张量

import torch# 全零张量
def f01():out=torch.zeros(5,5)print(out,out.shape,out.dtype)# 全1张量
def f02():out=torch.ones(5,5)print(out,out.shape,out.dtype)# 指定值张量
def f03():out=torch.full((5,5),100)print(out,out.shape,out.dtype)# like
def f04():# 形状tem=torch.rand(2,5)out=torch.zeros_like(tem)print(out,out.shape,out.dtype)print('-'*100)out2=torch.ones_like(tem)print(out2,out2.shape,out2.dtype)print('-' * 100)out3=torch.full_like(tem,50)print(out3,out3.shape,out3.dtype)if __name__ == '__main__':# f01()# f02()# f03()f04()

张量元素的转化:

data.type(torch.float64)

data.half()/double()/float()/short()/int()/long()

import torch
# data.type(torch.类型)  进行转化def f01():out=torch.rand(3,3)print(out,out.dtype)out2=out.type(torch.float64)print(out2,out2.dtype)out3=out2.type(torch.int64)print(out3,out3.dtype)def f02():out=torch.rand(3,3)print(out.dtype)print(out.half().dtype)print(out.double().dtype)print(out.float().dtype)print(out.short().dtype)print(out.int().dtype)print(out.long().dtype)if __name__ == '__main__':# f01()f02()

张量的类型转换

张量转化为numpy数组:

Tensor.numpy  浅拷贝

copy()深拷贝

# 张量转化为numpy数组
def f01():tem=torch.randint(0,10,(3,5))out2=tem.numpy().copy()tem[0,0]=99print(tem,type(tem))out=tem.numpy()print(out,type(out))print(out2,type(out2))

获取数字  item()

# 获取数值
def f03():tem=torch.randn(1)print(tem.item(),type(tem),type(tem.item()))

numpy数组转化为张量:

torch_form_numpy()浅拷贝  clone()深拷贝

torch.tensor(data)深拷贝

# 数组转化为张量
def f02():tem=np.array([1,4,7,10])print(tem,type(tem))out3=torch.from_numpy(tem).clone()print(out3,type(out3))tem[0]=5# 转化1out=torch.tensor(tem)print(out,type(out))# 转化2out2=torch.from_numpy(tem)print(out2,type(out2))

张量的基本运算:

加减乘除  形状相同

add,sub,mul,div,neg

add_,sub_,mul_,div_,neg_的会修改原数据

点乘:相同形状的张量对应位置进行乘法

矩阵的乘法  @  或者是  torch.matmul  第一个矩阵的列=第二个矩阵的行

import torch
# 基本运算 加减乘除,取反
def f01():out=torch.tensor(1.)out2=torch.tensor(2.)# 运算符print(out+out2)print(out-out2)print(out*out2)print(out/out2)# apiprint(out.add(out2))# 取反d=torch.rand(3,4)print(d)print(d.neg())# 点乘
def f02():a=torch.randint(0,5,(2,3))print(a)b=torch.randint(6,10,(2,3))print(b)print('----------------------')print(a*b)print(a.mul(b))# 叉乘
def f03():a = torch.randint(0, 5, (3, 2))print(a)b = torch.randint(6, 10, (2,3))print(b)# print(a@b)print(a.matmul(b))if __name__ == '__main__':# f01()# f02()f03()

常见的计算函数

import torchdef f01():# 创建张量# 随机种子torch.manual_seed(1)emp=torch.randint(1,10,(3,2),dtype=torch.float64)print(emp)# 均值,dim=1为行的均值print(f'行的均值为{emp.mean(dim=1)}')# dim=0为列的均值print(f'列的均值为{emp.mean(dim=0)}')# 求和print(f'行的求和为{emp.sum(dim=1)}')print(f'列的求和为{emp.sum(dim=0)}')# 极大值极小值print(f'行的极大值为{emp.max(dim=1)}')print(f'列的极大值为{emp.max(dim=0)}')# 极小值print(f'行的极小值为{emp.min(dim=1)}')print(f'列的极小值为{emp.min(dim=0)}')# 平方根print(f'emp的平方根是{emp.sqrt()}')# 幂运算print(f'emp的幂运算为{emp.pow(2)}')# 指数运算print(f'emp的指数运算为{emp.exp()}')# 对数运算print(f'对数运算log为{emp.log()}')print(f'对数运算log2为{emp.log2()}')print(f'对数运算log10为{emp.log10()}')if __name__ == '__main__':f01()

张量的索引和多维索引操作

import torchtorch.manual_seed(12)
emp=torch.randint(1,10,(4,5))
# 行列倒叙
print(emp)
# dims=0  为只反转行  1 只反转列  0,1都反转
print(torch.flip(emp,[0,1]))
#
# print(emp)
# print(f'行索引{emp[1]}')
# print(f'列索引{emp[:,0]}')
# # 列表索引返回(0,1)和(1,2)两个位置的元素
# print(f'(0,1)的元素{emp[0,1]}')
# print(f'(1,2)的元素{emp[1,2]}')
# # 返回两行两列的元素
# print(f'返回第0,1两行和1,2两列的元素为{emp[0:2,1:3]}')
# # 返回范围索引的内容
# print(f'前三行的前两列数据{emp[0:3,0:2]}')
# print(f'第二行到最后的前两列的数据{emp[1:,0:2]}')
# # 布尔索引
# print(f'第三列数值大于5的完整行数据{emp[emp[:,2]>5]}')
# print(f'第二行数值大于5的元素对应的完整列数据{emp[:,emp[1,:]>5]}')
# 多维索引,创建一个  n  h  w 的矩阵
out=torch.randint(0,10,(3,4,5))
print(out)
print(f'获取0轴上的第一个元素{out[0]}')
print(f'获取1轴上的第一个元素{out[:,0,:]}')
print(f'获取2轴上的第一个元素{out[:,:,0]}')

张量形状的改变: 都是浅拷贝

reshape: 保证张量数据不变的前提下改变数据的维度,将其转化为指定维度  -1:会自动计算剩下维度

squeeze:删除形状为1的维度

unsqueeze:在指定位置添加形状为的维度

transpose:只能交换两个维度的位置

permute:可以交换多个维度的位置

view:改变维度但是内存要连续

is_contiguous:判断内存是否连续 返回True/False

contiguous:强制内存连续

API:

import torch
# reshape:修改形状
a=torch.randn([2,3,4])
print(a.shape)
print(a.reshape(2,-1).shape)
print()#squeeze删除维度为一的内容
a=torch.randn([1,2,3,4,1,1,2,3])
print(a.shape)
print(a.squeeze().shape)
print()# unsqueeze 扩维,在对应位置上添加形状为1的维度
b=torch.randn([2,3,4])
out=b.unsqueeze(0)
print(out.shape)
out2=b.unsqueeze(1)
print(out2.shape)
print()# transpose 维度交换,只能交换两个维度
a=torch.randn([2,3,4])
print(a.shape)
print(a.transpose(0,1).shape)
print(a.transpose(0,2).shape)
print()#permute 可以交换多个张量,有几个轴填写几个数字
b=torch.randn([2,3,4,5])
print(b.shape)
print(b.permute(0,3,2,1).shape)
print(b.permute(3,1,2,0).shape)
print()# 使用view进行改变维度
a=torch.randn([2,3,4])
print(a.shape)
print(a.view(2,-1).shape)
a=a.transpose(0,1)
print(a.is_contiguous())
a=a.contiguous()
print(a.is_contiguous())
print(a.view(3,-1).shape)

张量的拼接操作

torch.cat() :将多个张量根据指定的维度进行拼接,不改变维度数(维度的总个数不变)除拼接以外的维度要相同

torch.stack():会在一个新的维度上连接一系列张量,这会增加一个新维度,并且所有输入的张量必须完全相同   新增加维度的大小为堆叠张量的数量  形状必须相同

import torch# 张量的拼接,除了拼接的维度可以不同,其他的维度要相同
a=torch.randn(2,3,4)
b=torch.randn(2,3,5)
print(torch.cat([a,b],2).shape)
# print(torch.cat([a,b],1).shape) 报错因为剩下的维度的形状不同print()
# 张量的堆叠
a=torch.randn(5,4)
b=torch.randn(5,4)
c=torch.randn(5,4)
print(torch.stack([a,b],0).shape)
print(torch.stack([a,b],1).shape)
print(torch.stack([a,b],2).shape)
print(torch.stack([a,b,c],1).shape)

自动微分模块:

对损失函数求导,结合自动微分模块,更新权重参数w和b

backward方法  grad属性来完成梯度的计算和访问  使用的算法是反向传播

反向传递过程:基于预测值和真实的得出误差,得到损失函数,对损失函数求导得到梯度,通过梯度的更新来反向更新权重和偏置

单梯度下降:

requires_grad=True,启动了自动微分模块

import torch# 权重
w=torch.tensor([10,20],requires_grad=True,dtype=torch.float32)
# 梯度
loss=2*w**2# 自动微分
loss.sum().backward()
# 自动计算梯度
print(f'原梯度值为{w.data},学习率为{0.01},更新后的梯度为{w.grad},下一个权重为{w.data-0.01*w.grad}')

多梯度下降:

梯度会累加所以每次需要对梯度进行清零处理

import torch# 权重
w=torch.tensor([10],requires_grad=True,dtype=torch.float32)
# 多轮梯度
epochs=500
for epoch in range(epochs):# 损失函数loss = w**2+20# 梯度清零if w.grad is not None:w.grad.zero_()# 自动微分loss.sum().backward()# 自动计算梯度print(f'当前轮次为{epoch+1},当前权重为{w.data},学习率为{0.01},更新后的梯度为{w.grad},下一个权重为{w.data-0.01*w.grad}')# 更新梯度w.data=w.data-0.01*w.grad

梯度基本运算:

Pytorch不支持向量张量对向量张量的求导,只支持标量张量对标量张量的求导

所以如果w是张量y必须是标量才能进行求导   loss.sum().backward()  将向量转化为张量进行计算

import torch
# 记录初始的权重
# 参数 初始值    是否自动微分,这个参数为True的时候就可以求导   参数的类型
w=torch.tensor(10,requires_grad=True,dtype=torch.float)
# 定义损失函数变量
loss=2*w**2   # 求梯度(求导)  为  4w
# 查看梯度函数的类型,即曲线函数类型
# print(type(loss.grad_fn))
#
# 计算梯度=损失函数的导数,计算完毕之后,会记录到w.grad属性中
loss.backward()
# loss.sum().backward()   保证损失函数一定是一个标量,进行求导
#
# 就是求导得出来的梯度
print(w.grad)
# 带入权重更新公式: w新=w旧 - 学习率*梯度
w.data=w.data-0.01*w.grad
print(w.data)

梯度下降求最优解:

只有反向传播的时候才有梯度 先对梯度进行判断是否为空,为空进行梯度清零

import torch
# 计算梯度下降最优解就是损失函数最小,
# 定义初始权重w=10
# 参数   初始权重值     进行自动微分(求导)   数据类型
w = torch.tensor(10, requires_grad=True, dtype=torch.float32)
# 损失函数为loss=w**2+20
loss=w**2+20
# 定义学习率为0.01
# 输出初始值
print(f'初始权重为{w},(0.01*w.grad):无, loss:{loss}')
# 迭代1000次求最优解
for  i  in range(1,460):# 需要更新损失函数loss = w ** 2 + 20# 先判断梯度是否为Noneif w.grad is not None:# 不为空就需要进行梯度清空w.grad.zero_()# 进行自动微分和反向传播loss.sum().backward()# 更新权重w.data=w.data-0.01*w.grad# print(f'第{i}次,权重的初始值为{w.data} (0.01*w.grad):{0.01*w.grad}),loss:{loss}')print(f'第{i}次,权重的初始值为{w:.5f} (0.01*w.grad):{(0.01*w.grad):.5f}),loss:{loss:.5f}')# 最终结果
print(f'最终结果为:权重:{w:.5f},梯度:{w.grad:.5f},loss:{loss:.5f}')

梯度计算的注意点:不能将自动微分的张量转化为numpy数组会发生报错,使用detch()方法将张量进行拷贝

import torch
import numpy as np
# 创建张量
a=torch.tensor([[1,2,3],[4,5,6],[7,8,9]],requires_grad=True,dtype=torch.float32)
# b=a.numpy()
print(type(a))
# print(b,type(b))a1=a.detach()
print(type(a1))
print(a.requires_grad)
print(a1.requires_grad)
print(type(a1.numpy()))# 最终版   a1=a.detach().numpy()

自动微分模块的应用:

import torch# 特征矩阵
x=torch.ones(2,5)# 标签矩阵
y=torch.zeros(2,3)# 权重矩阵,需要进行自动微分
w=torch.randn(5,3,requires_grad=True)
# 偏置矩阵
b=torch.randn(3,requires_grad=True)# 求出预测值
z=x@w+b
# 创建损失函数对象
loss_fn=torch.nn.MSELoss()
# 使用损失函数
loss=loss_fn(z,y)
print(f'loss:{loss}')
# 进行自动微分
loss.backward()
# 返回更新后的梯度
print(f'更新前的w:{w}')
print(f'更新前的b:{b}')
print(f'更新w的梯度:{w.grad}')
print(f'更新b的梯度:{b.grad}')

综合案例:

1.造数据  封装为张量  将张量转化为张量数据集  再转化为数据迭代器对象 分批获取数据

2,创建回归模型对象

3,创建损失函数

4,创建优化器对象

5,外层遍历轮次,内层遍历每一批次

优化器帮我们自动更新权重和梯度使用step()函数

API:

# 导包
import torch
from torch.utils.data import TensorDataset          # 构造数据集对象
from torch.utils.data import DataLoader             # 数据加载器from torch import nn                                # nn模块中有平方损失函数和假设函数
from torch import optim                             # optim模块中有优化器函数
from sklearn.datasets import make_regression        # 创建线性回归模型数据集
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']        # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False          # 用来正常显示负号# 创建线性回归数据集
def create_dataset():x,y,coef=make_regression(n_samples=100,  # 100个样本n_features=1,   # 1个特征noise=10,      # 噪声,噪声越大样本点越分散,越小越密集、coef=True,      # 返回权重bias=14.5,      # 偏置random_state=3 # 随机种子)# 对x,y进行数据类型的转化x=torch.tensor(x,dtype=torch.float32)y=torch.tensor(y,dtype=torch.float32)return x,y,coef# 定义函数,进行模型的训练
def train_model(x,y,coef):# 创建数据集对象dataset=TensorDataset(x,y)# 创建加载器对象# 参数: 数据集对象,每批次的样本数,是否打乱样本dataloader=DataLoader(dataset,batch_size=16,shuffle=True)# 创建线性模型# 参数:   输入的特征数   输出的标签数model=nn.Linear(1,1)# 创建损失函数对象criterion=nn.MSELoss()# 创建优化器对象# 参数  模型待调整的参数      学习率optimizer=optim.SGD(model.parameters(),lr=0.001)# 初始化 轮数   每轮的平均损失值 训练总损失值  训练的样本数epochs=1000loss_list=[]tolal_loss=0.0tolal_sample=0# 循环论数for epoch in range(epochs):# 计算每轮的每批的损失for x_train,y_train in dataloader:# 模型的预测y_pred=model(x_train)# 计算损失# 参数    预测值 真实值,# 因为训练的数据为100行1列所有生成的预测值也是100行一列所有要把真实值改变形状loss=criterion(y_pred,y_train.reshape(-1,1))# 计算总损失和样本的批次数# 每批次累加损失值tolal_loss+=loss.item()# 每使用一批进行加一tolal_sample+=1# 进行梯度清零,反向传播,梯度更新optimizer.zero_grad()loss.backward()optimizer.step()# 将每轮的平均损失加入到列表中loss_list.append(tolal_loss / tolal_sample)print(f'轮数{epoch+1},平均损失函数为{tolal_loss/tolal_sample}')print(f'{epochs}轮的平均损失函数为{loss_list}')print(f'权重:{model.weight} 偏置为{model.bias}')# 绘制损失曲线plt.plot(range(epochs),loss_list)plt.title('损失值曲线变化图')plt.grid()plt.show()# 绘制样本点的分布plt.scatter(x,y)# 9.2 绘制训练模型的预测值(分离梯度并转 numpy)y_pred = torch.tensor([(v * model.weight + model.bias).detach().numpy() for v in x])# 9.3 计算真实值(确保为数值类型)y_true = torch.tensor([(v * coef + 14.5).numpy() if isinstance(v, torch.Tensor) else (v * coef + 14.5) for v in x])# 9.4 绘图时,若 x 是张量也需转 numpyplt.plot(x.detach().numpy(), y_pred.numpy(), color='red', label='预测值')plt.plot(x.detach().numpy(), y_true.numpy(), color='green', label='真实值')plt.legend()plt.grid()plt.show()if __name__ == '__main__':x,y,coef=create_dataset()# print(f'x:{x},y:{y},coef:{coef}')# print(f'x的形状为:{x.shape},y:{y.shape},coef:{coef}')train_model(x,y,coef)

http://www.dtcms.com/a/606260.html

相关文章:

  • 马云有没有学过做网站百度收录时间
  • 企业网站的规划与建设ppt建设一个打鱼游戏网站
  • 在 Linux Ubuntu 24.04 安装 IntelliJ IDEA
  • 自适应网站建设方案建设网站 请示 报告
  • 有哪些做网站的品牌ios开发app
  • C语言编译器电脑版 | 提供高效编译体验,轻松学习与开发
  • 容器访问某个链接中断后面又正常,socket
  • 构建现代应用的9个Python GUI库
  • 做网站业务的怎么寻找客户做网站公司哪家强
  • 【第1章>第6节】基于FPGA的图像膨胀处理算法的Verilog实现
  • 网站开发对企业的关键化妆品首页设计
  • 基于图的可解释性推荐综述
  • Nginx搭建RTMP点播流媒体服务器步骤详解,Nginx+RTMP+OBS推流搭建流媒体服务器
  • 东莞建设网站官网住房和城乡网站平台系统设计公司
  • 具身智能-一文详解视觉-语言-动作(VLA)大模型(2)
  • 如何使用 Docker 打包一个简单的应用程序:简易指南
  • Hyper-V Windows 11 Pro x64 开局问题
  • 长沙外贸建站土地 水利 勘测设计 公司宣传册设计样本
  • Cursor区域限制解决方法, Cursor 提示:“Model not available“的原因
  • 自签名证书需要手动确认风险导致nginx转发无效问题
  • 重庆市建设工程安全网站广告营销公司
  • 编译型语言有哪些 | 深入了解编译型语言的工作原理和特点
  • 实践教程|如何创建一个WhatsApp AI Chatbot
  • 网站流量分成专题制作 wordpress
  • 深度学习中适合长期租用的高性价比便宜的GPU云服务器有哪些?
  • 【DaisyUI】如何覆盖 dropdown 下拉效果?
  • 个人网站可以挂广告吗网站开发项目合同书
  • 网站建设前提企业信息管理
  • 每日两题day42
  • 最优惠的手机网站建设wordpress页面访问量