PyTorch初学者指南:数据操作
创始人
2024-05-13 20:14:42
0

PyTorch初学者指南:数据操作

文章目录

  • PyTorch初学者指南:数据操作
    • 一、前言
    • 二、张量
      • 1、何为张量
      • 2、如何创建张量
      • 3、如何访问张量的形状
      • 4、如何改变张量的形状而不改变元素数量和元素值
    • 三、运算符
      • 1、基本数学运算
      • 2、张量的连结
    • 四、广播机制
    • 五、索引和切片
      • 1、索引
      • 2、切片
      • 3、赋值
    • 六、节省内存
    • 七、转换为其他Python对象

一、前言

这是我创建的编程算法竞赛学习小组频道,欢迎大家加入,共同进步!!!

一般来说,数据的操作包含获取数据和将数据读入计算机后对其进行处理,如果没有方法来存储数据,那么获取数据也是没有意义的,接下来,我们将学习PyTorch中的一些基础的数据操作。

二、张量

在机器学习,深度学习中,一般都会使用n维数组,也称张量,进行各种计算操作,再学习数据操作之前我们先来了解一下张量的基本介绍。

1、何为张量

张量是多维数组,在 PyTorch 中,它是一种类似于 numpy 数组的数据结构。它可以存储向量、矩阵、三维数组等多维数据。张量可以使用 GPU 进行加速计算,这使得 PyTorch 成为了一种非常强大的深度学习框架。 张量也是PyTorch的核心数据结构,他是用来存储和变换数据的,并且他能跟踪操作的历史记录,可以用来计算梯度。

2、如何创建张量

在 PyTorch 中,可以使用 torch.Tensor() 或 torch.tensor() 函数来创建张量。

  • 使用 torch.Tensor() 函数:

    import torchtensor = torch.Tensor(2, 3)
    print(tensor)
    
  • 使用 torch.tensor() 函数:

    import torchtensor = torch.tensor((2, 3))
    print(tensor)
    
  • 使用 torch.zeros() 函数创建全0张量:

    import torch# 创建一个 2x3 的全零张量
    tensor = torch.zeros((2, 3))
    print(tensor)
    
  • 使用 torch.ones() 函数创建全1张量:

    import torch# 创建一个 2x3 的全1张量
    tensor = torch.ones((2, 3))
    print(tensor)
    
  • 使用 torch.rand() 函数创建随机张量:

    import torch# 创建一个 2x3 的全零张量
    tensor = torch.rand((2, 3))
    print(tensor)
    

3、如何访问张量的形状

在 PyTorch 中,可以使用 .shape 属性来访问张量的形状。

import torch# 创建一个 2x3 的张量
tensor = torch.randn(2, 3)
print(tensor)# 访问张量的形状
print(tensor.shape)
tensor([[ 0.0012, -0.7267,  0.0413],[-0.2877, -0.6770,  0.6846]])
torch.Size([2, 3])

或者使用 .size() 函数来获取张量的形状

import torch# 创建一个 2x3 的张量
tensor = torch.randn(2, 3)
print(tensor)# 访问张量的形状
print(tensor.size())
tensor([[ 0.1515, -0.9561, -1.0691],[-1.2747,  0.2559,  0.0547]])
torch.Size([2, 3])

.shape 和 .size() 都能得到一个torch.Size的对象,这是一个tuple, 它包含了张量的各维度的大小, 例如上面的代码中得到的是(2,3)

你也可以使用索引的方式来访问某一维的大小。

print(tensor.shape[0]) # 2

另外,还可以使用 .ndim 属性获取张量的维度数, 例如上面的代码中得到的是2。

print(tensor.ndim) # 2

张量的形状是一个重要的信息,在许多操作中都需要用到它。

4、如何改变张量的形状而不改变元素数量和元素值

在 PyTorch 中,可以使用 .view() 方法来改变一个张量的形状,而不改变元素数量和元素值。

