【youcans的深度学习 09】PyTorch入门教程:张量的逐点运算

欢迎关注『youcans的深度学习』系列,持续更新中…
【youcans的深度学习 01】安装环境之 miniconda
【youcans的深度学习 02】PyTorch CPU版本安装与环境配置
【youcans的深度学习 03】PyTorch CPU版本安装与环境配置
【youcans的深度学习 04】PyTorch入门教程:基础知识
【youcans的深度学习 05】PyTorch入门教程:快速入门
【youcans的深度学习 06】PyTorch入门教程:张量的基本操作 1
【youcans的深度学习 07】PyTorch入门教程:张量的基本操作 2
【youcans的深度学习 08】PyTorch入门教程:张量的就地操作和广播机制
【youcans的深度学习 09】PyTorch入门教程:张量的逐点运算

PyTorch 中支持 100 多种张量操作,包括转置、索引、切⽚、数学运算、线性代数、随机数等等,详见【PyTorch官方文档】

2. 张量的逐点运算

逐点运算(Pointwise Ops),是指针对张量的每个元素分别执行相同的运算操作。

逐点运算包括数学基本运算、数据调整运算和数据科学运算三类。数学基本运算包括:加法(add)、减法()、乘法(mul)和除法(div)。数值调整运算主要包括:绝对值(abs)、向上取整(ceil)、向下取整(floor)、四舍五入取整(round)、负值(neg)等。数据科学运算主要包括:幂运算、对数运算、三角函数运算、位运算、激活函数运算,等等。

本节介绍常用的张量逐点运算。

2.1 加法运算 add

同一种操作可能有很多种方法。

加法运算可以用加号 +或函数 torch.add() 实现。

函数原型:

torch.add(input, other, *, alpha=1, out=None) → Tensor

扫描二维码关注公众号,回复: 15161945 查看本文章

运算公式:

o u t i = i n p u t i + a l p h a ∗ o t h e r i out_i = input_i + alpha * other_i outi=inputi+alphaotheri

参数说明:

  • input,张量,输入值
  • other,张量或数值,与 input 相加
  • alpha,数值,加权系数
  • out,张量,输出值,可选项

函数说明:

(1)函数 torch.add() 支持广播机制(broadcasting)和类型提升(type promotion)。

例程如下。

# (3) 张量的加法运算
# 一维张量
x = torch.arange(6)
y = torch.arange(6)
# 二维张量
# x = torch.rand(4, 3)
# y = torch.rand(4, 3)

# 加法形式 1: 加号
z1 = x + y
print(z1)

# 加法形式 2: torch.add()
z2 = torch.add(x, y)
print(z2)

# 加法形式 3: 指定输出变量
z3 = torch.empty(x.shape)
torch.add(x, y, out=z3)
print(z3)

# 加法形式 4: 张量与数值的加法
z4 = torch.add(x, 10)
print(z4)

# 加法形式 5: 加权相加
z5 = torch.add(x, y, alpha=2)
print(z5)

# 加法形式 6: 就地操作
y.add_(x)  # y = y + x
print(y)  # y 的值已经改变

# 加法形式 7: 相加数组形状不同时触发广播机制
x = torch.rand(1, 3, 1, 6)
y = torch.rand(3, 3, 1)
z = x + y
print(x.shape, y.shape, z.shape)

输出结果如下。

tensor([ 0, 2, 4, 6, 8, 10])
tensor([ 0, 2, 4, 6, 8, 10])
tensor([ 0., 2., 4., 6., 8., 10.])
tensor([10, 11, 12, 13, 14, 15])
tensor([ 0, 3, 6, 9, 12, 15])
tensor([ 0, 2, 4, 6, 8, 10])
torch.Size([1, 3, 1, 6]) torch.Size([3, 3, 1]) torch.Size([1, 3, 3, 6])

说明:

(1)自动赋值运算在函数后添加 _ 后缀来表示,将方法调用执行的结果重新赋值给调用方法。例如,tensor.add_(x) 操作会改变 tensor 本身的值。

(2)如果加法运算的两个数组的形状不同, 就会触发广播机制,结果的形状是 A.shape 和 B.shape 对应位置的最大值,比如:A.shape=(1,3,2),B.shape=(6,1,2),则 A+B 的 shape 是 (6,3,2)。


2.2 减法运算 sub

减法运算可以用减号 -或函数 torch.sub() 实现。

函数原型:

torch.sub(input, other, *, alpha=1, out=None) → Tensor

