《Pytorch学习指南》- 基础API(2)

《Pytorch学习指南》- 基础API(2)

Scroll Down

1. inplace和广播机制

  • in-place 操作
    1. 就地操作, 不适用临时变量, 比如 a.add_(b) = a + b => 计算结果直接赋值给 a 等价于 a += b
  • 广播机制
    1. 张量参数可以自动的扩展为相同的大小
    2. 广播机制满足的条件
      • 每个张量至少有一个维度
      • 满足右对齐 :
      • 例如 torch.rand(2,1,1) 和 torch.rand(3) , 如果维度的最后一个维度, 比如 torch.rand(2,1,1) 最后一个是1, torch.rand(3)最后一个维度是3
      • 满足 最后(右) 维度的任意一个是1或者两个维度相等就满足右对齐
    3. torch.rand(2,1,1) 和 torch.rand(3) 会自动对其, 将torch.rand(3)扩展为torch.rand(1,1,3)
import torch

for module in torch,:
    print(module.__name__, module.__version__)
torch 1.9.1+cpu

1.1 广播机制

  • 关于计算结果维度问题
  • (2,1,1,3) + (4,2,3) => shape : (2, 4, 2, 3)
a = torch.tensor([
    [1, 1, 1],
    [2, 2, 2]
])
b = torch.tensor([1, 1, 1])

# a : (2, 3)
# b : (1, 3)
# a + b => c : b 和 a 的第一行和第二行分别相加

c = a + b
print(a.shape)
print(b.shape)
print(c)

torch.Size([2, 3])
torch.Size([3])
tensor([[2, 2, 2],
        [3, 3, 3]])

2. tensor的取整取余的运算

  • .floor()向下取整数
  • .ceil()向上取整数
  • .round()四舍五入>=0.5向上取整, <0.5向下取整.trunc()裁剪,只取整数部分
  • .frac()只取小数部分
  • %取余 : a % b, mod(a, b), remainder(a, b)
a = torch.rand(2, 2)
a = a * 10
print(a)

print("floor => ", torch.floor(a))
print("ceil => ", torch.ceil(a))
print("round => ", torch.round(a))
print("trunc => ", torch.trunc(a))
print("frac => ", torch.frac(a))
print("a % 2 => ", a % 2)

b = torch.tensor([[2, 3], [4, 5]],
                 dtype=torch.float)
print("fmod => ", torch.fmod(a, b))
print("remainder => ", torch.remainder(a, b))
tensor([[1.5728, 0.3311],
        [3.1508, 2.8495]])
floor =>  tensor([[1., 0.],
        [3., 2.]])
ceil =>  tensor([[2., 1.],
        [4., 3.]])
round =>  tensor([[2., 0.],
        [3., 3.]])
trunc =>  tensor([[1., 0.],
        [3., 2.]])
frac =>  tensor([[0.5728, 0.3311],
        [0.1508, 0.8495]])
a % 2 =>  tensor([[1.5728, 0.3311],
        [1.1508, 0.8495]])
fmod =>  tensor([[1.5728, 0.3311],
        [3.1508, 2.8495]])
remainder =>  tensor([[1.5728, 0.3311],
        [3.1508, 2.8495]])

3. tensor的比较运算

  • 注意 : 比较的时候, 要求两个数据的shape相同
  • torch.eq(input, other, out=None) 按成员进行等式操作,相同返回True
  • torch.equal(tensor1, tensor2) 如果tensor1和tensor2有相同的size和elements,则为true
  • torch.ge(input, other, out=None) input >= other
  • torch.gt(input, other, out=None) input > other
  • torch.le(input, other, out=None) input =< other
  • torch.It(input, other, out=None) input < other
  • torch.ne(input, other, out=None) input != other 不等于
a = torch.tensor([
    [1, 2, 3],
    [3, 4, 5]
])

b = torch.tensor([
    [2, 3, 4],
    [5, 6, 7]
])

print(a)
print(b)

# 判断是否相等
print(torch.eq(a, b))
print(torch.equal(a, b))
# 大于等于
print(torch.ge(a, b))
# 大于
print(torch.gt(a, b))
# 小于等于
print(torch.le(a, b))
# 小于
print(torch.lt(a, b))
# 不等于
print(torch.ne(a, b))
tensor([[1, 2, 3],
        [3, 4, 5]])
tensor([[2, 3, 4],
        [5, 6, 7]])
tensor([[False, False, False],
        [False, False, False]])
False
tensor([[False, False, False],
        [False, False, False]])
tensor([[False, False, False],
        [False, False, False]])
tensor([[True, True, True],
        [True, True, True]])
tensor([[True, True, True],
        [True, True, True]])
tensor([[True, True, True],
        [True, True, True]])

4. tensor的排序与前k值运算

  • torch.sort(input, dim=None, descending=False, out=None) 对目标input进行排序
  • torch.topk(input, k, dim=None, largest=True, sorted=True,out=None) 沿着指定维度返回最大k个数值及其索引值
  • torch.kthvalue(input, k, dim=None, out=None) 沿着指定维度返回第k个最小值及其索引值
  • torch.isfinite(tensor) tensor是否是有界的
  • torch.isinf(tensor) tensor是否是无界的(无穷大)
  • torch.isnan(tensor) 是否为有效数据

4.1 排序

  • sort(a, dim=1, descending=False)
    1. dim指定要排序的轴比如在dim=0表示在以某一列为单位进行排序
    2. dim=1,以某一行为单位进行排序
    3. descending : True : 降序排列, False 升序排列
