“same shapes are always broadcastable”,相同形状数组总是可以进行广播计算。这里简单强调一下,虽然我们往往觉得不同形状之间的张量计算才是应用到广播特性,但其实相同形状的张量计算,尽管是对应位置元素进行计算,但本质上也是应用到了广播特性。
import torch
t1 = torch.arange(3) # tensor([0, 1, 2])
t2 = torch.arange(2,5) # tensor([2, 3, 4])
# 对应位置元素依次相加
t1 + t2 # tensor([2, 4, 6])
标量可以和任意形状的张量进行计算,计算过程就是标量和张量的每一个元素进行计算。
import torch
t1 = torch.arange(3) # tensor([0, 1, 2])
# 1是标量,可以看成是零维
t1 + 1 # tensor([1, 2, 3])
t1 + torch.tensor(1) # tensor([1, 2, 3])
t2的形状是(1, 4),和t1的形状(3, 4)在第一个分量上取值不同,但该分量上t2取值为1,因此可以广播,也就可以进行计算。若该分量上t2取值不为1,则不可进行广播
t1 = torch.zeros(3, 4)
t1.shape # torch.Size([3, 4])
t2 = torch.ones(1, 4)
t2.shape # torch.Size([1, 4])
(t1 + t2).shape # torch.Size([3, 4])
t3的形状是(3, 1),和t1的形状(3, 4)在第二个分量上取值不同,但该分量上t3取值为1,因此可以广播,也就可以进行计算。若该分量上t3取值不为1,则不可进行广播
t1 = torch.zeros((3, 4))
t1.shape # torch.Size([3, 4])
t3 = torch.ones(3, 1)
t3.shape # torch.Size([3, 1])
(t1 + t3).shape # torch.Size([3, 4])
t4的形状是(3, 1),而t5的形状是(1, 3),二者的形状在两个份量上均不相同,但都有存在1的情况,因此也是可以广播的
t4 = torch.arange(3).reshape(3, 1)
print(t4.shape) # torch.Size([3, 1])
t5 = torch.arange(3).reshape(1, 3)
print(t5.shape) # torch.Size([1, 3])
(t4 + t5).shape # torch.Size([3, 3])
对于不同维度的张量,我们首先可以将低维的张量升维,然后依据相同维度不同形状的张量广播规则进行广播。
t6 = torch.arange(6).reshape(3, 2)
print(t6.shape) # torch.Size([3, 2])
t7 = torch.arange(7,9)
print(t7.shape) # torch.Size([2])
(t6 + t7).shape # torch.Size([3, 2])
逐点运算(Pointwise Ops):指的是针对Tensor中每个元素执行的相同运算操作;
函数 | 描述 |
---|---|
torch.add(t1,t2 ) | t1、t2两个张量逐个元素相加,等效于t1+t2 |
torch.subtract(t1,t2) | t1、t2两个张量逐个元素相减,等效于t1-t2 |
torch.multiply(t1,t2) | t1、t2两个张量逐个元素相乘,等效于t1*t2 |
torch.divide(t1,t2) | t1、t2两个张量逐个元素相除,等效于t1/t2 |
t1 = torch.tensor([1, 2]) # tensor([1, 2])
t2 = torch.tensor([3, 4]) # tensor([3, 4])
torch.add(t1, t2) # tensor([4, 6])
t1 + t2 # tensor([4, 6])
函数 | 描述 |
---|---|
torch.abs(t) | 返回绝对值 |
torch.ceil(t) | 向上取整 |
torch.floor(t) | 向下取整 |
torch.round(t) | 四舍五入取整 |
torch.neg(t) | 返回相反的数 |
torch.manual_seed(123)
t = torch.randn(5) # tensor([-0.1115, 0.1204, -0.3696, -0.2404, -1.1969])
torch.abs(t) # tensor([0.1115, 0.1204, 0.3696, 0.2404, 1.1969])
注:虽然此类型函数是数值调整函数,但并不会对原对象进行调整,而是输出新的结果。
而若要对原对象本身进行修改,则可考虑使用方法_()
的表达形式,对对象本身进行修改。此时方法就是上述同名函数。
torch.manual_seed(123)
t = torch.randn(5) # tensor([-0.1115, 0.1204, -0.3696, -0.2404, -1.1969])
t.abs_() # tensor([0.1115, 0.1204, 0.3696, 0.2404, 1.1969])
t.exp_() # tensor([1.1179, 1.1279, 1.4472, 1.2718, 3.3099])
tensor的大多数科学计算只能作用于tensor对象
数学运算函数 | 数学公式 | 描述 |
---|---|---|
幂运算 | ||
torch.exp(t) | $ y_{i} = e^{x_{i}} $ | 返回以e为底、t中元素为幂的张量 |
torch.expm1(t) | $ y_{i} = e^{x_{i}} $ - 1 | 对张量中的所有元素计算exp(x) - 1 |
torch.exp2(t) | $ y_{i} = 2^{x_{i}} $ | 逐个元素计算2的t次方。 |
torch.pow(t,n) | $\text{out}_i = x_i ^ \text{exponent} $ | 返回t的n次幂 |
torch.sqrt(t) | $ \text{out}{i} = \sqrt{\text{input}{i}} $ | 返回t的平方根 |
torch.square(t) | $ \text{out}_i = x_i ^ \text{2} $ | 返回输入的元素平方。 |
对数运算 | ||
torch.log10(t) | $ y_{i} = \log_{10} (x_{i}) $ | 返回以10为底的t的对数 |
torch.log(t) | $ y_{i} = \log_{e} (x_{i}) $ | 返回以e为底的t的对数 |
torch.log2(t) | $ y_{i} = \log_{2} (x_{i}) $ | 返回以2为底的t的对数 |
torch.log1p(t) | $ y_i = \log_{e} (x_i $ + 1) | 返回一个加自然对数的输入数组。 |
torch.pow(torch.tensor(2), 2) #tensor(4)
t = torch.arange(1, 4).float()
t.dtype # torch.float32
torch.exp(t) # tensor([ 2.7183, 7.3891, 20.0855])
torch.exp(torch.log(t)) # tensor([1., 2., 3.])
规约运算指的是针对某张量进行某种总结,最后得出一个具体总结值的函数。此类函数主要包含了数据科学领域内的诸多统计分析函数,如均值、极值、方差、中位数函数等等。
函数 | 描述 |
---|---|
torch.mean(t) | 返回张量均值 |
torch.var(t) | 返回张量方差 |
torch.std(t) | 返回张量标准差 |
torch.var_mean(t) | 返回张量方差和均值 |
torch.std_mean(t) | 返回张量标准差和均值 |
torch.max(t) | 返回张量最大值 |
torch.argmax(t) | 返回张量最大值索引 |
torch.min(t) | 返回张量最小值 |
torch.argmin(t) | 返回张量最小值索引 |
torch.median(t) | 返回张量中位数 |
torch.sum(t) | 返回张量求和结果 |
torch.logsumexp(t) | 返回张量各元素求和结果,适用于数据量较小的情况 |
torch.prod(t) | 返回张量累乘结果 |
torch.dist(t1, t2) | 计算两个张量的闵式距离,可使用不同范式 |
torch.topk(t) | 返回t中最大的k个值对应的指标 |
# 生成浮点型张量
t = torch.arange(10).float()
# 计算均值
torch.mean(t) # tensor(4.5000)
# 计算标准差、均值
torch.std_mean(t) # (tensor(3.0277), tensor(4.5000))
# 计算最大值
torch.max(t) # tensor(9.)
# 返回最大值的索引
torch.argmax(t) # tensor(9)
# 求和
torch.sum(t) # tensor(45.)
dist函数可计算闵式距离(闵可夫斯基距离),通过输入不同的p值,可以计算多种类型的距离,如欧式距离、街道距离等。
t1 = torch.tensor([1.0, 2])
t2 = torch.tensor([3.0, 4])
torch.dist(t1, t2, 2) # 计算欧式距离
torch.dist(t1, t2, 1) # 计算街道距离
由于规约运算是一个序列返回一个结果,因此若是针对高维张量,则可指定某维度进行计算。
# 按照第一个维度求和(每次计算三个)、按列求和
t2 = torch.arange(12).float().reshape(3, 4)
torch.sum(t2, dim = 0) # tensor([12., 15., 18., 21.])
# 按照第二个维度求和(每次计算四个)、按行求和
torch.sum(t2, dim = 1) # tensor([ 6., 22., 38.])
比较运算是一类较为简单的运算类型,和Python原生的布尔运算类似,常用于不同张量之间的逻辑运算,最终返回逻辑运算结果(逻辑类型张量)。
函数 | 描述 |
---|---|
torch.eq(t1, t2) | 比较t1、t2各元素是否相等,等效== |
torch.equal(t1, t2) | 判断两个张量是否是相同的张量 |
torch.gt(t1, t2) | 比较t1各元素是否大于t2各元素,等效> |
torch.lt(t1, t2) | 比较t1各元素是否小于t2各元素,等效< |
torch.ge(t1, t2) | 比较t1各元素是否大于或等于t2各元素,等效>= |
torch.le(t1, t2) | 比较t1各元素是否小于等于t2各元素,等效<= |
torch.ne(t1, t2) | 比较t1、t2各元素是否不相同,等效!= |
t1 = torch.tensor([1.0, 3, 4])
t2 = torch.tensor([1.0, 2, 5])
t1 == t2 # tensor([ True, False, False])
# 判断t1、t2是否是相同的张量
torch.equal(t1, t2) # False
torch.eq(t1, t2) # tensor([ True, False, False])
t1 > t2 # tensor([False, True, False])