每门语言都少不了加减乘除等数学运算,Pytorch 作为一个开源的机器学习库,除了这些基本的数学运算,还涉及到矩阵运算、三角函数、傅立叶变换等等。

对于我们来说,先从最简单的、常用的数学运算入手,主要是学习其 api 的使用,尤其是对于一些复杂的计算。有时间的话,去了解一下其背后的数学原理会更好。

1. 加减乘除

加法:torch.add(inputother,  * , alpha=1out=None) → [Tensor]

方法释义:将 other 与 alpha 的乘积加到 intput 上,如下公式

out =input + alpha×other

也可以直接使用运算符:+

参数:

  • input ([Tensor] – 输入的张量
  • other ([Tensor] or Number) – 要加到 input 上的张量或数值
  • alpha (Number) – 与 other 相乘的乘数
  • out ([Tensor], optional) – 输出的张量

示例:

a = torch.randn(4)
print(a)
b = torch.add(a, 20)
print(b)
c = torch.randn(4, 1)
print(c)
print(c * 10)
print(torch.add(b, c, alpha=10))  # 对于每个 b 来说,可扩展为 [4,4],然后 c 也可以扩展成 [4, 4], 再进行相加

# 输出结果
tensor([ 0.9834, -0.0915,  0.0711,  0.4074])
tensor([20.9834, 19.9085, 20.0711, 20.4074])
tensor([[-0.3610],
        [-1.0335],
        [-0.5380],
        [-0.2910]])
tensor([[ -3.6098],
        [-10.3351],
        [ -5.3804],
        [ -2.9098]])
tensor([[17.3736, 16.2987, 16.4613, 16.7976],
        [10.6483,  9.5734,  9.7360, 10.0723],
        [15.6030, 14.5281, 14.6907, 15.0270],
        [18.0736, 16.9987, 17.1613, 17.4976]])

减法:-

相同位置的元素相减

示例:

a = torch.ones(2, 2)
print(a)
b = torch.ones(1, 2)
print(b)
print(a - b)

# 输出结果
tensor([[1., 1.],
        [1., 1.]])
tensor([[1., 1.]])
tensor([[0., 0.],
        [0., 0.]])
乘法:torch.mul(inputother,  *** , out=None) → [Tensor]

方法释义:out =input × other,相同位置元素相乘

也可以直接使用运算符:*

示例:

a = torch.randn(2, 2)
print(a)
b = torch.tensor([[1, 2], [2, 3]])
print(b)
print(a * b)

# 输出结果
tensor([[ 0.1792, -0.1735],
        [-0.8009, -1.3489]])
tensor([[1, 2],
        [2, 3]])
tensor([[ 0.1792, -0.3470],
        [-1.6019, -4.0468]])
除法:torch.div(inputother,  *** , rounding_mode=Noneout=None) → [Tensor]

方法释义:相同位置内的元素进行相除

参数:

  • input ([Tensor] – the dividend
  • other ([Tensor] – the divisor
  • rounding_mode ([str] , optional) – 默认是 None,与运算符 / 一样; ‘trunc’ 则是取整;'floor’则是对除以b的结果向负无穷方向取整后的数, 与 python 的 // 运算符一样。

示例:

x = torch.tensor([0.3810,  1.2774, -0.2972, -0.3719])
y = torch.div(x, 0.5)
print(y)  # 相当于每个结果乘以 2
z = torch.randn(4, 4)
print(torch.div(y, z))
print(torch.div(y, z, rounding_mode='trunc'))  # 取整
print(torch.div(y, z, rounding_mode='floor'))  # 结果向负无穷方向取整

2. 矩阵相乘

torch.mm(inputmat2,  *** , out=None) → [Tensor]

方法释义:n 行 m 列的矩阵与 m 行 q 列的矩阵相乘,得到 n 行 q 列;只适合于 2 维矩阵相乘,不支持扩展。符合数学意义的矩阵乘积,如 矩阵 A 行向量的与矩阵 B 列向量乘积和,得到一个新的矩阵

示例:

x = torch.tensor([[1, 2], [3, 4]])
print(x)
y = torch.tensor([[2, 1, 1], [2, 1, 1]])
print(y)
print(torch.mm(x, y))

# 输出结果
tensor([[1, 2],
        [3, 4]])
tensor([[2, 1, 1],
        [2, 1, 1]])
tensor([[ 6,  3,  3],
        [14,  7,  7]])
torch.matmul(inputother,  *** , out=None) → [Tensor]

方法释义:多维矩阵相乘
两个张量的矩阵乘积。

行为取决于张量的维数,如下所示:

  • 如果两个张量都是一维的,则返回点积(标量)。

  • 如果两个参数都是二维的,则返回矩阵-矩阵乘积。

  • 如果第一个参数是一维的,第二个参数是二维的,则为了矩阵乘法的目的,在其维度前加上 1。矩阵相乘后,删除前置维度。

  • 如果第一个参数是二维的,第二个参数是一维的,则返回矩阵向量乘积。

  • 如果两个参数至少是一维的并且至少一个参数是 N 维的(其中 N > 2),则返回批处理矩阵乘法。如果第一个参数是一维的,则为了批处理矩阵乘法的目的,将 1 添加到其维度之前并在之后删除。如果第二个参数是一维的,则将 1 附加到其维度以用于批处理矩阵倍数并在之后删除。非矩阵(即批次)维度被[广播](因此必须是可广播的)。例如,如果input是一个 (j×1×n×n)张量,并且other是(k×n×n) 张量,out将是(j×k×n×n)张量。

    请注意,广播逻辑在确定输入是否可广播时仅查看批次维度,而不是矩阵维度。例如,如果input是一个(j×1×n×n)张量并且other是(k×m×p)张量,即使最后两个维度(即矩阵维度)不同,这些输入对于广播也是有效的。out将是一个(j×k×n×p )张量。

示例:

# vector x vector
tensor1 = torch.randn(3)
tensor2 = torch.randn(3)
torch.matmul(tensor1, tensor2).size()
# 输出结果
torch.Size([])

# matrix x vector
tensor1 = torch.randn(3, 4)
tensor2 = torch.randn(4)
torch.matmul(tensor1, tensor2).size()
# 输出结果
torch.Size([3])

# batched matrix x broadcasted vector
tensor1 = torch.randn(10, 3, 4)
tensor2 = torch.randn(4)
torch.matmul(tensor1, tensor2).size()
# 输出结果
torch.Size([10, 3])

# batched matrix x batched matrix
tensor1 = torch.randn(10, 3, 4)
tensor2 = torch.randn(10, 4, 5)
torch.matmul(tensor1, tensor2).size()
# 输出结果
torch.Size([10, 3, 5])

# batched matrix x broadcasted matrix
tensor1 = torch.randn(10, 3, 4)
tensor2 = torch.randn(4, 5)
torch.matmul(tensor1, tensor2).size()
# 输出结果
torch.Size([10, 3, 5])

3. 平方、平方根、平方根倒数、指数、底数

这些都是比较容易理解的运算了,直接看示例:

a = torch.full([2, 2], 3)
b = torch.pow(a, 2)    # 平方
print(b)
print(a ** 2)          # 平方
c = torch.sqrt(b)      # 平方根
print(c)
d = torch.rsqrt(b)     # 平方根倒数
print(d)
e = torch.log(d)       # log 底数
print(e)
x = torch.ones(2, 2)
f = torch.exp(x)    # 指数
print(f)

# 输出结果
tensor([[9, 9],
        [9, 9]])
tensor([[9, 9],
        [9, 9]])
tensor([[3., 3.],
        [3., 3.]])
tensor([[0.3333, 0.3333],
        [0.3333, 0.3333]])
tensor([[-1.0986, -1.0986],
        [-1.0986, -1.0986]])
tensor([[2.7183, 2.7183],
        [2.7183, 2.7183]])

4. 求解近似值的一些方法

floor:向下取整

ceil: 向上取整

round: 四舍五入

trunc: 取整数部分

frac: 取小数部分

示例:

a = torch.tensor(3.14)
print(torch.floor(a))
print(torch.ceil(a))
print(torch.round(a))
print(torch.trunc(a))
print(torch.frac(a))

# 输出结果
tensor(3.)
tensor(4.)
tensor(3.)
tensor(3.)
tensor(0.1400)

5. torch.clamp(inputmin=Nonemax=None,  *** , out=None) → [Tensor]

方法释义:将 input 张量中的所有元素,限定在 min ~ max 的范围内,小于 min 的则替换成 min ,大于 max 则替换成 max,如果 min 不传表示无下界,max 不传则表示无上界。

示例:

a = torch.rand(2, 3) * 15
print(a)
print(a.max())        # 最大
print(a.median())     # 最小
print(a.clamp(10))    # 是小值为 10 ,小于 10 的,都替换成 10
print(a.clamp(0, 10)) # 最小值为 0 , 最大值为 10 ,超过 10 的都替换成 10

# 输出结果
tensor([[ 1.9528,  7.5773,  1.5717],
        [ 1.7198, 12.2121,  8.1626]])
tensor(12.2121)
tensor(1.9528)
tensor([[10.0000, 10.0000, 10.0000],
        [10.0000, 12.2121, 10.0000]])
tensor([[ 1.9528,  7.5773,  1.5717],
        [ 1.7198, 10.0000,  8.1626]])

总结:数学运算比较难的,主要是多维度矩阵乘积的理解吧,这块需要了解其背后的一些数学意义,多写下代码,观察领悟。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