tensor的基础操作,包括创建,数学运算,索引等

前言

主要介绍一系列对tensor的操作,可以作为工具查找

一. 初始化tensor

1. 创建tensor
import torch 
my_tensor = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float32, device='cuda')
  • 如果有cuda当然就能用,不能则是cpu,所有有更好的写法
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
device = 'cuda' if torch.cuda.is_available() else 'cpu'
# 两者均可
my_tensor = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float32, device=device, requires_grad=True)
# 可选参数还有requires_grad, 这是能否自动求梯度的关键,单独写的时候是关的
# dtype也很重要,因为cuda一般只支持float32
  • 还可以用.的方法调用
my_tensor.dtype
my_tensor.device
my_tensor.requires.grad
2. 快速创建tensor
x = torch.empty(size=(3, 3))
x = torch.zeros((3, 3))
x = torch.rand((3, 3))
x = torch.ones((3, 3))
x = torch.eye(5, 5)
  • 首先在后面没有参数的情况下,()与(())没有区别, 然后torch.rand()是0~1的均匀分布, 而torch.randn() 是0~1的正态分布
  • torch.eye() 啊,多好的拟声词编程, 和 I I I含义一样
x = torch.arange(start=0, end=5, step=1)
x = torch.linspace(start=0, end=1, steps=10)
  • 这两个常用来比较, 当然可以不用写参数名, 其中第一个是按步长取数, 第二个是按个数, 一般这种都是左包右不包
  • 两者的输出

tensor([0, 1, 2, 3, 4])

tensor([0.0000, 0.1111, 0.2222, 0.3333, 0.4444, 0.5556, 0.6667, 0.7778, 0.8889, 1.0000])

3. 改变tensor分布
x = torch.empty(size=(1, 5)).normal_(mean=0, std=1)
  • 更改分布为均值为0, 标准差为1的正态分布
x = torch.empty(1, 5).uniform_(0, 1)
x = torch.ones(1, 5).uniform_(0, 1)
  • 更改分布为均匀分布, .方法是强制转换, 并不关心原来有什么
x = torch.ones(5)
x = torch.diag(x)
  • 保留对角线的元素, 上面处理之后等同于torch.eye(5)
4. 变量类型与数据类型转换
x = torch.arange(5)
print(x.bool())