运算公式:
o u t i = i n p u t i − a l p h a ∗ o t h e r i out_i = input_i - alpha * other_i outi=inputialphaotheri

参数说明:

  • input,张量,输入值
  • other,张量或数值,与 input 相减
  • alpha,数值,加权系数
  • out,张量,输出值,可选项

函数说明:

(1)减法函数 torch.subtract(),可以简写为 torch.sub()。
(2)函数 torch.sub() 支持广播机制(broadcasting)和类型提升(type promotion)。

# (4) 张量的减法运算
# 一维张量
x = torch.arange(6) * 5
y = torch.arange(6)
# 二维张量
# x = torch.rand(4, 3)
# y = torch.rand(4, 3)

# 减法形式 1: 减号
z1 = x - y
print(z1)

# 减法形式 2: torch.sub()
z2 = torch.sub(x, y)
print(z2)

# 减法形式 3: 指定输出变量
z3 = torch.empty(x.shape)
torch.sub(x, y, out=z3)
print(z3)

# 减法形式 4: 张量与数值的减法
z4 = torch.sub(x, 10)
print(z4)

# 减法形式 5: 加权相减
z5 = torch.add(x, y, alpha=2)
print(z5)

# 减法形式 6: 相减数组形状不同时触发广播机制
x = torch.rand(1, 3, 2)
y = torch.rand(6, 1, 2)
z = torch.sub(x, y)
print(x.shape, y.shape, z.shape)

输出如下。

tensor([ 0, 4, 8, 12, 16, 20])
tensor([ 0, 4, 8, 12, 16, 20])
tensor([ 0., 4., 8., 12., 16., 20.])
tensor([-10, -5, 0, 5, 10, 15])
tensor([ 0, 7, 14, 21, 28, 35])
torch.Size([1, 3, 1, 6]) torch.Size([3, 3, 1]) torch.Size([1, 3, 3, 6])


2.3 点乘运算 mul

张量的乘法运算比较复杂,首先讨论点乘,指逐个元素相乘。

使用乘号 *或函数 torch.mul() 实现点乘操作。

函数原型:

torch.mul(input, other, *, out=None) → Tensor

运算公式:

点乘是逐个元素相乘。
o u t i = i n p u t i ∗ o t h e r i out_i = input_i * other_i outi=inputiotheri

参数说明:

  • input,张量,输入值,支持整型、浮点型和复数类型
  • other,张量或数值,与 input 相乘
  • out,张量,输出值,可选项

函数说明:

(1)乘法函数 torch.multiply(),可以简写为 torch.mul()。
(2)函数 torch.mul() 支持广播机制(broadcasting)和类型提升(type promotion)。
(3)如果两个参数inputother的形状不同,将会应用广播机制处理。
(4)函数 torch.mul() 的两个参数 inputother的位置可以互换,不影响运算结果。

# (5) 张量的点乘运算
# 一维张量
x = torch.arange(6) * 3
y = torch.arange(6)
# 二维张量
# x = torch.rand(4, 3)
# y = torch.rand(4, 3)

# 点乘形式 1: 乘号
z1 = x * y
print(z1)

# 点乘形式 2: torch.mul()
z2 = torch.sub(x, y)
print(z2)

# 点乘形式 3: 指定输出变量
z3 = torch.empty(x.shape)
torch.mul(x, y, out=z3)
print(z3)

# 点乘形式 4: 张量与数值的点乘
z4 = torch.mul(x, 10)
print(z4)

# 点乘形式 5: 行向量与列向量点乘得到矩阵制
x = torch.arange(4).reshape(4, 1)  # torch.Size([4, 1])
y = torch.arange(4).reshape(1, 4)  # torch.Size([1, 4])
print(x)
print(y)
z = torch.mul(x, y)  # [4,1] * [1,4] -> [4,4]
print(x.shape, y.shape, z.shape)
print(z)
z = torch.mul(y, x)  # [1,4] * [4,1] -> [4,4]
print(x.shape, y.shape, z.shape)
print(z)

输出如下。

tensor([ 0, 3, 12, 27, 48, 75])
tensor([ 0, 2, 4, 6, 8, 10])
tensor([ 0., 3., 12., 27., 48., 75.])
tensor([ 0, 30, 60, 90, 120, 150])
tensor([[0],
[1],
[2],
[3]])
tensor([[0, 1, 2, 3]])
torch.Size([4, 1]) torch.Size([1, 4]) torch.Size([4, 4])
tensor([[0, 0, 0, 0],
[0, 1, 2, 3],
[0, 2, 4, 6],
[0, 3, 6, 9]])
torch.Size([4, 1]) torch.Size([1, 4]) torch.Size([4, 4])
tensor([[0, 0, 0, 0],
[0, 1, 2, 3],
[0, 2, 4, 6],
[0, 3, 6, 9]])


