0%

[DL] PyTorch 折桂 3:张量的运算 2

接上文 [DL] PyTorch 折桂 2:张量的运算 1

3. math 操作

3.1 pointwize 操作

pointwise 指的是元素对元素。比如

1
2
A = torch.Tensor([a1, a2])
A + 2. = torch.Tensor([a1+2., a2+2.])

3.1.1 张量的四则运算

1
2
3
4
torch.add(input, other, *, alpha=1, out=None) # 相加
torch.sub(input, other, out=None) # 相减
torch.mul(input, other, out=None) # 相乘
torch.div(input, other, out=None) # 相除

torch.add()比较特殊,它遵循如下公式:
$$out=input+alpha×other$$
所以 torch.add(torch.tensor(1), torch.tensor(2), torch.tensor(3)) 的运算实际上是 $1+2*3=7$。

我们还有 torch.addcdiv(input, tensor1, tensor2, *, value=1, out=None),对应的运算规则为
$$out=input+value*\frac{tensor1}{tensor2}$$
torch.addcmul(input, tensor1, tensor2, *, value=1, out=None),对应运算规则为
$$out=input+value*tensor1*tensor2$$

3.1.2 指数、对数、幂函数的运算

两个指数函数

  • torch.exp(input, out=None) 自然指数运算:
    $$out=e^{input}$$

  • torch.pow(input, exponent, out=None) 任意指数运算:
    $$out=x^{exponent}$$

四个对数函数

  • torch.log(input, out=None) 自然对数运算:
    $$out=log_e{input}$$
  • torch.log1p(input, out=None) 自然对数运算:
    $$out=log_e{(input+1)}$$
  • torch.log2(input, out=None) 以 2 为底的对数运算:
    $$out=log_2{input}$$
  • torch.log10(input, out=None) 以 10 为底的对数运算:
    $$out=log_{10}{input}$$

3.1.3 变换函数

  • torch.abs(input, out=None):返回张量的绝对值。
  • torch.ceil(input, out=None):对张量向上取整。
  • torch.floor(input, out=None):对张量向下取整。
  • torch.floor_divide(input, other, out=None):张量相除后向下取整。
  • torch.fmod(input, other, out=None):对张量取余。
  • torch.neg(input, out=None):取张量的相反数。
  • torch.round(input, out=None):对张量取整。
  • torch.sigmoid(input, out=None):对张量进行 sigmoid 计算。
  • torch.sqrt(input, out=None):对张量取平方根。
  • torch.square(input, out=None):对张量平方。
  • torch.sort(input, dim=-1, descending=False, out=None):返回张量的排序结果。

3.1.4 三角函数

  • torch.sin(input, out=None):正弦
  • torch.cos(input, out=None):余弦
  • torch.tan(input, out=None):正切

3.2 降维函数

所谓降维,就是某个维度经过运算后返回值是一个张量。如果下述函数中的 dim 变量没有显式赋值,则对整个张量进行计算,返回一个值;若 dim 被显性赋值,则对该 dim 内的每组数据分别进行运算。keepdim 若为 True,每个运算结果为一个一维张量,实际上没有降维。

  • torch.argmax(input, dim, keepdim=False):返回张量内最大元素的索引。
  • torch.argmin(input, dim, keepdim=False, out=None):返回张量内最小元素的索引。

例子:

1
2
3
>>> a = torch.tensor([[1, 3, 2, 4], [9, 8, 7, 6]])
>>> torch.argmax(a, dim=1)
tensor([3, 0])
  • torch.max(input, dim, keepdim=False, out=None):返回在指定维度内进行比较后的最大值。
  • torch.min(input, dim, keepdim=False, out=None):返回在指定维度内进行比较后的最小值。
  • torch.mean(input, dim, keepdim=False, out=None):返回张量内张量的平均数。
  • torch.median(input, dim=-1, keepdim=False, out=None):返回张量内张量的中位数。
  • torch.prod(input, dim, keepdim=False, dtype=None):返回张量内元素的乘积。
  • torch.std(input, dim, unbiased=True, keepdim=False, out=None):返回张量内的标准差。
  • torch.sum(input, dim, keepdim=False, dtype=None):返回张量内元素的和。
  • torch.var(input, dim, keepdim=False, unbiased=True, out=None):返回张量内元素的方差。

