Pytorch基础操作 —— 4. 创建 Tensor 的一般方法

创建 Tensor 的一般方法

在很多时候,我们需要创建一些 tensor,PyTorch 为我们提供了丰富的 tensor 创建方案,在这篇文章里,让我们来看看都有哪些可以使用。

一般函数共用参数

这主要是指,针对 randn、empty、zeros、ones 等函数时,我们可以在创建 tensor 时,可以指定的其他参数。

size
定义输出张量的维度,输入形式为列表或者元组。

import torch

tensor = torch.ones(size=(4, 4))

输出结果如下:

tensor([[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.]])

out (Tensor, optional)
输出张量指向的引用,一般不使用

dtype (torch.dtype, optional)
输出的张量数据类型,不指定的时候,使用默认数据类型。采用默认的函数创建的tensor,一般情况下都是 float32 类型,或者根据输入的原始数据类型,来决定tensor的类型。不同类型的tensor在计算上存在着精度丢失的问题,所以有时候需要你手工指定。

import torch

tensor = torch.ones(size=(4, 4), dtype=torch.float32)

我们可以使用并定义的数据类型如下:

Data typedtypeCPU tensorGPU tensor
32-bit floating pointtorch.float32 or torch.floattorch.FloatTensortorch.cuda.FloatTensor
64-bit floating pointtorch.float64 or torch.doubletorch.DoubleTensortorch.cuda.DoubleTensor
16-bit floating pointtorch.float16 or torch.halftorch.HalfTensortorch.cuda.HalfTensor
8-bit integer (unsigned)torch.uint8torch.ByteTensortorch.cuda.ByteTensor
8-bit integer (signed)torch.int8torch.CharTensortorch.cuda.CharTensor
16-bit integer (signed)torch.int16 or torch.shorttorch.ShortTensortorch.cuda.ShortTensor
32-bit integer (signed)torch.int32 or torch.inttorch.IntTensortorch.cuda.IntTensor
64-bit integer (signed)torch.int64 or torch.longtorch.LongTensortorch.cuda.LongTensor

layout (torch.layout, optional)
这个是比较涉及底层的操作,它指定某个tensor底层的数据逻辑组织方式。通常不需要单独指定,你如果需要指定layout,应该确保所有参与计算的每个tensor都遵循同样的数据布局。默认为 torch.strided.