2.4 除法运算 div

函数 torch.div() 实现张量的除法,对逐个元素相除。

函数原型:

torch.div(input, other, *, rounding_mode=None, out=None) → Tensor

运算公式:

将 input 的每个元素除以 other 的对应元素。
o u t i = i n p u t i / o t h e r i out_i = input_i / other_i outi=inputi/otheri

参数说明:

  • input,张量,被除数,支持整型、浮点型和复数类型。
  • other,张量或数值,除数。
  • out,张量,输出值,可选项。
  • rounding_mode,结果舍入方式,字符串,可选项。
    • None,默认选项,不进行舍入处理,相当于 Python 中的真除法(/运算符);
    • “trunc”,对除法结果向零取整,相当于 C型整数除法;
    • “floor”,对除法结果向下取整,相当于 Python 中的 //运算符。

函数说明:

(1)除法函数 torch.divide(),可以简写为 torch.div()。
(2)函数 torch.div() 支持广播机制(broadcasting)和类型提升(type promotion)。

# (6) 张量的除法运算
# 一维张量
x = torch.arange(6) * 3
y = torch.rand(6)
# 二维张量
# x = torch.rand(2, 3)
# y = torch.rand(2, 3)

# 除法形式 1: 除号
z1 = x / y
print(z1)

# 除法形式 2: torch.div()
z2 = torch.div(x, y)

# 除法形式 3: 指定输出变量
z3 = torch.empty(x.shape)
torch.div(x, y, out=z3)
print(z3)

# 除法形式 4: 舍入模式
z4 = torch.div(x, y, rounding_mode='trunc')
z5 = torch.div(x, y, rounding_mode='floor')
print("div-trunc: ", z4)
print("div-floor: ", z5)

# 除法形式 5: 张量与数值的除法
z6 = torch.mul(x, 10)
print(z6)

输出如下。

tensor([ 0.0000, 5.6767, 11.3654, 13.5191, 17.5318, 422.5318])
tensor([ 0.0000, 5.6767, 11.3654, 13.5191, 17.5318, 422.5318])
div-trunc: tensor([ 0., 5., 11., 13., 17., 422.])
div-floor: tensor([ 0., 5., 11., 13., 17., 422.])
tensor([ 0, 30, 60, 90, 120, 150])


2.5 数值调整运算

数值调整运算主要包括:绝对值(abs)、向上取整(ceil)、向下取整(floor)、四舍五入取整(round)、负值(neg)、倒数(reciprocal)等。

函数原型:

torch.abs(input, *, out=None) → Tensor # 绝对值
torch.ceil(input, *, out=None) → Tensor # 向上取整
torch.floor(input, *, out=None) → Tensor # 向下取整
torch.round(input, *, out=None) → Tensor # 四舍五入取整
torch.neg(input, *, out=None) → Tensor # 负值>
torch.reciprocal(input, *, out=None) → Tensor

参数说明:

  • input,张量,输入张量。
  • out,张量,输出张量,可选项。
# (7) 数值调整运算
# 绝对值(abs), 向上取整(ceil), 向下取整(floor), 四舍五入取整(round), 负值(neg), 倒数(reciprocal),
x = torch.rand(5) * 10 - 5
print("x=", x)
print("abs(x)=", torch.abs(x))  # 绝对值(abs)
print("ceil(x)=", torch.ceil(x))  # 向上取整(ceil)
print("floor(x)=", torch.floor(x))  # 向下取整(floor)
print("round(x)=", torch.round(x))  # 四舍五入取整(round)
print("neg(x)=", torch.neg(x))  # 负值(neg)
print("reciprocal(x)=", torch.reciprocal(x))  # 倒数(reciprocal)

结果如下:

x= tensor([ 1.6213, -0.2243, 0.4383, 2.7358, 1.7811])
abs(x)= tensor([1.6213, 0.2243, 0.4383, 2.7358, 1.7811])
ceil(x)= tensor([2., -0., 1., 3., 2.])
floor(x)= tensor([ 1., -1., 0., 2., 1.])
round(x)= tensor([2., -0., 0., 3., 2.])
neg(x)= tensor([-1.6213, 0.2243, -0.4383, -2.7358, -1.7811])
reciprocal(x)= tensor([ 0.6168, -4.4592, 2.2818, 0.3655, 0.5614])


