深度学习入门 ---- 张量(Tensor)

张量

张量在深度学习领域的定义

张量(tensor)是多维数组,目的是把向量、矩阵推向更高的维度。
有n维度就叫做n维张量

在这里插入图片描述
其实在实际中,并不需要过分的关注张量的定义,只需要明白张量是多维数组就行

张量的基本属性

主要有三个属性:秩、轴、形状

  • 秩:主要告诉我们是张量的维度,其实就是告诉我们是几维向量,通过多少个索引就可以访问到元素。
  • 轴:在张量中,轴是指张量的一个维度。当处理多维数据时,每个维度都可以被称为一个轴。通常,第一个轴称为0轴(或轴0),第二个轴称为1轴(或轴1),以此类推。
  • 形状:形状是指张量在每个轴上的维度大小。它是一个由整数组成的元组,表示张量沿着每个轴的大小。

关于这些后面的例子中会提到

使用PyTorch

在这里插入图片描述

安装PyTorch

PyTorch官网:https://pytorch.org/
根据自己的需求和电脑的硬件情况进行选择,复制下方的pip命令安装即可
在官网中

安装GPU版本的不需要再额外安装CUDA,现在的安装PyTorch会自带安装CUDA。

查看安装版本

print(torch.__version__) # 2.0.1+cpu  版本号
print(torch.cuda.is_available()) # False   # 没有GPU,如果有则返回True

创建张量

默认创建的张量是在CPU下创建

import torch 
# tensor 张量
t = torch.tensor([1,2,3])  # tensor([1, 2, 3])
print(t)

将张量转移到GPU下

# 使用gpu
t = t.cuda()  # tensor([1, 2, 3], device='cuda:0')
print(t)

直接在GPU下创建张量

t = torch.tensor([1, 2, 3]).to('cuda')  # tensor([1, 2, 3], device='cuda:0')

常用函数

import torch
# 创建一个二维张量
t = torch.tensor([
    [1,2,3],
    [4,5,6],
    [7,8,9]
])
# 输出张量
print(t)

查看数据类型

print(type(t))

输出张量的形状

# 同样也可以理解为每一个轴的长度
print(t.shape)
# 两种方式返回内容一样
print(t.size())

改变形状

# 改变后形状要个原张量里面包含的元素数量一样多。
new_t = t.reshape((1,9))
print(new_t)

我们在使用改变形状的时候,在以前需要指定每一个轴的大小,这样还需要自己计算,比较麻烦,我们可以通过将其中一个参数设置为-1,让reshape自动计算其实际值

t.reshape(1,-1)  # 会根据t元素的个数和其他指定的参数自动计算-1代表的实际值

统计张量中元素的个数

# prod() 用于计算张量中所有元素的乘积
# item() 取出张量的值
print(torch.tensor(t.shape).prod().item())  # 思路:根据将所有轴的长度相乘,得出的结果就是元素的个数
print(t.numel()) # 直接返回元素的个数

压缩张量/解压缩张量

通常指的是对张量进行降维操作和恢复原始形状的操作
torch.squeeze() 压缩
torch.unsqueeze() 解压缩

print(t.reshape(1,12))
# tensor([[1., 1., 1., 1., 2., 2., 2., 2., 3., 3., 3., 3.]])
print(t.reshape(1,12).shape)
# torch.Size([1, 12])

# 压缩张量 
# 通过结构我们可以看看出,压缩张量,去除张量中维度大小为1的维度,从而降低张量的维度。如果在调用时不指定维度,则会去除所有大小为1的维度。这对于减少张量的冗余维度很有用。
print(t.reshape(1,12).squeeze())
# tensor([1., 1., 1., 1., 2., 2., 2., 2., 3., 3., 3., 3.])
print(t.reshape(1,12).squeeze().shape)
# torch.Size([12])

# 解压缩张量
print(t.reshape(1,12).squeeze().unsqueeze(dim=0))
# tensor([[1., 1., 1., 1., 2., 2., 2., 2., 3., 3., 3., 3.]])
print(t.reshape(1,12).squeeze().unsqueeze(dim=0).shape)
# torch.Size([1, 12])

四种创建张量的方式和区别

data = np.array([1,2,3])
  • 方式1 Tensor()类构造器函数
    t1 = torch.Tensor(data) 会自动将整数转成小数

  • 方式2 tensor工厂函数
    t2 = torch.tensor(data) 会根据输入的数据类型自动推断张量的数据类型

  • 方式3 as_tensor工厂函数
    t3 = torch.as_tensor(data)

  • 方式4 from_numpy工厂函数
    t4 = torch.from_numpy(data)

四种方式的区别:
前两种方式会生成一份新的数据,后两种是和原数据共享,numpy和torch之间切换非常快,数据共享,两者之间保存统一的内存指向
举例

# 修改data原数据
data[0] = 0
data[1] = 0
data[2] = 0

方式一和方式二生成的张量中的数据没有发生改变

# 张量中的数据没有发生改变
print(t1)  # tensor([1., 2., 3.])
print(t2)  # tensor([1, 2, 3], dtype=torch.int32)

方式三和方式四生成的张量中的数据随着np.array的数据发生改变

# 张量中的数据随着np.array的数据发生改变-
print(t3)  #  tensor([0, 0, 0], dtype=torch.int32)
print(t4)  #  tensor([0, 0, 0], dtype=torch.int32)

注:在刚开始学习时,将重心放在逻辑和代码的正确性上,不需要太关注性能