>>> x = torch.tensor([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
>>> x.stride()
(5, 1)

>>> x.t().stride()
(1, 5)

device (torch.device, optional)
指定创建的tensor,它的数据存储的物理存储位置,默认是在CPU内存上划分区块,不过如果你的程序需要全部跑在GPU上,那么为了减少不必要的内存开销,在创建tensor的时候,一并指定设备内存会更好一些。默认值:”cpu“。

requires_grad (bool, optional)
求梯度的时候,是否需要保留梯度信息,默认为关闭。建议没事别动这个参数,如果你把这个参数设置为 True,那么就会在每一次运算的时候都会保留计算图,从而占用大量的内存。它的默认值:False. 那么是一直使用它的默认设置吗? 也不是, 通常在做网络迭代的时候, 为了验证参数的正确性, 会打开这个设置, 不过在你熟悉了这个框架后, 你再根据具体情况进行设置, 刚入门的时候就不用管了。

pin_memory (bool, optional)
它表示返回的tensor,会被存储在固定内存/锁页内存(the Pinned Memory)上。如果你有GPU的话,可以使用它来加速数据从CPU拷贝到GPU的过程。不过由于此块内存区域有限,使用时要谨慎一些。默认值:False。

memory_format (torch.memory_format, optional)
tensor的物理存储组织形式,默认数据是以连续形式创建,通常没必要碰这玩意。默认值:torch.contiguous_format.

创建空的张量 torch.empty(…)

有些时候我们需要创建空的张量,对于torch来说,可以使用 torch.empty 方法创建空白张量,函数原型如下:

 torch.empty(*size, *, 
 	out=None, 
 	dtype=None, 
 	layout=torch.strided, 
 	device=None, 
 	requires_grad=False, 
 	pin_memory=False, 
 	memory_format=torch.contiguous_format) -> Tensor

例程

>>> a = torch.empty((2,3), dtype=torch.int32, device = 'cuda')
>>> torch.empty_like(a)
tensor([[0, 0, 0],
        [0, 0, 0]], device='cuda:0', dtype=torch.int32)

创建随机数值的张量 torch.rand(…)

尽管我个人认为包含随机变量的张量一般没什么用,不过用来做测试的时候,还是可以用的。其函数原型如下:

 torch.rand(*size, *, 
 	out=None, 
 	dtype=None, l
 	ayout=torch.strided, 
 	device=None, 
 	requires_grad=False) -> Tensor

例程

>>> torch.rand(4)
tensor([ 0.5204,  0.2503,  0.3525,  0.5673])
>>> torch.rand(2, 3)
tensor([[ 0.8237,  0.5781,  0.6879],
        [ 0.3816,  0.7249,  0.0998]])

创建全0的张量 torch.zeros(…)

用处要更大一些,torch.empty 虽然常用,但是由于内部数值不一定都会初始化为0,所以在使用时有时候不小心会带入一些”脏东西“进去,所以我们更多的会使用创建时同时初始化的tensor。

函数原型为:

torch.zeros(*size, *, 
	out=None, 
	dtype=None, 
	layout=torch.strided, 
	device=None, 
	requires_grad=False) -> Tensor

例程

>>> torch.zeros(2, 3)
tensor([[ 0.,  0.,  0.],
        [ 0.,  0.,  0.]])

>>> torch.zeros(5)
tensor([ 0.,  0.,  0.,  0.,  0.])

创建全1的张量 torch.ones(…)

它的作用跟 zeros 相似,函数原型为:

torch.ones(*size, *, 
    out=None, 
    dtype=None, 
    layout=torch.strided, 
    device=None, 
    requires_grad=False) -> Tensor

例程

>>> torch.ones(2, 3)
tensor([[ 1.,  1.,  1.],
        [ 1.,  1.,  1.]])

>>> torch.ones(5)
tensor([ 1.,  1.,  1.,  1.,  1.])

创建顺序的张量 torch.arrange(…)

它的作用是创建一个顺序增加的一维张量。其函数原型:

torch.arange(start=0, end, step=1, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor

新建张量每一位的计算公式如下:

o u t i + 1 = o u t i + s t e p out_{i+1} = out_i + step outi+1=outi+step

例程

>>> torch.arange(5)
tensor([ 0,  1,  2,  3,  4])
>>> torch.arange(1, 4)
tensor([ 1,  2,  3])
>>> torch.arange(1, 2.5, 0.5)
tensor([ 1.0000,  1.5000,  2.0000])

Numpy 与 Tensor

在以Python为代表的数学框架,基本上都是建立在numpy之上的。

这是一种比python list更快,且用C实现的矩阵计算框架。所以Python并不擅长的数值计算,由于Numpy的存在而大大加强。所以也可以认为是Numpy成就了Python在今天数据数值分析、统计领域一哥的位置。

自然,在Numpy的加持下,大部分的科学计算框架都集成或融合了Numpy,这也使得原本在其他语言上需要花费很多时间编码的内存对齐这件事,Python上就变得十分轻巧而方便。

所以,Pytorch也不例外,尽管底层是自有的数据结构,但是依然提供了对Numpy的支持。所以我们可以轻易的把从诸如Pandas, OpenCV, OpenGL, scikit-learn 等框架的数据与Torch,通过Numpy进行对接。

从Numpy到Tensor

函数原型为:

torch.from_numpy(ndarray) → Tensor

例程

>>> nparray = numpy.array([1, 2, 3])
>>> tensor = torch.from_numpy(nparray, dtype=torch.float32)
>>> tensor
tensor([ 1,  2,  3])
>>> tensor[0] = -1
>>> nparray
array([-1,  2,  3])

使用Numpy的Copy命令创建备份

上面这个例子可以看见,torch只是把numpy的数据封装了一遍,如果希望 Torch 处理的数据与 Numpy 在物理上是隔离的,可以使用 copy 命令

>>> import torch
>>> import numpy
>>> arr1 = numpy.array([1, 2, 3])
>>> arr2 = arr1.copy()
>>> tensor = torch.from_numpy(arr2)
>>> tensor[0] = -1
>>> tensor
tensor([-1,  2,  3])
>>> arr1
[1 2 3]

创建Numpy时指定数据类型

由于Numpy到Tensor,不能指定Tensor的类型,所以最好在创建Numpy的时候,指定数据的类型。

>>> import torch
>>> import numpy
>>> arr1 = numpy.array([1, 2, 3], dtype=numpy.float32)
>>> tensor = torch.from_numpy(arr1)
>>> tensor
tensor([1., 2., 3.])

修改Numpy的数据类型

如果不能做到从Numpy创建之初就指定数据类型,那么可以用 astype 命令。

>>> import torch
>>> import numpy
>>> arr1 = numpy.array([1, 2, 3])
>>> arr2 = arr1.astype(numpy.float32)
>>> tensor = torch.from_numpy(arr2)
tensor
tensor([1., 2., 3.])

从Tensor到Numpy

数据处理完毕后,我们有时候会想把数据导回 Numpy,用于其他的后续处理,方法很简单,只要这样就可以了:

t = torch.ones(5)
n = t.numpy()

从Python列表、元组赋值

除了以上方法,我们还可以通过Python自己的基本数据类型创建Tensor:

torch.tensor(data, *, 
	dtype=None, 
	device=None, 
	requires_grad=False, 
	pin_memory=False) -> Tensor

例程

>>> torch.tensor([[0.1, 1.2], [2.2, 3.1], [4.9, 5.2]])
tensor([[ 0.1000,  1.2000],
        [ 2.2000,  3.1000],
        [ 4.9000,  5.2000]])

>>> torch.tensor([0, 1])  # Type inference on data
tensor([ 0,  1])

>>> torch.tensor([[0.11111, 0.222222, 0.3333333]],
...              dtype=torch.float64,
...              device=torch.device('cuda:0'))  # creates a torch.cuda.DoubleTensor
tensor([[ 0.1111,  0.2222,  0.3333]], dtype=torch.float64, device='cuda:0')

>>> torch.tensor(3.14159)  # Create a scalar (zero-dimensional tensor)
tensor(3.1416)

>>> torch.tensor([])  # Create an empty tensor (of size (0,))
tensor([])

从Tensor到List

我们有时候也会想这样一个问题,我能不能把Tensor转换回 Python.List

data = tensor.tolist()

从Tensor到Scalar

与上面这个方法不太一样,这是把Tensor中的某个具体元素转换为Python整数或浮点数

num = tensor[0].item()

但是一定要记住,这个函数只能对某个具体的值做转换,如果试图对一组Tensor,比如列表、矩阵做转化,那会导致最终的报错。

创建和其他Tensor维度一样的Tensor

如果我们想创建一个维度和其他Tensor一致的Tensor,主要用到这样这么几个函数。首先,假设我们有了一个Tensor

data = [[1, 2], [3, 4]]
x_data = torch.tensor(data)

然后分别创建全零、全一、随机Tensor

x_ones = torch.ones_like(x_data) # retains the properties of x_data
print(f"Ones Tensor: \n {x_ones} \n")

x_rand = torch.rand_like(x_data, dtype=torch.float) # overrides the datatype of x_data
print(f"Random Tensor: \n {x_rand} \n")

x_zeros = torch.zeros_like(x_data)
print(f"Zeros Tensor: \n {x_zeros} \n")

x_empty = torch.empty_like(x_data)
print(f"Empty Tensor: \n {x_empty} \n")
  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这段代码是一个用于加载和预处理CIFAR10数据集的示例代码,并打印出一个batch的输入x和对应的标签label。以下是对代码逐行的解释: 1. `batchsz = 128` 设置批量大小为128,即每次训练和测试时处理的样本数量。 3-11. 加载训练集数据: - `datasets.CIFAR10('cifar', True, transform=transforms.Compose([...]))` 创建一个CIFAR10数据集对象,指定数据集存储路径为'cifar',训练集为True。 - `transforms.Resize((32, 32))` 将图像大小重新调整为32x32像素。 - `transforms.ToTensor()` 将图像转换为Tensor对象,以便在PyTorch中进行处理。 - `transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])` 对图像进行归一化处理,使其均值为0.485、0.456、0.406,标准差为0.229、0.224、0.225。 - `download=True` 如果数据集不存在,则下载CIFAR10数据集。 - `DataLoader(cifar_train, batch_size=batchsz, shuffle=True)` 创建一个数据加载器,用于批量加载和处理训练集数据。 13-21. 加载测试集数据: - `datasets.CIFAR10('cifar', False, transform=transforms.Compose([...]))` 创建一个CIFAR10数据集对象,指定数据集存储路径为'cifar',训练集为False。 - `transforms.Resize((32, 32))` 将图像大小重新调整为32x32像素。 - `transforms.ToTensor()` 将图像转换为Tensor对象,以便在PyTorch中进行处理。 - `transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])` 对图像进行归一化处理,使其均值为0.485、0.456、0.406,标准差为0.229、0.224、0.225。 - `download=True` 如果数据集不存在,则下载CIFAR10数据集。 - `DataLoader(cifar_test, batch_size=batchsz, shuffle=True)` 创建一个数据加载器,用于批量加载和处理测试集数据。 23. `x, label = iter(cifar_train).next()` 通过iter函数将cifar_train转换为迭代器,并调用next方法获取一个batch的训练数据。x表示输入的图像数据,label表示对应的标签。 24. `print('x:', x.shape, 'label:', label.shape)` 打印出输入x和标签label的形状信息。 这段代码的主要目的是加载CIFAR10数据集并进行预处理,以便用于模型的训练和测试。同时,通过打印出一个batch的输入和标签信息,可以验证数据加载和预处理是否正确。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值