import torch# 创建一个 2x3 的张量
tensor = torch.randn(2, 3)
print(tensor)# 改变形状为 3x2
tensor = tensor.view(3, 2)
print(tensor)
tensor([[-0.9560, -1.4888, -0.1156],[-0.2095, -0.6208, -0.5531]])
tensor([[-0.9560, -1.4888],[-0.1156, -0.2095],[-0.6208, -0.5531]])

或者使用 -1 作为一维大小。

import torch# 创建一个 2x3 的张量
tensor = torch.randn(2, 3)
print(tensor)# 改变形状为 3x2
tensor = tensor.view(-1, 2)
print(tensor)
tensor([[ 0.3850,  0.3420, -0.7406],[-0.0208,  0.9118,  1.3379]])
tensor([[ 0.3850,  0.3420],[-0.7406, -0.0208],[ 0.9118,  1.3379]])

在上面的例子中,我们将原始的 2x3 的张量改变成了 3x2 的张量,其中元素数量和元素值都没有发生变化。

但是需要注意的是,如果将张量的形状改变为不能容纳原先的元素数量,会抛出异常。比如现在有一个 2x3 的张量,如果将它改变为 1x4 的形状就会抛出异常。

另外,如果你使用 -1 作为一维大小,pytorch会自动计算这一维的大小,保证元素个数不变

还有一个函数 reshape() 也能达到相同的效果。

tensor = tensor.reshape(3, 2)

总之, .view() 和 reshape() 都能达到改变张量形状的目的,只需要注意不能改变元素的个数。

三、运算符

1、基本数学运算

当我们学会如何创建张量之后,我们就可以来学习如何使用这些张量来进行一些数学运算。

在数学表示法中,我们将通过符号f:R→R来表示一元标量运算符(只接收一个输入)。这意味着该函数从任何实数(R)映射到另一个实数。同样,我们通过符号f:R,R→Rf:R,R→Rf:R,R→R表示二元标量运算符,这意味着该函数接收两个输入,并产生一个输出。给定同一形状的任意两个向量uv和二元运算符f,我们可以得到向量c=F(u,v)c = F(u,v)c=F(u,v)。具体计算方法是ci←f(ui,vi)c_i \leftarrow f(u_i,v_i)ci​←f(ui​,vi​),其中cic_ici​、viv_ivi​和viv_ivi​分别是向量cuv中的元素。在这里,我们通过将标量函数升级为按元素向量运算来生成向量值F∶Rd,Rd一RdF∶R^d,R^d一R^dF∶Rd,Rd一Rd。

PyTorch 中支持多种张量间的运算符,这些运算符可以在不创建新的张量的情况下对原始张量进行修改。

常用的运算符包括:

  • 加法运算符(+):可以将两个张量相加。
  • 减法运算符(-):可以将两个张量相减。
  • 乘法运算符(*):可以将两个张量相乘,或将一个张量乘上一个标量。
  • 除法运算符(/):可以将两个张量相除,或将一个张量除以一个标量。
  • 取模运算符(%):可以将两个张量进行取模运算。
  • 幂运算符(**):可以将一个张量的每个元素进行幂运算。

例如:

import torch# 创建两个张量
tensor1 = torch.ones(2, 3)
tensor2 = torch.randn(2, 3)# 两个张量相加
tensor3 = tensor1 + tensor2
print(f"相加结果:{tensor3}")
# 两个张量相乘
tensor4 = tensor1 * tensor2
print(f"相乘结果:{tensor4}")
# 张量除以标量
tensor5 = tensor1 / 2
print(f"相除结果:{tensor5}")
相加结果:tensor([[0.1391, 1.9700, 0.8572],[3.3594, 1.6085, 1.4660]])
相乘结果:tensor([[-0.8609,  0.9700, -0.1428],[ 2.3594,  0.6085,  0.4660]])
相除结果:tensor([[0.5000, 0.5000, 0.5000],[0.5000, 0.5000, 0.5000]])

另外,还有一些其他的运算符, 如+=,-=,*=,/=,%=,**=

tensor1 += tensor2
tensor1 *= 2

这些运算符都是在原始张量上进行修改,而不会创建新的张量。