2.6 幂运算和指数运算

函数 torch.pow() 对输入张量中的每个元素做幂运算。

函数原型:

torch.pow(input, exponent , *, out=None) → Tensor

运算公式:
指数可以是单个浮点数,也可以是具有与 input 相同形状的张量。
o u t i = i n p u t i e x p o n e n t i out_i = input_i ^{ exponent_i} outi=inputiexponenti

参数说明:

  • input,张量,输入张量。
  • exponent,张量或浮点数,指数值。
  • out,张量,输出张量,可选项。

函数 torch.exp() 对输入张量中的每个元素做指数运算。

函数原型:

torch.exp(input, *, out=None) → Tensor

参数说明:

  • input,张量,输入张量。
  • out,张量,输出张量,可选项。
# (8) 张量的幂运算和指数运算
# 幂运算,指数为标量数值
x = torch.randn(5)
xpow = torch.pow(x, 2)
print("x:", x)
print("xpow:", xpow)

# 幂运算,指数为张量,形状与 input 相同
y = torch.arange(1, 5)
e = torch.arange(4)
ypow = torch.pow(y, e)
print("y:", y)
print("e:", e)
print("pow(y,e):", ypow)

# 指数运算
y = torch.arange(5)
yexp = torch.exp(y)
print("exp(y):", yexp)
ylog = torch.log(y)
print("log(y):", ylog)
z = torch.exp(ylog)
print("exp(log(y)):", z)

结果如下。

x: tensor([ 1.1022, -0.2657, 1.6947, -0.2483, -1.4242])
xpow: tensor([1.2148, 0.0706, 2.8721, 0.0616, 2.0285])

y: tensor([1, 2, 3, 4])
e: tensor([0, 1, 2, 3])
pow(y,e): tensor([ 1, 2, 9, 64])

exp(y): tensor([ 1.0000, 2.7183, 7.3891, 20.0855, 54.5981])
log(y): tensor([ -inf, 0.0000, 0.6931, 1.0986, 1.3863])
exp(log(y)): tensor([0., 1., 2., 3., 4.])


2.7 对数运算

函数 torch.log 对输入张量中的每个元素做以 e 为底的对数运算,函数 torch.log2 进行以 2 为底的对数运算,函数 torch.log10 进行以 10 为底的对数运算。

函数原型:

torch.log(input, *, out=None) → Tensor
torch.log2(input, *, out=None) → Tensor
torch.log10(input, *, out=None) → Tensor

参数说明:

  • input,张量,输入张量。
  • out,张量,输出张量,可选项。
# (9) 张量的对数运算
x = torch.arange(5) * 10
print("x:", x)

xloge = torch.log(x)  # 自然对数
print("ln(x):", xloge)
xlog2 = torch.log(x)  # 以2为底的对数
print("log2(x):", xlog2)
xlog10 = torch.log(x)  # 以10为底的对数
print("log10(x):", xlog10)

z = torch.exp(xloge)
print("exp(ln(x)):", z)

结果如下。

x: tensor([ 0, 10, 20, 30, 40])
ln(x): tensor([ -inf, 2.3026, 2.9957, 3.4012, 3.6889])
log2(x): tensor([ -inf, 2.3026, 2.9957, 3.4012, 3.6889])
log10(x): tensor([ -inf, 2.3026, 2.9957, 3.4012, 3.6889])
exp(ln(x)): tensor([ 0.0000, 10.0000, 20.0000, 30.0000, 40.0000])


2.8 三角函数运算

常用的三角函数如下。

函数原型:

torch.sin(input, *, out=None) → Tensor # 正弦函数
torch.cos(input, *, out=None) → Tensor # 余弦函数
torch.tan(input, *, out=None) → Tensor # 正切函数
torch.asin(input, *, out=None) → Tensor # 反正弦函数
torch.acos(input, *, out=None) → Tensor # 反余弦函数
torch.atan(input, *, out=None) → Tensor # 反正切函数
torch.atan2(input, other, *, out=None) → Tensor # 反正切函数
torch.tanh(input, *, out=None) → Tensor # 双曲正切函数

参数说明:

  • input,张量,输入张量。
  • out,张量,输出张量,可选项。

函数说明:
一般来说,张量的三角函数就是对输入张量逐点计算三角函数,返回输出张量。
特殊的,函数 torch.atan2(input, other) 逐点计算 i n p u t i / o t h e r i input_i/other_i inputi/otheri 的反正切函数。

