2.4 Numpy与Tensor

2.4 Numpy与Tensor

Tensor是零维、一维、二维及多维的数组。它与Numpy相似,二者可以共享内存,且之间的转换非常方便和高效。不过它们也有不同之处,最大的区别在于Numpy会把ndarry放在CPU中进行加速运算,而由Torch产生的Tensor会放在GPU中进行加速运算(假设当前环境有GPU)。

2.4.1Tensor概述

对Tensor的操作很多,从接口的角度来划分,可以分为两类:
1)torch.function,如torch.sum,torch.add等;
2)tensor.function,如tensor.view,tensor.add等
这些操作对大部分Tensor都是等价的。
从修改方式的角度来划分,可以分为以下两类:
1)不修改自身数据,如x.add(y),x的数据不变,返回一个新的Tensor;
2)修改自身数据,如x.add_(y)(运行符带下划线后缀),运行结果存在x中,x被修改。

# 1、不修改自身数据,如x.add(y),x的数据不变,返回一个新的Tensor
# 2、修改自身数据,如x.add_(y)(运行符带下划线后缀),运算结果存在x中,x被修改
x = torch.tensor([1, 2])
y = torch.tensor([3, 4])
# add()不修改自身数据,返回一个新的张量
z = x.add(y)
z1 = torch.add(x, y)
print(z1)
print(z)
print(x)
# 运算结果直接保存在x中
x.add_(y)
print(x)

2.4.2 创建Tensor

创建Tensor的方法有很多,可以从列表或ndarry等类型进行构建,也可根据指定的形状构建。
常见的创建Tensor方法

t1 = torch.Tensor(2, 3)
t2 = torch.Tensor([[1, 2, 3], [4, 5, 6]])
t3 = torch.tensor([[1, 2, 3],[5, 6, 7]])
print("t1:{}".format(t1))
print("t2:{}".format(t2))
print("t3:{}".format(t3))
# 查看Tensor的形状
# shape和size()是等价的
print(t2.size())
print(t2.shape)
# 根据已有形状创建Tensor
t4 = torch.Tensor(t2.size())
print("t4:{}".format(t4))

在这里要注意torch.tensor与torch.Tensor的几点区别
1)torch.Tensor与torch.empty和torch.tensor的一种混合,但是当传入数据时,torch.Tensor使用全局默认dtype(FloatTensor),而torch.tensor是从数据中推断数据类型;
2)torch.tensor(1)返回一个固定值1,而torch.Tensor(1)返回一个大小为1的张量,它是随机初始化的值

# torch.Tensor与torch.tensor的几点区别
t5 = torch.Tensor(1)
t6 = torch.tensor(1)
print("t5的值{},t5的数据类型{}".format(t5, t5.type()))
print("t6的值{},t6的数据类型{}".format(t6, t6.type()))

输出结果
下面是一些生成Tensor的例子

# 下面是自动生成Tensor的例子
# 生成单位矩阵
x1 = torch.eye(2, 2)
# 生成全是0的矩阵
x2 = torch.zeros(3, 3)
# linspace 生成数据
x3 = torch.linspace(1, 10, 4)
# rand 生成满足[0,1)的均匀分布随机数
x4 = torch.rand(2, 3)
# randn生成标准正态随机数
x5 = torch.randn(2, 3)
# 返回所给数据形状相同,值全为0的张量
x6 = torch.zeros_like(torch.rand(2, 3))
print("x1的值:{}\nx2的值:{}\nx3的值:{}\nx4的值:{}\nx5的值:{}\nx6的值:{}\n".format(x1, x2, x3, x4, x5, x6))

2.4.3 修改Tensor形状

下面是修改Tensor常用的函数和它的说明
tensor常用修改形状的函数

# 生成一个矩阵
a1 = torch.rand(2, 3)
# 查看a1的形状
print(a1.size())
# 查看a1的维度
print(a1.dim())
# 把a1变为3×2的矩阵
print(a1.view(3, 2))
# 把a1展平为1维向量
y = a1.view(-1)
print(y, y.shape)
# 利用unsqueeze增加一个维度
z = torch.unsqueeze(y, 0)
print(z, z.shape)
# 计算z的元素个数
print(z.numel())