这些运算符都是基于element-wise运算的,也就是说对于两个张量,运算符会将它们的对应元素进行运算。这意味着它们的形状必须相同。

PyTorch也提供了一些其他的运算符,如:

  • torch.add()
  • torch.sub()
  • torch.mul()
  • torch.div()
  • torch.pow()
  • torch.remainder()

这些函数可以更灵活地控制运算符的行为。

import torch# 创建两个张量
tensor1 = torch.ones(2, 3)
tensor2 = torch.randn(2, 3)# 使用torch.add()函数两个张量相加
tensor3 = torch.add(tensor1, tensor2)# 使用torch.mul()函数两个张量相乘
tensor4 = torch.mul(tensor1, tensor2)# 使用torch.div()函数张量除以标量
tensor5 = torch.div(tensor1, 2)

这些函数和运算符都是在张量间进行运算,而且都是基于 element-wise 运算的。这些运算符和函数都能很好的支持 GPU 加速,使得 PyTorch 成为了一种高效的深度学习框架。

2、张量的连结

在 PyTorch 中,可以使用 torch.cat() 函数将多个张量连接在一起,形成一个新的张量。连接操作可以在第 0 维(即行)或第 1 维(即列)上进行。

例如:

import torch# 创建三个 2x3 的张量
tensor1 = torch.randn(2, 3)
tensor2 = torch.randn(2, 3)
tensor3 = torch.randn(2, 3)# 在第 0 维上连接
result = torch.cat((tensor1, tensor2, tensor3), dim=0)
print(result)
tensor([[-0.1000, -1.5875,  1.5468],[-0.6155, -0.4775, -0.7122],[ 0.1312,  1.0378, -1.1289],[-0.6397, -1.2239,  0.0601],[-0.2370,  0.4329,  1.9026],[-1.4683,  2.1071, -1.7164]])

这里我们将三个 2x3 的张量在第 0 维(即行)上连接起来,得到了一个 6x3 的张量。

四、广播机制

在 PyTorch 中,张量的广播机制允许在进行运算时使用不同形状的张量。它能自动地复制张量的元素,使得它们的形状相同。

例如:

import torch# 创建一个 2x3 的张量
tensor1 = torch.randn(2, 3)# 创建一个大小为 3 的张量
tensor2 = torch.randn(3)# 使用张量的广播机制进行运算
result = tensor1 + tensor2
print(result)
tensor([[ 0.0124,  0.9451, -0.3922],[-0.9794,  0.1206, -1.1299]])

在这个例子中,tensor1 是一个 2x3 的张量,而 tensor2 是一个大小为 3 的张量。在进行加法运算时,PyTorch 会自动地复制 tensor2 的元素,使得它们的形状与 tensor1 相同。

广播机制还可以应用在不同维度上,例如:

import torch# 创建一个 2x3 的张量
tensor1 = torch.randn(2, 3)# 创建一个 2x1 的张量
tensor2 = torch.randn(2, 1)# 使用张量的广播机制进行运算
result = tensor1 + tensor2
print(result)
tensor([[ 0.5422, -0.8242,  0.1485],[ 1.9900, -0.1229,  3.3772]])

Pytorch 在进行运算时会自动进行广播,这使得我们可以在不创建新的张量的情况下执行各种各样的数学运算,提高了编程的灵活性和效率。

五、索引和切片

1、索引

与任何Python数组一样,张量中的元素都可以通过索引来访问,而且也是第一个元素的索引是0,最后一个元素的索引是-1,也可以指定范围以内包含第一个元素和最后一个之前元素。

索引是指使用下标来访问张量中的元素,例如:

import torch# 创建一个 2x3 的张量
tensor = torch.randn(2, 3)# 访问第一行第二列的元素
print(tensor[0][1])# 也可以这样
print(tensor[0, 1])
tensor(-0.0790)
tensor(-0.0790)

2、切片

切片是指使用切片语法来访问张量中的一个子集。例如:

import torch# 创建一个 2x3 的张量
tensor = torch.randn(2, 3)# 访问第二行
print(tensor[1])# 访问第二列
print(tensor[:, 1])# 访问第二行第二列到最后一列
print(tensor[1, 1:])
tensor([ 0.3118, -0.8547,  0.5481])
tensor([-0.5568, -0.8547])
tensor([-0.8547,  0.5481])

3、赋值

索引和切片都可以用来访问张量中的元素,并且都可以赋值。例如:

import torch# 创建一个 2x3 的张量
tensor = torch.randn(2, 3)# 使用索引赋值
tensor[0][1] = 0# 使用切片赋值
tensor[1] = torch.ones(3)

在 PyTorch 中,索引和切片可以结合使用,进行更细粒度的控制。例如:

import torch# 创建一个 2x3x4 的张量
tensor = torch.randn(2, 3, 4)# 访问第一个维度的第二个切片
print(tensor[1])# 访问第二个维度的第二个切片
print(tensor[:, 1])# 访问第三个维度的第二个切片
print(tensor[:, :, 1])
tensor([[ 1.4468,  0.4494, -0.8026,  0.6946],[ 1.1855,  0.2480,  0.1043,  0.1165],[-0.9049,  1.1424, -0.2831, -0.5333]])
tensor([[ 0.5936,  0.0597, -0.1426,  1.0866],[ 1.1855,  0.2480,  0.1043,  0.1165]])
tensor([[ 0.5400,  0.0597, -0.3470],[ 0.4494,  0.2480,  1.1424]])

这样就可以访问到不同维度上的元素,更灵活地进行操作。

另外,Pytorch还提供了一些函数来简化索引和切片,比如

torch.index_select(),torch.masked_select(),torch.narrow()等, 可以根据需要选择使用。

这些索引和切片的操作让我们可以轻松地访问张量中的元素,并对它们进行操作,提高了编程的灵活性和效率。

六、节省内存

在 PyTorch 中,有一些操作可以节省内存。

例如:

  • torch.view() 函数可以重新改变张量的形状,并且不会复制元素。
  • torch.squeeze() 函数可以删除张量中所有维度为 1 的维度,并且不会复制元素。
  • torch.transpose() 函数可以对张量进行转置,并且不会复制元素。

例如:

import torch# 创建一个 2x3 的张量
tensor = torch.randn(2, 3)# 使用 torch.view() 函数改变形状
tensor = tensor.view(3, 2)# 使用 torch.squeeze() 函数删除维度
tensor = tensor.squeeze()# 使用 torch.transpose() 函数进行转置
tensor = tensor.transpose(0, 1)

这些操作都是在不复制元素的情况下改变张量的形状,从而节省内存,提高程序的效率。

还有一种常用的操作是torch.clone()函数, 它会为张量中的元素创建一个副本.

例如:

import torch# 创建一个 2x3 的张量
tensor = torch.randn(2, 3)# 使用 torch.clone() 函数创建副本
tensor2 = tensor.clone()

使用这些操作可以根据需要节省内存,提高程序的效率。

七、转换为其他Python对象

在 PyTorch 中,可以使用以下函数将张量转换为其他 Python 对象:

  • torch.tolist() 函数可以将张量转换为 Python 列表。
  • torch.numpy() 函数可以将张量转换为 numpy 数组。
  • torch.tensor() 函数可以将其他 Python 对象转换为张量。

例如:

import torch
import numpy as np# 创建一个 2x3 的张量
tensor = torch.randn(2, 3)
print(f'张量:{tensor}')# 将张量转换为 Python 列表
python_list = tensor.tolist()
print(f'将张量转换为Python列表:{python_list}')# 将张量转换为 numpy 数组
numpy_array = tensor.numpy()
print(f'将张量转换为numpy数组:{numpy_array}')# 将 numpy 数组转换为张量
tensor2 = torch.tensor(numpy_array)
print(f'将numpy数组转换为张量:{tensor2}')
张量:tensor([[-1.1032,  1.7890,  0.6399],[ 1.2101,  0.0476,  0.7854]])
将张量转换为Python列表:[[-1.103205680847168, 1.788976788520813, 0.6398880481719971], [1.2101296186447144, 0.047570642083883286, 0.7854281067848206]]
将张量转换为numpy数组:[[-1.1032057   1.7889768   0.63988805][ 1.2101296   0.04757064  0.7854281 ]]
将numpy数组转换为张量:tensor([[-1.1032,  1.7890,  0.6399],[ 1.2101,  0.0476,  0.7854]])