# (10) 张量的三角函数运算
x = torch.rand(4)
print("x:", x)

print("sin(x)", torch.sin(x))  # 正弦函数
print("cos(x)", torch.cos(x))  # 余弦函数
print("tan(x)", torch.tan(x))  # 正切函数
print("asin(x)", torch.asin(x))  # 反正弦函数
print("acos(x)", torch.acos(x))  # 反余弦函数
print("atan(x)", torch.atan(x))  # 反正切函数
print("atan2(x)", torch.atan2(x, x))  # 反正切函数2
print("tanh(x)", torch.tanh(x))  # 双曲正切函数

结果如下。

x: tensor([0.0411, 0.6685, 0.8194, 0.1078])
sin(x) tensor([0.0411, 0.6198, 0.7307, 0.1076])
cos(x) tensor([0.9992, 0.7848, 0.6827, 0.9942])
tan(x) tensor([0.0411, 0.7897, 1.0703, 0.1082])
asin(x) tensor([0.0411, 0.7321, 0.9603, 0.1080])
acos(x) tensor([1.5297, 0.8387, 0.6105, 1.4628])
atan(x) tensor([0.0411, 0.5892, 0.6864, 0.1074])
atan2(x) tensor([0.7854, 0.7854, 0.7854, 0.7854])
tanh(x) tensor([0.0411, 0.5840, 0.6747, 0.1074])


2.9 位运算

PyTorch 提供了位操作函数 torch.bitwise,包括与操作、或操作、非操作、异或操作、向左移位和向右移位。

函数原型:

torch.bitwise_not(input, *, out=None) → Tensor # 逻辑非
torch.bitwise_and(input, *, out=None) → Tensor # 逻辑与
torch.bitwise_or(input, *, out=None) → Tensor # 逻辑或
torch.bitwise_xor(input, *, out=None) → Tensor # 逻辑异或
torch.bitwise_left_shift(input, other, *, out=None) → Tensor # 向左移位
torch.bitwise_right_shift(input, other, *, out=None) → Tensor # 向右移位

参数说明:

  • input,张量,输入张量。
  • other,张量或标量,移位的位数。
  • out,张量,输出张量,可选项。

函数说明:
函数 torch.bitwise_left_shift(input, other) 对张量 input 向左移动 other 位,torch.bitwise_right_shift(input, other) 对张量 input 向右移动 other 位。other 是标量时,逐点左/右移的位数相同;other 是张量时,则张量 input_i 左/右移 other_i 位。

例程如下。

# (10) 张量的按位运算(逻辑运算)
x = torch.arange(4, dtype=torch.int8)
y = torch.ones(4, dtype=torch.int8)
print("x:", x)

x_not = torch.bitwise_not(x)  # 逻辑非, 按位取反
print("not(x):", x_not)
x_and = torch.bitwise_and(x, y)  # 逻辑与, 按位与
print("and(x, y):", x_and)
x_or = torch.bitwise_or(x, y)  # 逻辑或, 按位或
print("or(x, y):", x_or)
x_xor = torch.bitwise_xor(x, y)  # 逻辑异或, 按位异或
print("xor(x, y):", x_xor)
x_Lshift_2 = torch.bitwise_left_shift(x, 2)  # 左移2位
print("left_shift(x, 2):", x_Lshift_2)
x_Rshift_1 = torch.bitwise_right_shift(x, 2)  # 右移1位
print("right_shift(x, 1):", x_Rshift_1)

结果如下。

x: tensor([0, 1, 2, 3], dtype=torch.int8)
not(x): tensor([-1, -2, -3, -4], dtype=torch.int8)
and(x, y): tensor([0, 1, 0, 1], dtype=torch.int8)
or(x, y): tensor([1, 1, 3, 3], dtype=torch.int8)
xor(x, y): tensor([1, 0, 3, 2], dtype=torch.int8)
left_shift(x, 2): tensor([ 0, 4, 8, 12], dtype=torch.int8)
right_shift(x, 1): tensor([0, 0, 0, 0], dtype=torch.int8)


**【本节完】**

版权声明:
欢迎关注『youcans的深度学习』系列,转发请注明原文链接:
【youcans的深度学习 09】PyTorch入门教程:张量的逐点运算(https://youcans.blog.csdn.net/article/details/130654793)
Copyright 2023 youcans, XUPT
Crated:2023-05-16

猜你喜欢

转载自blog.csdn.net/youcans/article/details/130654793