『pytorch』一:数据处理

1.创建tensor

1.1 直接创建

直接根据数据创建:

x = torch.tensor(2,3)       # 创建 2*3 的 tensor
x = torch.tensor([5.5, 3])   # 创建 tensor,值为[5.5, 3]
print(x)
# tensor([5.5000, 3.0000])

# 在制定 GPU 上创建与 data 一样的类型
torch.tensor(data, dtype=torch.float64, device=torch.device('cuda:0'))

1.2 Tensor和NumPy相互转换

numpy 创建 tensor

# 从 numpy 创建 tensor
torch.tensor(numpy_array)
torch.from_numpy(numpy_array)

tensor 转换numpy

# 将 tensor 转换为 numpy
numpy_array = pytensor2.numpy()  # 在 cpu 上
numpy_array = pytensor2.cpu().numpy()  # 在 gpu 上
  • Tensor 与 numpy 对象共享内存,所以他们之间切换很快,几乎不消耗资源。但是,这意味着如果其中一个变化了,则另一个也会跟着改变。

  • 直接用torch.tensor()将NumPy数组转换成Tensor,该方法总是会进行数据拷贝,返回的Tensor和原来的数据不再共享内存。

# 用torch.tensor()转换时不会共享内存
c = torch.tensor(a)
a += 1
print(a, c)

# [4. 4. 4. 4. 4.] tensor([3., 3., 3., 3., 3.], dtype=torch.float64)

1.3 拷贝创建

通过 clone 的方式进行创建:

b = a.clone()

1.4 创建特殊矩阵

x = torch.empty(5, 3)    # 创建空的 Tensor
x = torch.ones(3,2)      # 创建 1 矩阵
x = torch.zeros(2,3)     # 创建 0 矩阵
x = torch.eye(2,3)       # 创建单位矩阵 

x = torch.arange(1,6,2)  # 创建 [1, 6),间隔为 2
x = torch.linspace(1, 10, 3)  # [1, 10]  等间距取 3 个数

x = torch.randn(2,3)     # 随机矩阵
x = torch.randperm(5)    # 长度为 5 的随机排列

通过现有的Tensor来创建,此方法会默认重用输入Tensor的一些属性,例如数据类型,除非是自定义数据类型。

x = x.new_ones(5, 3, dtype=torch.float64)      # 返回的tensor默认具有相同的torch.dtype和torch.device
x = torch.randn_like(x, dtype=torch.float)    # 指定新的数据类型 
# tensor([[ 1.6973e+00,  1.8816e+00,  4.3511e-01],
#         [ 1.8384e+00, -1.0594e+00, -1.5551e-03],
#         [ 7.7326e-01,  3.3609e-02,  4.8899e-01],
#         [ 6.7233e-01, -5.9922e-01,  9.3289e-01],
#         [-3.5564e-01, -1.8505e-01, -6.8453e-01]])

2.tensor的属性

2.1 类型属性

通过如下代码查看 tensor 的类型:

x.type()     # 类型
# <function Tensor.type>

pytorch 中的 tensor 支持如下类型:

数据类型CPU tensorGPU Tensor
32 bit浮点torch.FloatTensortorch.cuda.FloatTensor
64bit浮点torch.DoubleTensortorch.cuda.DoubleTensor
16bit半精度浮点N/Atorch.cuda.HalfTensor
8bit无符号整型torch.ByteTensortorch.cuda.ByteTensor
8bit 有符号整型torch.CharTensortorch.cuda.CharTensor
16bit有符号整型torch.ShortTensortorch.cuda.ShortTensor
32bit 有符号整型torch.IntTensortorch.cuda.lntTensor
64 bit有符号整型torch.LongTensortorch.cuda.LongTensor

其中,HalfTensor 是专门为 GPU 设计的,其占用的内存空间只有 CPUFloatTensor 的一半。

2.2 尺度属性

查看 tensor 的相关尺寸:

x.shape      # 尺寸,tuple
# torch.Size([5, 3])
x.size()     # 尺寸,tuple 的 size 对象 
# torch.Size([5, 3])
x.dim()      # 维度
# 2
x.numel()    # 所有元素个数
# 15

查看值

# 将一个标量Tensor转换成一个Python number
x[0, 0]
# tensor(1.6973)
x[0, 0].item()
# 1.6973174810409546

3.数据操作

tensorAPINumpy 类似。

3.1 操作的类型

API 角度

Pytorch API 角度而言,对 tensor 的操作,可分为两类:

  1. torch.function:如 torch.save()
  2. tensor.function:如 tensor.save()

为方便使用,对 tensor 而言,大部分操作同时支持这两类接口。

存储角度

从存储角度讲,对 tensor 的操作又分为两类:

  1. 不修改自身,而是返回新的 tensor:如 a.add(b)
  2. 对自身进行修改,即 inplace 操作,如:a.add_(b)

3.2 索引操作

索引出来的结果与原数据共享内存,也即修改一个,另一个会跟着修改。

a = t.randn(3,4)
b= a[:, 1]

# tensor([[-1.2908,  1.0193,  1.0039,  0.9335],
#         [ 1.2542, -1.0350, -0.5729, -0.2693],
#         [ 1.2768, -0.7739, -0.0743, -0.3614]])
# tensor([ 1.0193, -1.0350, -0.7739])

3.3 类型转换

