飞道的博客

2. Pytorch 张量运算

298人阅读  评论(0)

目录

2.1 比较大小

 2.2基本运算

 2.3 统计相关的计算

2.4 张量的自动微分


张量计算 张量的计算内容主要包括:张量之间的大小比较,张量的基本运算,如元素之间的运算和矩阵之间的运算等,张量与统计相关的运算,如排序,最大值,最小值,最大值的位置等内容。

2.1 比较大小

对于torch.allclose()函数,比较的是两个元素是否接近,比较A和B是否接近的公式为: ∣A − B∣<= atol + rtol ×∣B∣


  
  1. import torch
  2. # 比较两个数是否接近
  3. A = torch.tensor([ 10.0])
  4. B = torch.tensor([ 10.1])
  5. torch.allclose(A,B,rtol= 1e-05,atol= 1e-08,equal_nan= False)
  6. torch.allclose(A, B, rtol= 0.1, atol= 0.01, equal_nan= False)
  7. # 在不同的判断条件下,得出的结果也是不同的
  8. # 如果equal_nan=True,那么缺失值可以判断为接近
  9. A = torch.tensor( float( "nan"))
  10. print(torch.allclose(A, A, equal_nan= False))
  11. print(torch.allclose(A, A, equal_nan= True))
  12. A = torch.tensor([ 1, 2, 3, 4, 5, 6])
  13. B = torch.arange( 1, 7)
  14. C = torch.unsqueeze(B, dim= 0)
  15. # torch.eq()函数用来判断两个元素是否相等
  16. print(torch.eq(A, B))
  17. print(torch.eq(A, C))
  18. # torch.equal()函数可以判断两个张量是否具有相同的形状和元素
  19. print(torch.equal(A, B))
  20. print(torch.equal(A, C))
  21. # torch.ge()函数是逐元素比较是否大于等于(>=)
  22. print(torch.ge(A, B))
  23. print(torch.ge(A, C))
  24. # torch.gt()函数是逐元素比较大于
  25. print(torch.gt(A, B))
  26. print(torch.gt(A, C))
  27. # torch.le()函数是逐元素比较是否小于等于(<=)
  28. print(torch.le(A, B))
  29. print(torch.le(A, C))
  30. # torch.lt()函数是逐元素比较大于
  31. print(torch.lt(A, B))
  32. print(torch.lt(A, C))
  33. # torch.ne()函数是逐元素比较不等于
  34. print(torch.ne(A, B))
  35. print(torch.ne(A, C))
  36. # torch.isnan()函数用来判断是否为缺失值
  37. # 缺失值是值:NULL,也包括表示数值确实的特殊数值(如,在系统中用-999来表示的数值不存在)
  38. 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基本运算


  
  1. # 矩阵逐元素相乘
  2. a = torch.arange( 6.0).reshape( 2, 3)
  3. b = torch.linspace( 10, 20, steps= 6).reshape( 2, 3)
  4. print( "a", a)
  5. print( "b", b)
  6. print(a * b)
  7. # 逐元素相除
  8. print(a / b)
  9. # 逐元素相加
  10. print(a + b)
  11. # 逐元素相减
  12. print(a - b)
  13. # 逐元素整除
  14. print(b // a)
  15. # 计算张量的幂可以使用torch.pow()函数,或者使用**
  16. print(torch. pow(a, 3))
  17. print(a ** 3)
  18. # 计算张量的指数可以使用torch.exp()函数
  19. print(torch.exp(a))
  20. # 计算张量的对数可以使用torch.log()函数
  21. print(torch.log(a))
  22. # 计算张量的平方根可以使用torch.sqrt()函数
  23. print(torch.sqrt(a))
  24. print(a ** 0.5)
  25. # 计算张量的平方根倒数可以使用torch.rsqrt()函数
  26. print(torch.rsqrt(a))
  27. print( 1 / (a** 0.5))
  28. # 对张量的数据裁剪,有根据最大值裁剪torch.clamp_max()函数
  29. # 将大于x的数值都替换为x
  30. print(a, "\n", torch.clamp_max(a, 4))
  31. # 有根据最小值裁剪torch.clamp_min()函数
  32. # 将小于x的数值都替换为x
  33. print(torch.clamp_min(a, 3))
  34. # 有根据范围裁剪torch.clamp()函数
  35. # 按照范围剪裁张量,小于边界的数值都替换为下界值,大于上界的数值都替换为上界
  36. print(torch.clamp(a, 2.5, 4))
  37. # torch.t()计算矩阵的转置
  38. c = torch.t(a)
  39. print(c)
  40. # torch.matmul()输出两个矩阵的乘积
  41. print(a.matmul(c))
  42. # 矩阵相乘只计算最后面的两个维度的乘法
  43. a = torch.arange( 12.0).reshape( 2, 2, 3)
  44. b = torch.arange( 12.0).reshape( 2, 3, 2)
  45. print(a, b)
  46. ab = torch.matmul(a, b)
  47. print(ab)
  48. print(ab[ 0].eq(torch.matmul(a[ 0], b[ 0])))
  49. print(ab[ 0].eq(torch.matmul(a[ 1], b[ 0])))
  50. # 计算矩阵的逆
  51. c = torch.rand( 3, 3)
  52. d = torch.inverse(c)
  53. print(torch.mm(c, d))
  54. # 计算张量矩阵的迹,对角线元素的和
  55. 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方式的写法


  
  1. # 此外,加减乘除还可以使用API
  2. A = torch.tensor([ 1., 2., 3., 4., 5., 6.])
  3. A = A.reshape( 2, 3)
  4. print(A+ 3)
  5. B = torch.ones( 2, 3)
  6. print(B)
  7. print(A+B) #广播原则 不会改变原有的结果
  8. A.add(B) #不会改变原有的结果
  9. print(A)
  10. A.add_(B) #会改变原有的结果 很多后面加上_会就地改变原值
  11. print(A)
  12. print(torch. abs(A)) #它们不仅有这种静态方法
  13. 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 都有这些性质


  
  1. t = torch.rand( 2, 3)
  2. print(t)
  3. print(t.T) #转置 shape (3,2)
  4. print(t.matmul(t.T))
  5. #矩阵乘法的简化写法
  6. print(t@(t.T))
  7. print(t. sum())
  8. print(t. sum().item()) #将其转为python的数据类型
  9. result = t.mean()
  10. 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 统计相关的计算


  
  1. # 一维张量的最大值和最小值
  2. a = torch.tensor([ 12., 34, 25, 11, 67, 32, 29, 30, 99, 55, 23, 44])
  3. print( "最大值:", a. max())
  4. print( "最大值位置:", a.argmax())
  5. print( "最小值", a. min())
  6. print( "最小值位置", a.argmin())
  7. b = a.reshape( 3, 4)
  8. print( "2-D张量:", b)
  9. # 最大值及位置(每行)
  10. print( "最大值:", b. max(dim= 1))
  11. print( "最大值位置:", b.argmax(dim= 1))
  12. # 最小值及位置(每列)
  13. print( "最小值", b. min(dim= 0))
  14. print( "最小值位置", b.argmin(dim= 0))
  15. # torch.sort()可以对一维张量进行排序,或者对高维张量在指定的维度进行排序,输出排序结果,还会输出对应的值在原始位置的索引
  16. print(torch.sort(a))
  17. # 按照降序排序
  18. print(torch.sort(a, descending= True))
  19. # 对二维张量进行排序
  20. bsort, bsort_id = torch.sort(b)
  21. print( "b sort", bsort)
  22. print( "b sort_id", bsort_id)
  23. print( "b argsort:", torch.argsort(b))
  24. # torch.topk()根据指定的k值,计算出张量中取值大小为第k大的数值与数值所在的位置
  25. # torch.kthvalue()根据指定的数值k,计算出张量中取值大小为第k小的数值与数值所在的位置
  26. # 获取张量前几大的数值
  27. print(torch.topk(a, 4))
  28. # 获取2-D张量每列前几大的数值
  29. btop2, btop2_id = torch.topk(b, 2, dim= 0)
  30. print( "b 每列 top2", btop2)
  31. print( "b 每列 top2 位置", btop2_id)
  32. # 获取张量第k小的数值和位置
  33. print(torch.kthvalue(a, 3))
  34. # 获取2-D张量第k小的数值和位置
  35. print(torch.kthvalue(b, 3, dim= 1))
  36. # 获取2-D张量第k小的数值和位置
  37. bkth, bkth_id = torch.kthvalue(b, 3, dim= 1, keepdim= True)
  38. print(bkth)
  39. # torch.mean()根据指定的维度计算均值
  40. # 计算每行的平均值
  41. print(torch.mean(b, dim= 1, keepdim= True))
  42. # 计算每列的均值
  43. print(torch.mean(b, dim= 0, keepdim= True))
  44. # torch.sum()根据指定的维度求和
  45. # 计算每行的和
  46. print(torch. sum(b, dim= 1, keepdim= True))
  47. # 计算每列的和
  48. print(torch. sum(b, dim= 0, keepdim= True))
  49. # torch.cumsum()根据指定的维度计算累加和
  50. # 按照行计算累加和
  51. print(torch.cumsum(b, dim= 1))
  52. # 按照列计算累加和
  53. print(torch.cumsum(b, dim= 0))
  54. # torch.median()根据指定的维度计算中位数
  55. # 计算每行的中位数
  56. print(torch.median(b, dim= 1, keepdim= True))
  57. # 计算每列的中位数
  58. print(torch.median(b, dim= 0, keepdim= True))
  59. # 按照行计算乘积
  60. print(torch.prod(b, dim= 1, keepdim= True))
  61. # 按照列计算乘积
  62. print(torch.prod(b, dim= 1, keepdim= True))
  63. # 按照行计算累乘积
  64. print(torch.cumprod(b, dim= 1))
  65. # 按照列计算累乘积
  66. print(torch.cumprod(b, dim= 0))
  67. # torch.std()计算张量的标准差
  68. 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上的导数,实现过程如下:


  
  1. import torch
  2. x = torch.tensor([[ 1.0, 2.0], [ 3.0, 4.0]], requires_grad= True) # requires_grad pytorch是否自动跟踪计算它的梯度计算
  3. # 默认requires_grad=False
  4. y = torch. sum(x** 2+ 2*x+ 1)
  5. print( "x是否可导:", x.requires_grad)
  6. print( "y是否可导:", y.requires_grad)
  7. print( "x:", x)
  8. print( "y:", y)
  9. ## 计算y在x上的梯度
  10. y.backward()
  11. print( "y在x的每个元素上的导数为:",x.grad) #打印x的梯度,d(y)/d(x)
  12. with torch.no_grad(): #pytorch不要跟踪运算 上下文管理器,用于测试。 有些时候,我们不想一些层参与运算,那么就让requires_grad变为false或者使用上下文管理器
  13. y = x + 2
  14. print(y.requires_grad)
  15. result = x.detach() #截断梯度运算
  16. print(result.requires_grad)
  17. 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
False

Out[24]:

tensor([[1., 2.],
        [3., 4.]])

转载:https://blog.csdn.net/qq_37080185/article/details/128877636
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场