>>
tensor([False,  True,  True,  True,  True])
print(x[x.bool()]

>>
tensor([1, 2, 3, 4])
  • bool类型在true的时候保留
x = torch.arange(4)
print(x.short()) # int16
print(x.long()) # int64 (important)
print(x.half()) # float16
print(x.float()) # float32 (important)
print(x.double()) # float64
  • 一些快速变化的方法
x = numpy.zeros(5)
x = torch.from_numpy(x) # 从numpy变为tensor

a = x.numpy() # 从tensor变回numpy

二. 张量的数学计算与比较

1. 张量的加减
a = torch.tensor([1, 2, 3])
b = torch.tensor([1, 2, 3])
z = a + b
z = a - b
  • 虽然torch.add(a, b) 也是可以的, 但是还是简洁一点好
2. 张量的除法
a = torch.tensor([1, 2, 3])
b = torch.tensor([1, 2, 3])
c = torch.tensor([2])
print(torch.true_divide(a, b))
  • torch.true_divide() 是元素级的除法,如果维度一致就是一对一除法, 如果除数是单个tensor就统统除以它
3. inplace操作
  • inplace操作 是pytorch计算的一种技巧, 它使得pytorch不会创建变量的副本, 而是就地操作,增加了计算效率
a = torch.ones(1, 3)
b = torch.zeros(1, 3)
b.add_(a)
b += a
  • inplace 有两种方式, 一种是这样加下划线, 一种是类似b += a 的操作, 有些令人疑惑, 因为b = b+a 就会创建副本
4. 求幂
x = torch.tensor([1, 2, 3])
print(x.pow(2))
print(x ** 2)
  • 一样的结果
5. 简单的比较
x = torch.tensor([0, 1, 2, 3])
print(x > 0)
print(x < 0)
  • 这样会返回一个bool类型的tensor
6. 张量乘法
a = torch.rand(2, 5)
b = torch.rand(5, 3)

print(torch.mm(a, b)) # 2*3
print(a.mm(b))
  • torch.mm()a.mm() 都是正常的矩阵乘法
a = torch.rand(2, 5)
b = torch.rand(2, 5)
print(a * b)
  • 这是执行的元素级的乘法
a = torch.tensor([1, 2, 3])
b = torch.tensor([1, 2, 3])
print(a.dot(b))

a.dot(b) 是先元素级相乘再求和

7. 矩阵求幂
  • 这里是对方针进行操作, 因为实际是对自己执行矩阵运算
a = torch.rand(2, 2)
print(a.matrix_power(3))
8. batch 级矩阵乘法
  • 两个维度当然可以直接矩阵乘法, 但是带有batch就需要batch的乘法
a = torch.rand(3, 2, 5)
b = torch.rand(3, 5, 4)

print(torch.bmm(a, b))  # 3, 2, 4
  • batch不变, 而后对每片执行矩阵乘法
9. 其余有用的操作,像求和,最大值
x = torch.tensor([1, 2, 3])
y = torch.tensor([2, 3, 4])
sum_x = torch.sum(x, dim=0)
values, index = torch.max(x, dim=0) # 返回的是tensor的数,比如index是tensor(2)
values, index = torch.min(x, dim=0) 
abs_x = torch.abs(x) # 计算绝对值
z = torch.argmax(x, dim=0) # 感觉torch.argmax有些像max的特例, 因为它只返回索引值
z = torch.argmin(x, dim=0) 
mean_x = torch.mean(x.float(), dim=0) # 注意mean需要float的格式
z = torch.eq(x, y)  # 这里输出的是元素等级判别的bool值
sorted_value, index = torch.sort(y, dim=0, descending=False) # descending参数为True则为降序, 反之为升序
z = torch.clamp(x, min=2, max=10) # min与max可以缺省, 这里是小于2的被设为2, 大于10的被限制为10

三. 张量索引

1. 基础索引
batch_size = 10
features = 25

print(x[0])
print(x[:, 0]) # 这是取所有行第一列
print(x[2, 0:10]) # 第三行, 0到9列, 左包右不包
2. 稍微高级
x = torch.arange(10)
index = [2, 4, 5]
print(x[index]) # 索引可以是列表
x = torch.tensor([[1, 2, 3], [4, 5, 6]])
rows = torch.tensor([1, 0])
cols = torch.tensor([1, 0])
print(x[rows, cols])

>>
tensor([5, 1])
  • 先选第二行第二个数, 然后是第一行第一个数
x = torch.ones((4, 4))
y = x[::2, ::2]
  • 隔着两个元素确定行和列
3. 高级点的索引操作
x = torch.tensor([2, 3, 5])
print(x[(x<2) | (x > 3)]) # 输出x小于2或者x大于3的数
print(x[(x>2) & (x < 5)]) # 输出x大于2或者x小于5的数
x = torch.arange(10)
print(x[x.remainder(2) == 0]) # 这是输出x除2余数为0
4. 其余有用的操作, 例如torch.where, .unique
x = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(torch.where(x>5, x, 10))
  • 这个torch.where有些像if else这种, 上面如果满足x>5的地方就维持x不变, 如果不满足也就是小于等于5就变为10
x = torch.tensor([0, 0, 1, 2])
print(x.unique())
  • 这个是集合那种保留单个的操作
x = torch.rand(3, 4)
print(x.ndimension())

>> 
2
  • 这是输出的有几维
x = torch.rand(3, 4)
print(x.numel())

>>
12
  • 输出一个矩阵的总元素个数
5. 广播机制
a = torch.arange(3).reshape((3, 1))
b = torch.arange(2).reshape((1, 2))

print(a+b)

>>
tensor([[0, 1],
        [1, 2],
        [2, 3]])

  • 相当于是a的列复制了一下,b的行复制了一下

四. reshape操作

1. view() & reshape
  • reshape 有两种方法, 一是view() , 另一个是reshape()
x = torch.arange(9)
x = x.reshape(3, 3)
x = x.view(3, 3)
  • 这两者有些不同, view 用于储存在连续内存的张量, reshape则不受限制\

  • 下面用一个例子来说明:

x = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(x.t())
x = x.t()
x = x.view(6)

这样就会报错, 因为转置使得其不再连续空间了, 所以此时需要用reshape

2. torch.cat()
x = torch.rand(2, 3)
y = torch.rand(2, 3)
z = torch.cat(x, y, dim=0) # (4, 3)
z = torch.cat(x, y, dim=1) # (2, 6)
3. 二维与多维矩阵的转置
  • 对于二维有两种方法
x = torch.rand(2, 3)
print(x.t()) # 3, 2
print(x.T) 
  • 这两个是一样的

  • 对于多维

x = torch.rand(5, 3, 8)
z = x.permute(0, 2, 1) 
print(z.shape)

>>
torch.Size([5, 8, 3])
  • x.permute() 是变换轴, 上面程序0轴不变, 而1与2轴交换位置

五. squeeze() 操作

  • squeeze()unsqueeze是个比较重要的函数, 主要是对数据的维度进行压缩或者解压.
x = torch.arange(10)
print(x.unsqueeze(0).shape)
print(x.unsqueeze(1).shape)

>>
torch.Size([1, 10])
torch.Size([10, 1])
x = torch.arange(10)
print(x.unsqueeze(0).unsqueeze(2).shape)
y = x.unsqueeze(0).unsqueeze(2)
print(y.squeeze(2).shape)

>>
torch.Size([1, 10, 1])
torch.Size([1, 10])

六. np.tile

1.沿X轴复制
  • 在numpy中,np.tile(a,(2))函数的作用就是将函数将函数沿着X轴扩大两倍。如果扩大倍数只有一个,默认为X轴
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

live_for_myself

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

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

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

打赏作者

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

抵扣说明:

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

余额充值