例子:

1
2
3
4
5
6
7
8
9
10
>>> a = torch.ones((4, 3)) # 4 x 3 的全 1 矩阵
>>> torch.sum(a) # 没有维度,对所有元素求和
tensor(12.)
>>> torch.sum(a, dim=1)
tensor([3., 3., 3., 3.])
>>> torch.sum(a, dim=1, keepdim=True)
tensor([[3.],
[3.],
[3.],
[3.]])

3.3 比较函数

返回索引的函数:

  • torch.argsort(input, dim=-1, descending=False) 返回在指定维度中第几大/小索引的张量,默认升序比较最后一维:
    1
    2
    3
    4
    >>> a = torch.tensor([[1, 3, 2, 4], [9, 8, 7, 6]])
    >>> torch.argsort(a)
    tensor([[0, 2, 1, 3],
    [3, 2, 1, 0]])

既返回值,又返回索引的函数:

  • torch.sort(input, dim=-1, descending=False, out=None):对张量进行排序。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> x = torch.randn(3, 4)
    >>> sorted, indices = torch.sort(x)
    >>> sorted
    tensor([[-0.2162, 0.0608, 0.6719, 2.3332],
    [-0.5793, 0.0061, 0.6058, 0.9497],
    [-0.5071, 0.3343, 0.9553, 1.0960]])
    >>> indices
    tensor([[ 1, 0, 2, 3],
    [ 3, 1, 0, 2],
    [ 0, 3, 1, 2]])
  • torch.topk(input, k, dim=None, largest=True, sorted=True, out=None):返回最大/最小的 k 个值和它们的索引。
    1
    2
    3
    4
    5
    >>> x = torch.arange(1., 6.)
    >>> x
    tensor([ 1., 2., 3., 4., 5.])
    >>> torch.topk(x, 3)
    torch.return_types.topk(values=tensor([5., 4., 3.]), indices=tensor([4, 3, 2]))
  • torch.cummax(input, dim, out=None):值与索引为当前位置以前的最大值和最大值的索引。
  • torch.cummin(input, dim, out=None):值与索引为当前位置以前的最小值和最小值的索引。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    >>> a = torch.randn(10)
    >>> a
    tensor([-0.3449, -1.5447, 0.0685, -1.5104, -1.1706, 0.2259, 1.4696, -1.3284,
    1.9946, -0.8209])
    >>> torch.cummax(a, dim=0)
    torch.return_types.cummax(
    values=tensor([-0.3449, -0.3449, 0.0685, 0.0685, 0.0685, 0.2259, 1.4696, 1.4696,
    1.9946, 1.9946]),
    indices=tensor([0, 0, 2, 2, 2, 5, 6, 6, 8, 8]))

    >>> a = torch.randn(10)
    >>> a
    tensor([-0.2284, -0.6628, 0.0975, 0.2680, -1.3298, -0.4220, -0.3885, 1.1762,
    0.9165, 1.6684])
    >>> torch.cummin(a, dim=0)
    torch.return_types.cummin(
    values=tensor([-0.2284, -0.6628, -0.6628, -0.6628, -1.3298, -1.3298, -1.3298, -1.3298,
    -1.3298, -1.3298]),
    indices=tensor([0, 1, 1, 1, 4, 4, 4, 4, 4, 4]))

比较两个张量的元素,返回包含每个元素间比较的最大/小值:

  • torch.max(input, other, out=None)
  • torch.min(input, other, out=None)

这两个函数与上面的降维函数中的同名函数的区别在于上面的两个函数的输入是一个张量,这里是两个。

1
2
3
4
5
6
7
8
9
>>> a = torch.tensor([[1, 3, 96, 97], [98, 99, 7, 6]])
>>> b = torch.tensor([[100, 101, -1, -2], [-3, -4, 102, 103]])