拼接操作

t1 = torch.tensor([
        [1, 2],
        [3, 4]
])
t2 = torch.tensor([
    [5, 6],
    [7, 8]
])

使用cat函数进行拼接

# dim 根据指定轴进行拼接
t1_2 = torch.cat((t1,t2),dim=0)
print(t1_2)
# 两种拼接方式,张量秩不发生改变
t1_2 = torch.cat((t1,t2),dim=1)
print(t1_2)

合并张量
使用stack将张量合并成更高维的张量

t1 = torch.tensor([
    [1,1,1,1],
    [1,1,1,1],
    [1,1,1,1],
    [1,1,1,1]
])
t2 = torch.tensor([
    [2,2,2,2],
    [2,2,2,2],
    [2,2,2,2],
    [2,2,2,2]
])
t3 = torch.tensor([
    [3,3,3,3],
    [3,3,3,3],
    [3,3,3,3],
    [3,3,3,3]
])
# 使用stack将张量合并成更高维的张量
t = torch.stack((t1,t2,t3))
print(t)
print(t.shape)
# torch.Size([3, 4, 4])

拉伸张量
将多维的张量拉伸到一维,主要有两个方式,reshapeflatten

print(t.reshape(-1))
print(t.flatten())
# 另外还有两个参数可选
# start_dim(可选):指定展平的起始维度。默认为0,表示从第0维开始展平。
# end_dim(可选):指定展平的结束维度。默认为-1,表示展平到最后一维。

四则运算

张量的四则运算和numpy中ndarray的运算一致,都使用了广播机制

张量和常量的四则运算

t1 = torch.tensor([[1,2,3,4],[5,6,7,8]])
print(t1+1)
print(t1.add(1))
# 减法
print(t1-1)
print(t1.sub(1))
# 乘法
print(t1*1)
print(t1.mul(1))
# 除法
print(t1/1)
print(t1.div(1))

张量之间的四则运算

当两个张量形状相同或可广播时,可以直接进行四则运算。如果张量形状不匹配,PyTorch会尝试自动进行广播操作,使得张量能够进行元素级别的四则运算。

import torch

# 创建两个示例张量
tensor1 = torch.tensor([[1, 2], [3, 4]])
tensor2 = torch.tensor([[5, 6], [7, 8]])

# 加法
add_result = tensor1 + tensor2
print(add_result)  # Output: tensor([[ 6,  8],
                   #         [10, 12]])
# 减法
subtract_result = tensor1 - tensor2
print(subtract_result)  # Output: tensor([[-4, -4],
                        #         [-4, -4]])
# 乘法
multiply_result = tensor1 * tensor2
print(multiply_result)  # Output: tensor([[ 5, 12],
                        #         [21, 32]])

# 除法
divide_result = tensor1 / tensor2
print(divide_result)  # Output: tensor([[0.2000, 0.3333],
                      #         [0.4286, 0.5000]])

需要注意的是,张量之间的四则运算是逐元素的,即对应位置的元素进行运算。此外,还要注意确保参与四则运算的张量形状是兼容的,或者能够进行广播操作,否则会引发运算错误。

广播机制的原理

当执行算术运算时,如果两个数组的形状不完全相同,但是符合一定的规则,那么广播机制会自动对其中一个或两个数组进行扩展,使得它们的形状能够匹配,从而实现逐元素的运算。

广播机制的优点

广播机制的好处在于,它允许我们在不创建额外副本的情况下执行运算,从而节省内存和提高运算效率。同时,它也使得我们可以更方便地处理不同形状的数据,例如在神经网络中处理批量数据或处理多维特征数据时

矩阵的乘法和除法 二维张量的点乘

矩阵乘法使用torch.matmul()函数或者@运算符,而矩阵除法则使用逆矩阵(或者伪逆矩阵)来实现。

矩阵乘法

import torch

# 创建两个示例矩阵
matrix1 = torch.tensor([[1, 2], [3, 4]])
matrix2 = torch.tensor([[5, 6], [7, 8]])

# 矩阵乘法
result = torch.matmul(matrix1, matrix2)
print(result)  # Output: tensor([[19, 22],
               #         [43, 50]])

# 或使用 @ 运算符
result = matrix1 @ matrix2
print(result)  # Output: tensor([[19, 22],
               #         [43, 50]])

# 这样也可以用
matrix1.matmul(matrix2)

矩阵除法

在线性代数中,通常没有直接的矩阵除法运算,而是使用逆矩阵(inverse matrix)或者伪逆矩阵(pseudoinverse matrix)来实现矩阵除法。在PyTorch中,可以使用torch.inverse()函数来计算逆矩阵,从而实现矩阵除法。

import torch

# 创建两个示例矩阵
matrix1 = torch.tensor([[1, 2], [3, 4]])
matrix2 = torch.tensor([[5, 6], [7, 8]])

# 计算矩阵2的逆矩阵
inverse_matrix2 = torch.inverse(matrix2)

# 矩阵除法,等价于 matrix1 @ inverse_matrix2
result = torch.matmul(matrix1, inverse_matrix2)
print(result)  # Output: tensor([[-4.0000,  4.0000],
               #         [ 6.5000, -3.5000]])

参考:https://deeplizard.com/learn/video/gZmobeGL0Yg
在这里插入图片描述

  • 9
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小鱼干儿♛

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

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

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

打赏作者

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

抵扣说明:

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

余额充值