目录
张量计算 张量的计算内容主要包括:张量之间的大小比较,张量的基本运算,如元素之间的运算和矩阵之间的运算等,张量与统计相关的运算,如排序,最大值,最小值,最大值的位置等内容。
2.1 比较大小
对于torch.allclose()函数,比较的是两个元素是否接近,比较A和B是否接近的公式为: ∣A − B∣<= atol + rtol ×∣B∣
-
import torch
-
-
# 比较两个数是否接近
-
A = torch.tensor([
10.0])
-
B = torch.tensor([
10.1])
-
torch.allclose(A,B,rtol=
1e-05,atol=
1e-08,equal_nan=
False)
-
torch.allclose(A, B, rtol=
0.1, atol=
0.01, equal_nan=
False)
-
# 在不同的判断条件下,得出的结果也是不同的
-
-
# 如果equal_nan=True,那么缺失值可以判断为接近
-
A = torch.tensor(
float(
"nan"))
-
print(torch.allclose(A, A, equal_nan=
False))
-
print(torch.allclose(A, A, equal_nan=
True))
-
-
-
A = torch.tensor([
1,
2,
3,
4,
5,
6])
-
B = torch.arange(
1,
7)
-
C = torch.unsqueeze(B, dim=
0)
-
# torch.eq()函数用来判断两个元素是否相等
-
print(torch.eq(A, B))
-
print(torch.eq(A, C))
-
# torch.equal()函数可以判断两个张量是否具有相同的形状和元素
-
print(torch.equal(A, B))
-
print(torch.equal(A, C))
-
-
# torch.ge()函数是逐元素比较是否大于等于(>=)
-
print(torch.ge(A, B))
-
print(torch.ge(A, C))
-
# torch.gt()函数是逐元素比较大于
-
print(torch.gt(A, B))
-
print(torch.gt(A, C))
-
# torch.le()函数是逐元素比较是否小于等于(<=)
-
print(torch.le(A, B))
-
print(torch.le(A, C))
-
# torch.lt()函数是逐元素比较大于
-
print(torch.lt(A, B))
-
print(torch.lt(A, C))
-
# torch.ne()函数是逐元素比较不等于
-
print(torch.ne(A, B))
-
print(torch.ne(A, C))
-
# torch.isnan()函数用来判断是否为缺失值
-
# 缺失值是值:NULL,也包括表示数值确实的特殊数值(如,在系统中用-999来表示的数值不存在)
-
print(torch.isnan(torch.tensor([
0,
1,
float(
"nan"),
2])))
输出:
False True tensor([True, True, True, True, True, True]) tensor([[True, True, True, True, True, True]]) True False tensor([True, True, True, True, True, True]) tensor([[True, True, True, True, True, True]]) 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([False, False, False, False, False, False]) tensor([[False, False, False, False, False, False]]) tensor([False, False, False, False, False, False]) tensor([[False, False, False, False, False, False]]) tensor([False, False, True, False])
2.2基本运算
-
# 矩阵逐元素相乘
-
a = torch.arange(
6.0).reshape(
2,
3)
-
b = torch.linspace(
10,
20, steps=
6).reshape(
2,
3)
-
print(
"a", a)
-
print(
"b", b)
-
print(a * b)
-
# 逐元素相除
-
print(a / b)
-
# 逐元素相加
-
print(a + b)
-
# 逐元素相减
-
print(a - b)
-
# 逐元素整除
-
print(b // a)
-
# 计算张量的幂可以使用torch.pow()函数,或者使用**
-
print(torch.
pow(a,
3))
-
print(a **
3)
-
# 计算张量的指数可以使用torch.exp()函数
-
print(torch.exp(a))
-
# 计算张量的对数可以使用torch.log()函数
-
print(torch.log(a))
-
# 计算张量的平方根可以使用torch.sqrt()函数
-
print(torch.sqrt(a))
-
print(a **
0.5)
-
# 计算张量的平方根倒数可以使用torch.rsqrt()函数
-
print(torch.rsqrt(a))
-
print(
1 / (a**
0.5))
-
-
# 对张量的数据裁剪,有根据最大值裁剪torch.clamp_max()函数
-
# 将大于x的数值都替换为x
-
print(a,
"\n", torch.clamp_max(a,
4))
-
# 有根据最小值裁剪torch.clamp_min()函数
-
# 将小于x的数值都替换为x
-
print(torch.clamp_min(a,
3))
-
# 有根据范围裁剪torch.clamp()函数
-
# 按照范围剪裁张量,小于边界的数值都替换为下界值,大于上界的数值都替换为上界
-
print(torch.clamp(a,
2.5,
4))
-
-
# torch.t()计算矩阵的转置
-
c = torch.t(a)
-
print(c)
-
# torch.matmul()输出两个矩阵的乘积
-
print(a.matmul(c))
-
# 矩阵相乘只计算最后面的两个维度的乘法
-
a = torch.arange(
12.0).reshape(
2,
2,
3)
-
b = torch.arange(
12.0).reshape(
2,
3,
2)
-
print(a, b)
-
ab = torch.matmul(a, b)
-
print(ab)
-
print(ab[
0].eq(torch.matmul(a[
0], b[
0])))
-
print(ab[
0].eq(torch.matmul(a[
1], b[
0])))
-
-
# 计算矩阵的逆
-
c = torch.rand(
3,
3)
-
d = torch.inverse(c)
-
print(torch.mm(c, d))
-
-
# 计算张量矩阵的迹,对角线元素的和
-
print(torch.trace(torch.arange(
9.0).reshape(
3,
3)))
a tensor([[0., 1., 2.], [3., 4., 5.]]) b tensor([[10., 12., 14.], [16., 18., 20.]]) tensor([[ 0., 12., 28.], [ 48., 72., 100.]]) tensor([[0.0000, 0.0833, 0.1429], [0.1875, 0.2222, 0.2500]]) tensor([[10., 13., 16.], [19., 22., 25.]]) tensor([[-10., -11., -12.], [-13., -14., -15.]]) tensor([[inf, 12., 7.], [ 5., 4., 4.]]) tensor([[ 0., 1., 8.], [ 27., 64., 125.]]) tensor([[ 0., 1., 8.], [ 27., 64., 125.]]) tensor([[ 1.0000, 2.7183, 7.3891], [ 20.0855, 54.5981, 148.4132]]) tensor([[ -inf, 0.0000, 0.6931], [1.0986, 1.3863, 1.6094]]) tensor([[0.0000, 1.0000, 1.4142], [1.7321, 2.0000, 2.2361]]) tensor([[0.0000, 1.0000, 1.4142], [1.7321, 2.0000, 2.2361]]) tensor([[ inf, 1.0000, 0.7071], [0.5774, 0.5000, 0.4472]]) tensor([[ inf, 1.0000, 0.7071], [0.5774, 0.5000, 0.4472]]) tensor([[0., 1., 2.], [3., 4., 5.]]) tensor([[0., 1., 2.], [3., 4., 4.]]) tensor([[3., 3., 3.], [3., 4., 5.]]) tensor([[2.5000, 2.5000, 2.5000], [3.0000, 4.0000, 4.0000]]) tensor([[0., 3.], [1., 4.], [2., 5.]]) tensor([[ 5., 14.], [14., 50.]]) tensor([[[ 0., 1., 2.], [ 3., 4., 5.]], [[ 6., 7., 8.], [ 9., 10., 11.]]]) tensor([[[ 0., 1.], [ 2., 3.], [ 4., 5.]], [[ 6., 7.], [ 8., 9.], [10., 11.]]]) tensor([[[ 10., 13.], [ 28., 40.]], [[172., 193.], [244., 274.]]]) tensor([[True, True], [True, True]]) tensor([[False, False], [False, False]]) tensor([[ 1.0000e+00, 5.9605e-08, -2.9057e-07], [ 5.9605e-08, 1.0000e+00, -1.7881e-07], [ 5.9605e-08, -5.9605e-08, 1.0000e+00]]) tensor(12.)
API方式的写法
-
# 此外,加减乘除还可以使用API
-
A = torch.tensor([
1.,
2.,
3.,
4.,
5.,
6.])
-
A = A.reshape(
2,
3)
-
print(A+
3)
-
B = torch.ones(
2,
3)
-
print(B)
-
print(A+B)
#广播原则 不会改变原有的结果
-
A.add(B)
#不会改变原有的结果
-
print(A)
-
A.add_(B)
#会改变原有的结果 很多后面加上_会就地改变原值
-
print(A)
-
print(torch.
abs(A))
#它们不仅有这种静态方法
-
print(A.abs_())
#也是有实例方法的
tensor([[4., 5., 6.], [7., 8., 9.]]) tensor([[1., 1., 1.], [1., 1., 1.]]) tensor([[2., 3., 4.], [5., 6., 7.]]) tensor([[1., 2., 3.], [4., 5., 6.]]) tensor([[2., 3., 4.], [5., 6., 7.]]) tensor([[2., 3., 4.], [5., 6., 7.]]) tensor([[2., 3., 4.], [5., 6., 7.]])
注意 abs,mean,cumsum,multiply,divide 都有这些性质
-
t = torch.rand(
2,
3)
-
print(t)
-
print(t.T)
#转置 shape (3,2)
-
print(t.matmul(t.T))
-
#矩阵乘法的简化写法
-
print(t@(t.T))
-
print(t.
sum())
-
print(t.
sum().item())
#将其转为python的数据类型
-
result = t.mean()
-
print(result.item())
tensor([[0.5961, 0.0197, 0.8739], [0.8200, 0.0368, 0.2758]]) tensor([[0.5961, 0.8200], [0.0197, 0.0368], [0.8739, 0.2758]]) tensor([[1.1194, 0.7305], [0.7305, 0.7498]]) tensor([[1.1194, 0.7305], [0.7305, 0.7498]]) tensor(2.6223) 2.6223182678222656 0.43705305457115173
2.3 统计相关的计算
-
# 一维张量的最大值和最小值
-
a = torch.tensor([
12.,
34,
25,
11,
67,
32,
29,
30,
99,
55,
23,
44])
-
print(
"最大值:", a.
max())
-
print(
"最大值位置:", a.argmax())
-
print(
"最小值", a.
min())
-
print(
"最小值位置", a.argmin())
-
-
b = a.reshape(
3,
4)
-
print(
"2-D张量:", b)
-
# 最大值及位置(每行)
-
print(
"最大值:", b.
max(dim=
1))
-
print(
"最大值位置:", b.argmax(dim=
1))
-
# 最小值及位置(每列)
-
print(
"最小值", b.
min(dim=
0))
-
print(
"最小值位置", b.argmin(dim=
0))
-
-
# torch.sort()可以对一维张量进行排序,或者对高维张量在指定的维度进行排序,输出排序结果,还会输出对应的值在原始位置的索引
-
print(torch.sort(a))
-
# 按照降序排序
-
print(torch.sort(a, descending=
True))
-
# 对二维张量进行排序
-
bsort, bsort_id = torch.sort(b)
-
print(
"b sort", bsort)
-
print(
"b sort_id", bsort_id)
-
print(
"b argsort:", torch.argsort(b))
-
-
# torch.topk()根据指定的k值,计算出张量中取值大小为第k大的数值与数值所在的位置
-
# torch.kthvalue()根据指定的数值k,计算出张量中取值大小为第k小的数值与数值所在的位置
-
-
# 获取张量前几大的数值
-
print(torch.topk(a,
4))
-
# 获取2-D张量每列前几大的数值
-
btop2, btop2_id = torch.topk(b,
2, dim=
0)
-
print(
"b 每列 top2", btop2)
-
print(
"b 每列 top2 位置", btop2_id)
-
-
# 获取张量第k小的数值和位置
-
print(torch.kthvalue(a,
3))
-
-
# 获取2-D张量第k小的数值和位置
-
print(torch.kthvalue(b,
3, dim=
1))
-
# 获取2-D张量第k小的数值和位置
-
bkth, bkth_id = torch.kthvalue(b,
3, dim=
1, keepdim=
True)
-
print(bkth)
-
-
# torch.mean()根据指定的维度计算均值
-
# 计算每行的平均值
-
print(torch.mean(b, dim=
1, keepdim=
True))
-
# 计算每列的均值
-
print(torch.mean(b, dim=
0, keepdim=
True))
-
# torch.sum()根据指定的维度求和
-
# 计算每行的和
-
print(torch.
sum(b, dim=
1, keepdim=
True))
-
# 计算每列的和
-
print(torch.
sum(b, dim=
0, keepdim=
True))
-
# torch.cumsum()根据指定的维度计算累加和
-
# 按照行计算累加和
-
print(torch.cumsum(b, dim=
1))
-
# 按照列计算累加和
-
print(torch.cumsum(b, dim=
0))
-
# torch.median()根据指定的维度计算中位数
-
# 计算每行的中位数
-
print(torch.median(b, dim=
1, keepdim=
True))
-
# 计算每列的中位数
-
print(torch.median(b, dim=
0, keepdim=
True))
-
# 按照行计算乘积
-
print(torch.prod(b, dim=
1, keepdim=
True))
-
# 按照列计算乘积
-
print(torch.prod(b, dim=
1, keepdim=
True))
-
# 按照行计算累乘积
-
print(torch.cumprod(b, dim=
1))
-
# 按照列计算累乘积
-
print(torch.cumprod(b, dim=
0))
-
# torch.std()计算张量的标准差
-
print(torch.std(a))
最大值: tensor(99.) 最大值位置: tensor(8) 最小值 tensor(11.) 最小值位置 tensor(3) 2-D张量: tensor([[12., 34., 25., 11.], [67., 32., 29., 30.], [99., 55., 23., 44.]]) 最大值: torch.return_types.max( values=tensor([34., 67., 99.]), indices=tensor([1, 0, 0])) 最大值位置: tensor([1, 0, 0]) 最小值 torch.return_types.min( values=tensor([12., 32., 23., 11.]), indices=tensor([0, 1, 2, 0])) 最小值位置 tensor([0, 1, 2, 0]) torch.return_types.sort( values=tensor([11., 12., 23., 25., 29., 30., 32., 34., 44., 55., 67., 99.]), indices=tensor([ 3, 0, 10, 2, 6, 7, 5, 1, 11, 9, 4, 8])) torch.return_types.sort( values=tensor([99., 67., 55., 44., 34., 32., 30., 29., 25., 23., 12., 11.]), indices=tensor([ 8, 4, 9, 11, 1, 5, 7, 6, 2, 10, 0, 3])) b sort tensor([[11., 12., 25., 34.], [29., 30., 32., 67.], [23., 44., 55., 99.]]) b sort_id tensor([[3, 0, 2, 1], [2, 3, 1, 0], [2, 3, 1, 0]]) b argsort: tensor([[3, 0, 2, 1], [2, 3, 1, 0], [2, 3, 1, 0]]) torch.return_types.topk( values=tensor([99., 67., 55., 44.]), indices=tensor([ 8, 4, 9, 11])) b 每列 top2 tensor([[99., 55., 29., 44.], [67., 34., 25., 30.]]) b 每列 top2 位置 tensor([[2, 2, 1, 2], [1, 0, 0, 1]]) torch.return_types.kthvalue( values=tensor(23.), indices=tensor(10)) torch.return_types.kthvalue( values=tensor([25., 32., 55.]), indices=tensor([2, 1, 1])) tensor([[25.], [32.], [55.]]) tensor([[20.5000], [39.5000], [55.2500]]) tensor([[59.3333, 40.3333, 25.6667, 28.3333]]) tensor([[ 82.], [158.], [221.]]) tensor([[178., 121., 77., 85.]]) tensor([[ 12., 46., 71., 82.], [ 67., 99., 128., 158.], [ 99., 154., 177., 221.]]) tensor([[ 12., 34., 25., 11.], [ 79., 66., 54., 41.], [178., 121., 77., 85.]]) torch.return_types.median( values=tensor([[12.], [30.], [44.]]), indices=tensor([[0], [3], [3]])) torch.return_types.median( values=tensor([[67., 34., 25., 30.]]), indices=tensor([[1, 0, 0, 1]])) tensor([[ 112200.], [1865280.], [5510340.]]) tensor([[ 112200.], [1865280.], [5510340.]]) tensor([[1.2000e+01, 4.0800e+02, 1.0200e+04, 1.1220e+05], [6.7000e+01, 2.1440e+03, 6.2176e+04, 1.8653e+06], [9.9000e+01, 5.4450e+03, 1.2524e+05, 5.5103e+06]]) tensor([[1.2000e+01, 3.4000e+01, 2.5000e+01, 1.1000e+01], [8.0400e+02, 1.0880e+03, 7.2500e+02, 3.3000e+02], [7.9596e+04, 5.9840e+04, 1.6675e+04, 1.4520e+04]]) tensor(25.0108)
2.4 张量的自动微分
在torch中的torch.autograd模块,提供了实现任意标量值函数自动求导的类和函数。针对一个张量只需要设置参数requires_grad = True,通过相关计算即可输出其在传播过程中的梯度(导数)信息。 如在PyTorch中生成一个矩阵张量x,并且y=sum(x2+2x+1)。计算出y在x上的导数,实现过程如下:
-
import torch
-
x = torch.tensor([[
1.0,
2.0], [
3.0,
4.0]], requires_grad=
True)
# requires_grad pytorch是否自动跟踪计算它的梯度计算
-
# 默认requires_grad=False
-
y = torch.
sum(x**
2+
2*x+
1)
-
print(
"x是否可导:", x.requires_grad)
-
print(
"y是否可导:", y.requires_grad)
-
print(
"x:", x)
-
print(
"y:", y)
-
## 计算y在x上的梯度
-
y.backward()
-
print(
"y在x的每个元素上的导数为:",x.grad)
#打印x的梯度,d(y)/d(x)
-
with torch.no_grad():
#pytorch不要跟踪运算 上下文管理器,用于测试。 有些时候,我们不想一些层参与运算,那么就让requires_grad变为false或者使用上下文管理器
-
y = x +
2
-
print(y.requires_grad)
-
result = x.detach()
#截断梯度运算
-
print(result.requires_grad)
-
x.data
x是否可导: True y是否可导: True x: tensor([[1., 2.], [3., 4.]], requires_grad=True) y: tensor(54., grad_fn=<SumBackward0>) y在x的每个元素上的导数为: tensor([[ 4., 6.], [ 8., 10.]]) False FalseOut[24]:
tensor([[1., 2.], [3., 4.]])
转载:https://blog.csdn.net/qq_37080185/article/details/128877636
查看评论