>>> torch.max(a, b)
tensor([[100, 101, 96, 97],
[ 98, 99, 102, 103]])
>>> torch.min(a, b)
tensor([[ 1, 3, -1, -2],
[-3, -4, 7, 6]])

两个张量比较是否相同,返回一个布尔值:torch.equal(input, other)

1
2
>>> torch.equal(torch.tensor([1, 2]), torch.tensor([1, 2]))
True

两个张量的元素之间互相比较,每个比较返回一个布尔值,最终返回一个与被比较元素形状相同的张量:

  • torch.eq(input, other, out=None):如果 input 中的元素等于 output 中的对应元素,返回 True
  • torch.ge(input, other, out=None):如果 input 中的元素大于等于 output 中的对应元素,返回 True
  • torch.gt(input, other, out=None):如果 input 中的元素大于 output 中的对应元素,返回 True
  • torch.le(input, other, out=None):如果 input 中的元素小于等于 output 中的对应元素,返回 True
  • torch.lt(input, other, out=None):如果 input 中的元素小于 output 中的对应元素,返回 True
    1
    2
    3
    4
    5
    >>> a = torch.tensor([[1, 3, 96, 97], [98, 99, 7, 6]])
    >>> c = torch.tensor([[1, 3, 5, 7], [98, 99, 100, 101]])
    >>> torch.eq(a, c)
    tensor([[ True, True, False, False],
    [ True, True, False, False]])

4. 随机函数

所有随机函数都有一个 generator 变量用于指定随机种子。

  • torch.manual_seed(seed):设置随机种子。
  • torch.bernoulli(input, *, generator=None, out=None):生成服从伯努利分布(二项式分布)的张量。
    1
    2
    3
    4
    5
    6
    7
    >>> a = torch.empty(2, 2).uniform_(0, 1)
    >>> a
    tensor([[0.0117, 0.2281],
    [0.8750, 0.9974]])
    >>> torch.bernoulli(a)
    tensor([[0., 0.],
    [1., 1.]])
  • torch.multinomial(input, num_samples, replacement=False, *, generator=None, out=None):生成符合多项式分布的张量。input 为多项式分布的权重,当 replacementFalse 时,num_samples 的长度必须小于 input
    1
    2
    3
    >>> weights = torch.tensor([1., 2., 3., 4.])
    >>> torch.multinomial(weights, 10, replacement=True)
    tensor([1, 2, 2, 2, 3, 2, 2, 3, 0, 2])
  • torch.normal(mean, std, size, *, out=None):生成服从均值为 mean,方差为 std 的正态分布张量。meanstd 可以省略一个,若想同时省略请使用 torch.randn 函数。
    1
    2
    3
    >>> torch.normal(2, 1, [2, 2])
    tensor([[1.7697, 2.2627],
    [2.0743, 2.1683]])
  • torch.poisson(input *, generator=None):生成一个形状与 input 相同,服从泊松分布的张量。
    1
    2
    >>> torch.poisson(torch.tensor([2., 2.]))
    tensor([1., 4.])
  • torch.rand(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False):生成一个范围为 $[0,1)$ 的均匀分布的张量。
    1
    2
    3
    >>> torch.rand((2, 2))
    tensor([[0.2255, 0.5614],
    [0.7037, 0.2410]])
  • torch.randn(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False):生成一个均值为 0,方差为 1 的标准正态分布的张量。
    1
    2
    3
    >>> torch.randn((2, 2))
    tensor([[ 1.2622, -1.3420],
    [-0.2331, 0.6151]])
  • torch.randint(low=0, high, size, *, generator=None, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False):生成一个范围为 $[low, high)$ 内取整数的均匀分布的张量。
    1
    2
    3
    >>> torch.randint(10, (2, 2))
    tensor([[6, 2],
    [2, 3]])
  • torch.randperm(n, out=None, dtype=torch.int64, layout=torch.strided, device=None, requires_grad=False):返回一个经过随机打乱顺序的张量。
    1
    2
    >>> torch.randperm(10)
    tensor([8, 9, 5, 3, 2, 1, 0, 7, 4, 6])

欢迎关注我的其它发布渠道