各种类型之间可以转换,type(new_type) 是通用做法。而 CPUGPU 之间通过 tensor.cudatensor.cpu 进行转换。

import torch

torch.set_default_tensor_type(torch.FloatTensor)

a = torch.tensor([1., 3])
print(a.dtype)
print(a.device)

# torch.float32
# cpu

3.4 沿指定维度操作

import torch

x = torch.randn(3,4)
print(x)

# 沿着行取最大值。返回 value 和 index
max_value, max_idx = torch.max(x, dim=1)
print(max_value, max_idx)

# 沿着行对x求和
sum_x = torch.sum(x, dim=1)
print(sum_x)

# tensor([[-0.8164, -1.6156,  1.8044, -0.0276],
#         [-0.5526,  0.7886, -0.8338, -0.5740],
#         [-2.0342, -0.6267,  0.2875,  1.2596]])
# tensor([1.8044, 0.7886, 1.2596]) tensor([2, 1, 3])
# tensor([-0.6551, -1.1718, -1.1139])

3.5 修改维数

import torch

x = torch.randn(3,4)
print(x.shape)

# 在指定维度增加
x = x.unsqueeze(0)
print(x.shape)
x = x.unsqueeze(1) # 在第二维增加
print(x.shape)

# 在指定维度减少
x = x.squeeze(0) # 减少第一维
print(x.shape)
x = x.squeeze()
print(x.shape)

# torch.Size([3, 4])
# torch.Size([1, 3, 4])
# torch.Size([1, 1, 3, 4])
# torch.Size([1, 3, 4])
# torch.Size([3, 4])

3.6 维度转置

import torch

x = torch.randn(3,4,5)
print(x.shape)

# 使用permute和transpose进行维度交换
x = x.permute(1,0,2)
print(x.shape)

# transpose交换tensor中的两个维度
x = x.transpose(0,2)
print(x.shape)

# torch.Size([3, 4, 5])
# torch.Size([4, 3, 5])
# torch.Size([5, 3, 4])

3.7 修改尺寸

常用的修改尺寸的方式有 tensor.viewtensor.unsqueeze(),以及 tensor.squeeze() 等。

import torch

# 使用 view 对 tensor 进行 reshape
x = torch.randn(3,4,5)
print(x.shape)

x = x.view(-1, 5)
# -1 表示任意的大小,5 表示第二维变成 5
print(x.shape)

# 重新 reshape 成 (3, 20) 的大小
x = x.view(3,20)
print(x.shape)

# torch.Size([3, 4, 5])
# torch.Size([12, 5])
# torch.Size([3, 20])

除此之外,还有另一种方式,即 resize。与 view 不同,它可以修改 tensor 的尺寸。如果新尺寸总尺寸超过原尺寸,则会自动分配新空间;如果小于,则之前的数据依旧会保留。

a = torch.arange(0, 6)
b = a.view(-1, 3)  # [[0,1,2], [3,4,5]]

b.resize_(1, 3)  # [0,1,2]  仍会保留截断的数据

b.resize_(3,3)   # [[0, 1, 2], [3, 4, 5], [0, 0, 0]]

3.8 转换为列表

通过 tolist() 可以将 tensor 转换为 list,如下所示:

a.tolist()

3.9 其他操作

3.9.1 元素选择
函数功能
index_select(input, dim, index)在指定维度dim上选取
masked_select(input, mask)如:a[a>0],使用ByteTensor 进行选取
non_zero(input)非0元素下标
gather(input, dim, index)根据index,在dim维度上选取数据,输出size与index一致

例如:

a.masked_select(a > 1)  # 等价于 a[a>1]
3.9.2 element-wise 操作
函数功能
abs/sqrt/div/exp/fmod/1og/pow...绝对值/平方根/除法/指数/求余/幂…
cos/sin/asin/atan2/cosh三角函数
ceil/round/floor/trunc上取整/四舍五入/下取整/保留整数
clamp(input,min,max)截断为指定区间的值
sigmoid/tanh...激活函数

例如:

cosine_score = torch.clamp(cosine_score, -1, 1.0)
3.9.3 聚合操作
函数功能
mean/sum/meian/mode均值/和/中位数/众数
norm/dist范数/距离
std/var标准差/方差
cumsum/cumprod累加/累乘

以上大多数函数都有一个参数 dim,表示对指定维度进行聚合运算。

例如:

candidate_norm = torch.norm(candidate, dim=-1)
cosine_score = torch.sum(torch.multiply(query, candidate), dim=-1)
3.9.4 比较运算
函数功能
gt / lt / ge / le / eq / ne大于 / 小于 / 不小于 / 不大于 / 等于 / 不等
topk最大的k个数
sort排序
max / min比较两个tensor的最值

4.广播机制

x = torch.arange(1, 3).view(1, 2)
print(x)
y = torch.arange(1, 4).view(3, 1)
print(y)
print(x + y)

# tensor([[1, 2]])
# tensor([[1],
#         [2],
#         [3]])
# tensor([[2, 3],
#         [3, 4],
#         [4, 5]])

5.Tensor on GPU

if torch.cuda.is_available():
    device = torch.device("cuda")          # GPU
    y = torch.ones_like(x, device=device)  # 直接创建一个在GPU上的Tensor
    x = x.to(device)                       # 等价于 .to("cuda")
    z = x + y
    print(z)
    print(z.to("cpu", torch.double))       # to()还可以同时更改数据类型
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值