深度学习-2基础语法

本文详细介绍了PyTorch中的tensor与numpy的关系,包括创建tensor的方法、tensor属性查看、变形技巧(view和reshape)、索引与切片操作,以及tensor的连接、拆分、换位、置换和基本运算。重点讲解了如何进行tensor的微分计算,展示了在深度学习中如何利用PyTorch进行自动梯度计算。
摘要由CSDN通过智能技术生成

day2

2.1pytorch中的tensor与numpy

Tensor:

Tensor 中文为张量。张量的意思是一个多维数组,它是标量、向量、矩阵的高维扩展。(数组里面同一个数组类型)和numpy 是对应的PyTorch 的 Tensor 可以和 numpy的ndarray相互转换区别:唯一不同的是PyTorch可以在GPU上运行,而numpy的ndarray只能在CPU上运行

numpy:

在这里插入图片描述

python的一个数值计算扩展,可用来存储和处理大型矩阵

一个是numpy的数组,一个是tensor的张量

两者可以相互转化

2.2创建pytorch的tensor

代码书写:

print("#################第二种:未初始化创建##################")

e = torch.empty(1)
print(e)
f = torch.Tensor(2, 3)
print(f)

print("###############第三种:随机生成 创建 ##############")

g = torch.rand(3, 3)
print(g)
h = torch.randn(3, 3)
print(h)
i = torch.rand_like(g)
print(i)

print("##############第四种:序列生成 创建 ###############")

print(torch.arange(0, 10))
print(torch.arange(0, 10, 2))
print(torch.linspace(0, 10, steps=3))

print("###############第五种: 全零,全一, 单位矩阵 创建############ ")
print(torch.ones(3, 3))
print(torch.zeros(2, 3))
print(torch.eye(4, 4))
print(torch.eye(2))

结果:

在这里插入图片描述+

2.3,查看tensor属性

在这里插入图片描述

2.4,tensor变形

print("##########tensor变形##############")
# view和reshape的差别  查资料
a = torch.tensor([[1, 2, 3], [4, 5, 6]])    #定义numpy的二维数组
print("b的值:", a)
print("a的形状:", a.shape)
b = a.flatten()          # 拉平,就成1维tensor
print("b的值:", b)
print("b的形状:", b.shape)
c = b.reshape(2, 3)      # 采用reshape将输入张量形状变为(2,3)
print("c的值:", c)
print("c的形状:", c.shape)
d = b.view(1, 6)            # 采用view将输出张量形状变为(1,6)
print("d的值:", d)
print("d的形状:", d.shape)
e = torch.squeeze(d)
print("e的值:", e)
print("e的形状:", e.shape)
f = torch.unsqueeze(e,0)
print("f的值:", f)
print("f的形状:", f.shape)
f = torch.unsqueeze(e,1)
print("f的值:", f)
print("f的形状:", f.shape)

用的最多的还是view和respace

view和respace的区别:

reshape()函数返回一个新的张量,而view()函数返回一个与原始张量共享存储空间的张量。这意味着,当你使用reshape()函数改变张量形状时,会创建一个新的张量对象,而原始张量对象不会改变。而当你使用view()函数改变张量形状时,会返回一个新的张量对象,但是它与原始张量对象共享存储空间,因此对新张量的修改也会影响原始张量。

reshape()函数可以处理任意形状的张量,而view()函数只能处理连续的张量。如果你尝试使用view()函数处理非连续的张量,会引发RuntimeError异常。

reshape()函数可以自动推断某些维度的大小,而view()函数需要手动指定所有维度的大小。如果你使用reshape()函数时只指定了部分维度的大小,它会自动推断其他维度的大小。而如果你使用view()函数时没有指定所有维度的大小,会引发RuntimeError异常。

reshape()函数可以使用-1作为占位符来自动计算某个维度的大小,而view()函数不支持使用-1作为占位符。

reshape()和view()函数都是用于改变张量形状的函数,但是它们之间有一些区别。如果你需要处理非连续的张量或者需要自动推断某些维度的大小,应该使用reshape()函数。如果你需要处理连续的张量并且需要手动指定所有维度的大小,应该使用view()函数。

结果:

在这里插入图片描述

2.5tensor索引与切片

索引:

代码部分:
print("###########tebsor 索引和切片 ##############")
# tensor所有元素都有编号 正索引数是从左往右, 从0开始,负索引是从右往左,从-1开始

a = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]],dtype=torch.float)     #定义二维tensor
b = torch.tensor([[10, 10, 10], [10, 10, 10], [10, 10, 10]],dtype=torch.float)  #定义二维tensor
print("a的值:",a)
# 索引
print("a[1,2]的值:",a[1,2])
print("a[-1,-1]",a[-1,-1])
print("a的第一行,第1列和3的值",a[1,[0,2]])
print("a的大于4的索引:",a>4)         #bool索引
print("a大于4的值:", a[a>4])
print("大于5输出a的值,否则s输出b:\n",torch.where(a>5, a, b))

结果:

在这里插入图片描述

切片:

代码部分:
# 切片;提取tensor中某一范围的元素
print("a的第1列",a[:, 0])
print("a的第3列",a[:, 2])
print("a的第3列",a[:,-1])
print("a的1-2列",a[:, 0:2])


print("a的第一行",a[0, :])
print("a的第二行",a[1, :])
print("a的最后一行",a[-1, :])
print("a的间隔行值",a[::2,::2])

结果:

在这里插入图片描述

2.6.tensor连接和拆分

连接:

代码部分:
a = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]],dtype=torch.float)     #定义二维tensor
b = torch.tensor([[10, 10, 10], [10, 10, 10], [10, 10, 10]],dtype=torch.float)  #定义二维tensor
print(a)
print(b)
print("a,b按行拼接:\n",torch.cat((a,b),dim=0))        #在给定维度上对输出的张量进行连接操作
print("a,b按行拼接:\n",torch.cat((a,b),dim=0).shape)
print("a,b按列拼接:\n",torch.cat((a,b),dim=1))
print("a,b按列拼接:\n",torch.cat((a,b),dim=1).shape)

print("a,b按行拼接:\n",torch.stack((a,b),dim=0))     #沿着一个维度对输入张量序列进行连接 在新维度拼接张量 将原始数据维度扩展一维
print("a,b按行拼接:\n",torch.stack((a,b),dim=0).shape)
print("a,b按列拼接:\n",torch.stack((a,b),dim=1))
print("a,b按列拼接:\n",torch.stack((a,b),dim=1).shape)
结果:

**外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传*
*

拆分:

代码部分:
a = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]],dtype=torch.float)     #定义二维tensor
b = torch.tensor([[10, 10, 10], [10, 10, 10], [10, 10, 10]],dtype=torch.float)  #定义二维tensor
print(torch.split(a, 2,dim=0))  #按块大小拆分张量  除不尽的取余数 返回一个元组tutle
print(torch.split(a, 1,dim=0))
print(torch.split(a, 1,dim=1))

print(torch.chunk(a, 2,dim=0))  #按块数拆分数量
print(torch.chunk(a, 2,dim=1))

结果:

在这里插入图片描述

2.7tensor 换位或置换

代码:

a = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]],dtype=torch.float) 
print(a)
print(a.T)
print(torch.t(a))
print(torch.transpose(a , 1, 0))
print(a.permute(1,0))

c = torch.unsqueeze(a,0)
print(c)
print(c.shape)
print(c.permute(1, 0 ,2).shape)

运行结果:

在这里插入图片描述

2.8 tensor 运算

代码

a = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]],dtype=torch.float)     #定义二维tensor
b = torch.tensor([[10, 10, 10], [10, 10, 10], [10, 10, 10]],dtype=torch.float)  #定义二维tensor
print(a)
print(b)
print(a+100)        #点加
print(a+b)          #点加
print(a.add(b))     #点加

print(a*b)          #点乘
print(a @ b)        #矩阵相乘
print(a.matmul(b))  #矩阵相乘
print(torch.mm(a,b))#矩阵相乘

结果
在这里插入图片描述

2.9 tensor微分计算

代码:

print("#####################tensor 自动微分(自动求导)Autograd####################")
x=torch.tensor([1.0,2.0,3.0,4.0,5.0],requires_grad=True,dtype=torch.float32)
print(x.requires_grad)
print(x.grad)
print(x.grad_fn)

y=torch.sum(x ** 2)
print(y)
print(y.item())
print(y.grad_fn)
print(x.grad)

y.backward()
print('shape:{0}; {1}'.format(x.grad.size(),x.grad))
  1. 创建张量x并设置requires_grad=True:
x = torch.tensor([1.0, 2.0, 3.0, 4.0, 5.0], requires_grad=True, dtype=torch.float32)