torch.view与torch.reshape的异同
1)reshape可以由torch.reshape(),也可由torch.Tensor.reshape调用。但view只能由torch.Tensor.view来调用
2)对于一个将要被view的Tensor,新的size必须与原来的size与stride兼容。否则,在view之前必须调用contiguous方法
3)同样也是返回与input数据量相同,但形状不同的Tensor。若满足view条件,则不会copy,若不能满足,则会copy
4)如果你只想重塑张量,请使用torch.reshape。如果你还关注内存使用情况并希望两个张量共享相同的数据,请使用torch.Tensor.view

2.4.4 索引操作

Tensor的索引操作与Numpy类似,一般情况下索引结果与源数据共享内存,即修改了一个另外一个也会改变。
在这里插入图片描述

2.4.5 广播机制

import torch
import numpy as np

A = np.arange(0, 40, 10).reshape(4, 1)
B = np.arange(0, 3)
# 把ndarrary转换为tensor
A1 = torch.Tensor(A)
B1 = torch.Tensor(B)
# Tensor自动实现广播 
C = A1 + B1
# 我们根据广播机制,可以手工进行配置
# 根据规则1,B1需要向A1看齐,把B变为(1, 3)
# unsqueeze表示在指定维度增加个1
B2 = B1.unsqueeze(0)
# 使用expand函数重复数组,分别得到4×3矩阵
A2 = A1.expand(4, 3)
B3 = B2.expand(4, 3)
# 然后进行相加,C1与C结果一致
C1 = A2 + B3

2.4.6 逐元素操作

与Numpy一样,Tensor也有逐元素操作,且操作内容相似,但使用函数可能不尽相同
在这里插入图片描述
说明:这些操作均会创建新的Tensor,如果需要就地操作,可以使用这些方法的下划线版本,如add_()

import torch
t = torch.randn(1, 3)
t1 = torch.randn(3, 1)
t2 = torch.randn(1, 3)
# t+0.1 * (t1/t2)
torch.addcdiv(t, 0.1, t1, t2)
# 计算sigmoid
torch.sigmoid(t)
# 将t限制在[0,1]之间
torch.clamp(t, 0, 1)
# 对t+2进行就地运算,直接改变t的自身数据
t.add_(2)

2.4.7 归并操作

归并操作就是对输入进行归并或合计等操作,这类操作的输入输出形状一般并不相同。
在这里插入图片描述
说明:归并操作一般涉及一个dim参数,指定沿哪个维进行归并。另一个参数是keepdim,说明输出结果中是否保留维度1,缺省情况是False,即不保留。

import torch
# 生成一个含6个数的向量
a = torch .linspace(0, 10 ,6)
# 使用view方法,把a变为2×3矩阵
a = a.view((2, 3))
# 沿y轴方向累加,即dim=0
b = a.sum(dim=0)
# 沿y轴方向累加,即dim=0,并保留含1的维度,这时要考虑keepdim参数
b = a.sum(dim=0, keepdim=True)

2.4.8 比较操作

比较操作一般是进行逐元素比较,有些是按指定方向比较。
在这里插入图片描述

import torch
x = torch.linspace(0, 10, 6).view(2, 3)
# 求所有元素的最大值
torch.max(x)
# 求y轴方向的最大值,会返回下标
torch.max(x, dim=0)
# 求最大的2个元素,会返回下标
torch.topk(x, 2, dim =0)

2.4.9 矩阵操作

常用的算法有两种:一种是逐元素乘法,另外一种是点积乘法。
在这里插入图片描述
说明:
1)Torch的dot与Numpy的dot有点不同,Torch中的dot是对两个1D张量进行点积运算,Numpy中的dot无此限制。
2)mm是对2D的矩阵进行点积,bmm对含batch的3D进行点积运算
3)转置运算会导致存储空间不连续,需要调用contiguous方法转为连续

import torch
a = torch.tensor([2, 3])
b = torch.tensor([3, 4])
# 只能计算一维张量
torch.dot(a, b)
x = torch.randint(10, (2, 3))
y = torch.randint(6, ( 3, 4))
torch.mm(x,y)
x = torch.randint(10, (2, 2, 3))
y = torch.randint(6, (2, 3, 4))
# 带batch
torch.bmm(x, y)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值