这些函数可以方便地将张量转换为其他 Python 对象,这样可以在 PyTorch 中使用其他 Python 库,提高编程的灵活性和效率。

需要注意的是, 在转换后的对象中的操作并不会影响到原始的张量,如果需要可以再次转回去。

相关内容

热门资讯

为什么赛尔号克洛斯星沼泽的小J... 为什么赛尔号克洛斯星沼泽的小J不见了,只有3片叶子在而已,不是卡的重新登录赛尔号,还不行的话先去基地...
个人简历该怎么写才算好简历? 个人简历该怎么写才算好简历?其实一份好的简历也是来自你的自身哦,为什么现在每个公司都要求应聘者都要写...
蜜什么意思啊 蜜什么意思啊蜜什么意思啊①蜂蜜,蜜蜂用采集的花蜜酿成的黏稠液体,黄白色,有甜味,供食用和药用:采蜜、...
高二分班到底是怎么分的? 高二分班到底是怎么分的?分班的时候主要是按孩子们报的是学文的还是学理的分科的呀?你要是报的文科呢,肯...
过犹不及是什么意思? 过犹不及是什么意思?过犹不及的意思是事情做得过头,就跟做得不够一样,都是不合适的。【出自】:《论语·...
快来! 快来!不是写完了?
快乐的什么词语。 填空 快乐的什么词语。 填空快乐的童年生话的快乐学习的快乐快乐的童年,快乐的节日,快乐的时光快乐的生活,快...
想找本好书,请帮忙推荐! 想找本好书,请帮忙推荐!最好能写上作者及主要内容!《英国病人》讲述的是20世纪三四十年代,在沙漠里,...
英布后人都在哪些地方? 英布后人都在哪些地方?英布有无后裔,一直是个悬念。英布从投吴芮到起义远征,在番阳仅大半年时间,虽已娶...
在电路中什么叫过载 在电路中什么叫过载指的是电路中电流超过额定负载,会导致电器元件损坏,如装有保护断路器的话,断路器会跳...
过松源晨炊漆公店的写法 过松源晨炊漆公店的写法急!!!过松源晨炊漆公店写作手法:诗人借助景物描写和生动形象的比喻,通过写山区...
电影留守孩子拍摄于哪年 电影留守孩子拍摄于哪年电影留守孩子拍摄于哪年电影《留守孩子》2006年4月在襄樊首映,估计是2005...
百科全书 目标群体 百科全书 目标群体说清楚点啊~~
小孩子什么名字好听 小孩子什么名字好听只要符合你对孩子的期望,并且没不好的含义或谐音,最好还记好读就行了
免费建站真的就是免费吗 免费建站真的就是免费吗阿里云,腾讯云,亚马逊云上租个服务器,自己搭。没有绝对免费的。没有免费的午餐。
巴斯克人的简介 巴斯克人的简介 西班牙语称瓦斯科人(Vasco),或称瓦斯康加多人(Vascongado),巴斯克语...
怎么教女生游泳 怎么教女生游泳我想多教她几次 ,嘿嘿 大家知道的,注意些什么,怎么能通过游泳培养感情告诉你决窍: 三...
关于真情与爱的故事或作文 关于真情与爱的故事或作文人间处处有真情,这不,今天我正好碰上了呢! 天气很热,我和小伙伴们去买冰棍儿...
世界上最高的楼在哪里?一共有多... 世界上最高的楼在哪里?一共有多少层?目前世界最高楼要算比斯迪拜塔了,有160层,总高828米。但阿联...
有人说刘德华作词功低深厚,你觉... 有人说刘德华作词功低深厚,你觉得呢?为什么?我觉的刘德华绝对有这个能力,可惜呀,华仔已经老了,以后还...