tensor是深度学习运算的基本数据结构,本文主要归纳总结了Pytorch中的tensor对象的基础知识,包括它的常用属性、创建方法以及类型转化。
1. Tensor属性
Pytorch中定义了许多类,类就包括属性和行为(方法),Tensor是最基本的类,是用来运算的基本单位。tensor的大多属性都不是基本数据类型,而是Pytorch中定义的类,比如torch.dtype、torch.device等
1.1 torch.dtype
torch.dtype 属性标识了 tensor的数据类型。Pytorch中定义了8种CPU张量类型和对应的GPU张量类型,CPU类型(如torch.FloatTensor)中间加一个cuda即为GPU类型(如torch.cuda.FloatTensor),八种数据类型如下(左一列是Python中的元素数据类型,中间一列是pytorch中tensor的元素数据类型,最后一列是pytorch中tensor的数据类型,有点绕hhh):
| Data type | dtype | Tensor types |
| 32-bit floating point | torch.float32 or torch.float | torch.*.FloatTensor |
| 64-bit floating point | torch.float64 or torch.double | torch.*.DoubleTensor |
| 16-bit floating point | torch.float16 or torch.half | torch.*.HalfTensor |
| 8-bit integer (unsigned) | torch.uint8 | torch.*.ByteTensor |
| 8-bit integer (signed) | torch.int8 | torch.*.CharTensor |
| 16-bit integer (signed) | torch.int16 or torch.short | torch.*.ShortTensor |
| 32-bit integer (signed) | torch.int32 or torch.int | torch.*.IntTensor |
| 64-bit integer (signed) | torch.int64 or torch.long | torch.*.LongTensor |
注意:type()是方法,它返回的是数据本身的数据类型(右侧那列),detype是属性,返回的是其中的数据元素的数据类型(中间一列),在pytorch它两是有一一对应关系的,比如:
1 2 3 4 5 6 7 | x = torch.Tensor([1, 2]) print(x.dtype) # 返回x中的元素的数据类型 print(x.type()) # 返回x的数据类型 # torch.float32 #tensor中的元素的数据类型 torch.FloatTensor #tensor的数据类型 |
需要特别注意tensor的类型,特别是在默认(不指定dtype)情况下创建的类型,只有相同数据类型的tensor才能做运算
1.2 torch.device
torch.device 属性标识了torch.Tensor对象所存储在的设备名称,包含了两种类型 :cpu和cuda ,表示是存在CPU还是GPU,如果是GPU还可以指定具体的卡号,如果没有指定设备编号,则默认将对象存储于current_device()当前设备中。
torch.device 对象支持使用字符串或者字符串加设备编号这两种方式来创建:
1 2 3 4 | cuda0= torch.device('cuda:0') cuda1 = torch.device('cuda', 1) cudax = torch.device('cuda') # 默认当前设备中 cpu = torch.device('cpu') |
但通常我们不会用得这么麻烦,都是直接用字符串来代替,比如:
1 2 3 | cuda1 = torch.device('cuda:1') a = torch.randn((2,3), device=cuda1) b = torch.randn((2,3), device='cuda:1') |
1.3 torch.size
torch.size标识了tensor的形状,虽然是pytorch中的类,但本质上是tuple,获取tensor的size可以通过 tensor.shape或tensor.size(),一个是属性一个是方法,结果都一样。torch.size用法和tuple一样,比如:
1 2 3 4 5 6 7 8 | a = torch.randn(size=(1,2)) b = a.shape c = a.size() print(b, type(b), b[0]) print(c, type(c), c[1]) # torch.Size([1, 2]) <class 'torch.Size'> 1 torch.Size([1, 2]) <class 'torch.Size'> 2 |
2. Tensor创建
在PyTorch中创建一个tensor从宏观上看主要有2种:一种是使用torch提供的方法,一种是实例化Tensor类
2.1 torch方法创建
为了满足多样化的需求,torch提供了许多方法来创建tensor。
- 大多方法都有size、dtype、device、requires_grad(默认False)几个参数
- 创建浮点数的方法默认(不设置dtype)情况下都是torch.float32(torch.FloatTensor),创建整形的方法默认是torch.int64(torch.LongTensor),这个需要特别注意!!不同类型的tensor不能作运算
- size就是元组,可以通过tensor.size()得到,创建一维tensor最好写成(m, ),要是写m有些方法会报错*
torch方法创建tensor主要分三类:
- 按照特定规则创建,比如随机和特定数值
常见的随机创建方法有:
1 2 3 4 5 6 7 | torch.randn(size):均值为0,方差为1的正态分布N(0,1) torch.rand(size):产生[0,1]均匀分布的数据 torch.randint(low = 0, high, size):随机生成整数值tensor,范围 [min,max):左闭右开 每种方法都有一个like(input)方法,表示创建同input一样size的tensor,比如torch.rand_like(input) |
常见的特定数值创建方法有:
1 2 3 4 5 6 7 | torch.arange(start, end, step) :生成一维的**整形**等差数列tensor, [start,end) 左闭右开,间隔为step(公差)默认为1 torch.linspace(start, end, steps) : 生成一维的**浮点**等差数列tensor,包括end, steps 是点的个数,注意和arrange的区别 torch.full(size, fill_value) :使用相同元素创建tensor,注意默认类型是**torch.float32** torch.zeros(size):全0tensor,类似还有全1, 注意默认类型是**torch.float32** |
- 从python 对象中创建
1 2 | torch.tensor(data, dtype):data可以是list、tuple,如果data的元素是浮点数, 默认创建出来的就是torch.float32(torch.FloatTensor),如果是整形,默认是torch.int64(torch.LongTensor) |
- 从numpy对象中创建
这个好像用的少一点
1 | torch.from_numpy(x):x是ndarry对象,创建出来的tensor类型和x保持一致 |
2.2 实例化torch.Tensor创建
另一种方法是通过实例化Tensor类来创建tensor,结果都是一样的。因为tensor有不同的数据类型,所以Tensor也有为不同的类,可以指定特定类型的类来创建特定类型的tensor,比如:
1 2 3 4 5 6 7 8 | torch.FloatTensor(data):data可以是list、tuple,它的另一个别名是torch.Tensor() 这个更常用些 类似的还有: torch.LongTensor() torch.DoubleTensor() torch.IntTensor() … 其它类型见八中数据类型表 |
3. 类型转化
上面我们讲了tensor对象它有device属性,这区分了它是存在GPU还是CPU,有dtype属性,这区分了它的元素是什么类型,也有从不同对象中(Python、numpy)创建而来的,这就涉及一个这些不同对象之间的转化问题。
- 数据类型转化
在tensor后加 .long(), .int(), .float(), .double()等即可,比如
1 2 3 4 5 6 7 8 9 10 | a = torch.randn((4,), dtype=torch.float) b = a.int() c = a.double() print( a.dtype) print(b.dtype) print(c.dtype) # torch.float32 torch.int32 torch.float64 |
-
数据存储位置转换
CPU张量 ----> GPU张量:data.cuda()
GPU张量 ----> CPU张量:data.cpu() -
与Python数据类型转换
Tensor ----> Python list,使用data.tolist(),返回shape相同的嵌套的list
如果data是一个一维的而且只有一个数(1, ),可以用data.item()来得到Python单个数据 -
与numpy数据类型转换
Tensor---->Numpy : data.numpy()
Numpy ---->Tensor:torch.from_numpy(data)