a = torch.tensor([[1, 4, 4, 3, 5],
                  [2, 3, 1, 3, 5]])
print(a.shape)
print(torch.sort(a, dim=1,
                 descending=False))


b = torch.tensor([[1, 4, 4, 3, 5],
                  [2, 3, 1, 3, 5]])
print(b.shape)
print(torch.sort(b, dim=0,
                 descending=False))
torch.Size([2, 5])
torch.return_types.sort(
values=tensor([[1, 3, 4, 4, 5],
        [1, 2, 3, 3, 5]]),
indices=tensor([[0, 3, 1, 2, 4],
        [2, 0, 1, 3, 4]]))
torch.Size([2, 5])
torch.return_types.sort(
values=tensor([[1, 3, 1, 3, 5],
        [2, 4, 4, 3, 5]]),
indices=tensor([[0, 1, 1, 0, 0],
        [1, 0, 0, 1, 1]]))

4.2 TopK

  • torch.topk(a, k=2, dim=1, largest=False)
    1. 获取前 k 的数据
    2. dim=0, 表示以列为单位统计, 比如 第一列的前k大(小)的数据,dim=1表示以行为单位
    3. largest : 如果为True, 表示获取最大的k个数据, 如果为False,表示获取最小的k个数据
  • torch.kthvalue(a, k=2, dim=0)
    1. 获取第k大(小)的数据
a = torch.tensor([[2, 4, 3, 1, 5],
                  [0, 3, 5, 1, 4]])
print("\n",a.shape)

# 获取最小的前2个数据
# a 的第一行最小的两个数据是 1,2
# a 的第二行最小的两个数据是 0,1
print("\n",torch.topk(a, k=2, dim=1, largest=False))

# 获取以列为单位的第二小的数据
# 比如 : 第一列第二小的是2, 第二列第二小的是4
print("\n",torch.kthvalue(a, k=2, dim=0))
print("\n",torch.kthvalue(a, k=2, dim=1))
 torch.Size([2, 5])

 torch.return_types.topk(
values=tensor([[1, 2],
        [0, 1]]),
indices=tensor([[3, 0],
        [0, 3]]))

 torch.return_types.kthvalue(
values=tensor([2, 4, 5, 1, 5]),
indices=tensor([0, 0, 1, 1, 0]))

 torch.return_types.kthvalue(
values=tensor([2, 1]),
indices=tensor([0, 3]))

4.3 判断数据无穷或有效

  • torch.isfinite(a)
    1. 判断是否是无界值, 如果是无界值为True
  • torch.isinf(a/0)
    1. 判断是否为无穷值, 如果是返回True
  • torch.isnan(a)
    1. 判断是否为 nan 值
a = torch.rand(2, 3)
print(a)
print(a/0)
# 非0值除以0会得到无限大的值
# 判断是否为无界值(无穷大)
print(torch.isfinite(a))
print(torch.isfinite(a/0))
# 如果不是无界值会返回True
print(torch.isinf(a/0))
# 判断是否为Nan值
print("\n", torch.isnan(a))

import numpy as np
a = torch.tensor([1, 2, np.nan])
print(torch.isnan(a))

a = torch.rand(2, 3)
print(a)
print(torch.topk(a, k=2, dim=1, largest=False))
print(torch.topk(a, k=2, dim=1, largest=True))
tensor([[0.9370, 0.2305, 0.1475],
        [0.3855, 0.3496, 0.7522]])
tensor([[inf, inf, inf],
        [inf, inf, inf]])
tensor([[True, True, True],
        [True, True, True]])
tensor([[False, False, False],
        [False, False, False]])
tensor([[True, True, True],
        [True, True, True]])

 tensor([[False, False, False],
        [False, False, False]])
tensor([False, False,  True])
tensor([[0.8951, 0.0250, 0.2720],
        [0.4033, 0.2682, 0.7609]])
torch.return_types.topk(
values=tensor([[0.0250, 0.2720],
        [0.2682, 0.4033]]),
indices=tensor([[1, 2],
        [1, 0]]))
torch.return_types.topk(
values=tensor([[0.8951, 0.2720],
        [0.7609, 0.4033]]),
indices=tensor([[0, 2],
        [2, 0]]))

5. 三角函数

  • torch.abs(input, out=None)
  • torch.acos(input, out=None)
  • torch.asin(input, out=None)
  • torch.atan(input, out=None)
  • torch.atan2(input, input2, out=None)
  • torch.cos(input, out=None)
  • torch.cosh(input, out=None)
    1. 双曲余弦
  • torch.sin(input, out=None)
  • torch.sinh(input, out=None)
  • torch.tan(input, out=None)
  • torch.tanh(input, out=None)
a = torch.rand(2, 3)
b = torch.cos(a)
print(a)
print(b)
tensor([[0.3334, 0.8809, 0.6101],
        [0.2979, 0.1444, 0.8445]])
tensor([[0.9449, 0.6365, 0.8196],
        [0.9560, 0.9896, 0.6641]])
a = torch.tensor([60,30])
print(torch.cosh(a))
tensor([5.7100e+25, 5.3432e+12])

6.tensor中的其他函数

  • torch.abs()
    1. 绝对值
  • torch.sign()
    1. sgn函数, 也叫阶跃函数
  • torch.erf
  • torch.lerp
  • torch.erfinv()
  • torch.addcdiv()
  • torch.sigmoid()
  • torch.addcmul()
  • torch.neg()
  • torch.cumprod()
  • torch.reciprocal()
  • torch.cumsum()
  • torch.rsqrt()