这行代码创建了一个包含5个元素的张量x,数据类型为float32requires_grad=True表示我们需要跟踪这个张量的计算历史,以便后续可以计算梯度。
2. 打印x的属性:

print(x.requires_grad)  # 输出: True
print(x.grad)           # 输出: None
print(x.grad_fn)        # 输出: None
  • x.requires_grad:检查x是否需要计算梯度,输出为True
  • x.grad:查看x的梯度。因为此时还没有进行任何计算,所以梯度为None
  • x.grad_fn:查看x的梯度函数。x是一个直接创建的张量,并没有经过任何操作,所以没有梯度函数,输出为None
  1. 计算y并进行相关操作:
y = torch.sum(x ** 2)

这行代码计算了x中每个元素的平方和。**是幂运算符,torch.sum是求和函数。

print(y)             # 输出: tensor(55., grad_fn=<SumBackward0>)
print(y.item())      # 输出: 55.0
print(y.grad_fn)    # 输出: <SumBackward0 object at 0x...>
print(x.grad)        # 输出: None
  • y:输出的张量,包含一个元素(即x中所有元素的平方和),并且有grad_fn属性,说明这是一个通过操作得到的张量,可以计算梯度。
  • y.item():当张量y只包含一个元素时,可以使用item()方法将其转换为一个Python数值。
  • y.grad_fn:查看y的梯度函数。这里是一个求和操作的梯度函数。
  • x.grad:此时仍然为None,因为还没有计算梯度。
  1. 计算梯度:
y.backward()

这行代码告诉PyTorch我们要计算y关于x的梯度。因为y是一个标量(只包含一个元素),所以我们可以直接调用backward()方法。如果y是一个向量,我们需要传入一个与y形状相同的权重向量。
5. 打印梯度:

print('shape:{0}; {1}'.format(x.grad.size(), x.grad))
  • x.grad.size():查看x的梯度张量的形状。
  • x.grad:查看x的梯度。

输出结果应该是:

shape:torch.Size([5]); tensor([ 2.,  4.,  6.,  8., 10.])

这意味着x的每个元素对y的偏导数分别是2, 4, 6, 8, 10。这是因为yx的每个元素的平方和,所以y关于x的偏导数是2*x

总的来说,这段代码展示了如何使用PyTorch创建一个需要计算梯度的张量,进行简单的数学操作,并计算梯度。

结果:

在这里插入图片描述

Tensor微分计算是深度学习中的重要概念,它涉及到对多维数组(即tensors)进行自动微分。这通常在反向传播算法中使用,用于优化神经网络的权重。

在TensorFlow或PyTorch等深度学习框架中,可以使用自动微分工具来计算张量的梯度。这些框架会跟踪张量的操作历史,并使用链式法则来自动计算梯度。

PyTorch 示例:

import torch

# 创建一个张量,并设置requires_grad=True以跟踪其计算历史
x = torch.tensor([3.0], requires_grad=True)

# 定义一个函数y,它是x的函数
y = x * x * 2

# 计算y关于x的梯度
y.backward()

# 输出梯度,即dy/dx
print(x.grad)  # 输出tensor([12.])

在这个例子中,首先创建了一个一维张量x,并设置了requires_grad=True。然后,我们定义了一个函数y,它是x的平方的两倍。最后,我们调用y.backward()来计算y关于x的梯度,并将结果存储在x.grad中。

在深度学习的上下文中,对向量进行微分计算通常涉及到自动微分(Automatic Differentiation)。这种技术使得计算函数相对于其输入的梯度变得简单和高效。以下是一个简单的例子,展示了如何在PyTorch和TensorFlow中对向量进行微分计算。

PyTorch 示例

import torch

# 创建一个向量x,并设置requires_grad=True以跟踪其计算历史
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)

# 定义一个简单的函数y,它是向量x的函数
y = x * 2 + 3

# 将y中的所有元素相加,得到一个标量
y_sum = y.sum()
print(y_sum)#tensor(21., grad_fn=<SumBackward0>)
# 计算y_sum关于x的梯度
y_sum.backward()

# 输出梯度
print(x.grad)#tensor([2., 2., 2.])

在这个例子中,我们创建了一个包含三个元素的向量x,并设置requires_grad=True。然后,我们定义了一个简单的函数y,它只是x的每个元素乘以2然后加上3。接着,我们调用y.backward()来计算y关于x的梯度。最后,我们输出x.grad,它包含了y相对于x的每个元素的梯度。

  • 45
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值