从0开始学pytorch【3】--张量数据类型
- 前言
- 学习目标
- 基本数据类型
- 创建tensor
- 索引、切片
- 小结
前言
在前两篇博文中,从0开始学pytorch【1】–线性函数的梯度下降、从0开始学pytorch【2】——手写数字集案例中介绍了人工智能入门最为基础的梯度下降算法实现,以及机器学习、深度网络编程基本流程。
请自行安装适配版本的torch。如果你需要安装GPU加速版本Torch,可以参照:RTX 3060配置CUDA和cuDNN、安装PyTorch,其他版本系列的显卡与之类似。本系列代码均为在jupyter notebook中运行完成,请自主创建虚拟环境,并配置好开发环境。
学习目标
从本篇开始,博文将从最为基础的张量数据类型、如何创建tensor开始学习,就好比学习python时,先学习什么是列表、元组等,直到完全自主构造出复杂的深度网络并传入自定义数据成功运行。
本篇学习内容
基本数据类型
python中的数据类型与tensor的数据类型对比。python中的字符串在tensor中没有对应的类型,tensor是张量,主要处理的是“数字”,如果要处理字符串,需要先将字符串转为数字,tensor才能处理。
python | PyTorch |
int | inttensor of size() |
float | FloatTensor of size() |
int array | intTensor of size[d1,d2,…] |
Float array | FloatTensor of size[d1, d2, …] |
string | — |
import torch
a = torch.randn(2,3) # 标准高斯随机数
print(a)
print(a.type)
print(type(a))
print(isinstance(a, torch.FloatTensor))
'''
输出:
tensor([[ 1.0753, -0.0644, -2.3731],
[-1.2818, 0.9982, 1.6261]])
<built-in method type of Tensor object at 0x0000020AA418E0C0>
<class 'torch.Tensor'>
True
'''
torch的好处就是可以便捷实现GPU加速。默认tensor数据是放在CPU上面的,但可以通过cuda放在GPU上面。
data = torch.randn(2,3)
print(data.device)
data = data.cuda()
print(data.device)
isinstance(data, torch.cuda.DoubleTensor)
'''
输出
cpu
cuda:0
False
'''
直接创建一个标量
torch.tensor(1.), torch.tensor(1.3)
'''
输出
(tensor(1.), tensor(1.3000))
'''
查看tensor变量的“维”,标量对应为dim=0, 向量对应为dim=1,矩阵对应为dim=2,3维张量对应为dim=3,依次类推。这样的规则和tensorflow一致。
a = torch.tensor(2.2)
print(a.shape, len(a.shape), a.size())
'''
输出
torch.Size([]) 0 torch.Size([])
'''
生成向量
torch.tensor([1.11]), torch.tensor([1.1, 2.2, 3.4])
'''
输出
(tensor([1.1100]), tensor([1.1000, 2.2000, 3.4000]))
'''
随机初始化
torch.FloatTensor(5)
'''
输出
tensor([6.3058e-44, 6.7262e-44, 7.1466e-44, 6.3058e-44, 6.8664e-44])
'''
tensor和numpy有许多相似之处,或者说numpy和tensor之前非常紧密。
import numpy as np
data = np.ones(2)
data
'''
输出
array([1., 1.])
'''
将numpy转为tensor
torch.from_numpy(data)
'''
输出
tensor([1., 1.], dtype=torch.float64)
'''
- numpy比pandas 在深度学习中更加受欢迎
- dim 是指一共有几个维度,比如,长宽高3个维度
- size,shape, 指的是,[2, 2, 6],具体形状
- tensor 就是 具体数值
创建2维度tensor,dim=2,dim=3。[0,1]区间的均匀分布。
a = torch.rand(2,3)
a
'''
输出
tensor([[0.0219, 0.2349, 0.2174],
[0.9983, 0.4190, 0.8041]])
'''
# torch.rand 均匀分布
a = torch.rand(2, 2, 3)
a
'''
tensor([[[0.3968, 0.4470, 0.9715],
[0.4955, 0.3495, 0.1292]],
[[0.1746, 0.8058, 0.0195],
[0.8069, 0.0932, 0.8258]]])
'''
查看维度
a.shape
'''
torch.Size([2, 3])
'''
简单索引
a[0], a[0][0]
'''
(tensor([0.0219, 0.2349, 0.2174]), tensor(0.0219))
'''
查看shape
list(a.shape)
'''
[2, 3]
'''
dim=3, 适用rnn自然语言处理,dim=4适用于cnn图片数据。在本专栏中也会详细讲解rnn和cnn网络。
a = torch.rand(2, 3, 4, 4)
a
'''
tensor([[[[0.8399, 0.2434, 0.5270, 0.0887],
[0.1645, 0.7509, 0.9101, 0.0221],
[0.1977, 0.4140, 0.4865, 0.4262],
[0.7162, 0.0587, 0.7144, 0.0167]],
[[0.6846, 0.4662, 0.0519, 0.2674],
[0.6867, 0.0318, 0.0291, 0.9790],
[0.2822, 0.6616, 0.3969, 0.3447],
[0.4841, 0.9506, 0.2636, 0.2979]],
[[0.1976, 0.9796, 0.5986, 0.9721],
[0.9621, 0.4665, 0.0261, 0.8652],
[0.4392, 0.5551, 0.8391, 0.3831],
[0.8881, 0.8574, 0.5706, 0.4185]]],
[[[0.4116, 0.8071, 0.9701, 0.6361],
[0.1729, 0.4556, 0.8821, 0.6383],
[0.7171, 0.6803, 0.3309, 0.4817],
[0.4309, 0.1841, 0.1067, 0.2243]],
[[0.2967, 0.4904, 0.0102, 0.9429],
[0.4744, 0.1564, 0.3656, 0.7188],
[0.2192, 0.6564, 0.6573, 0.9538],
[0.6782, 0.9565, 0.3695, 0.2114]],
[[0.1950, 0.5392, 0.9727, 0.2925],
[0.7348, 0.7432, 0.6725, 0.0173],
[0.4818, 0.9278, 0.1491, 0.8513],
[0.2923, 0.7817, 0.5649, 0.4202]]]])
'''
注意,传入的参数是2,3,4,4,即dim=4, shape为(2,3,4,4)。numel指tensor占用内存的数量,即234*4=96
a.numel(), a.dim(), a.shape
'''
(96, 4, torch.Size([2, 3, 4, 4]))
'''
创建tensor
从numpy转换而来
import torch
import numpy as np
a = np.array([2,3.3])
print(torch.from_numpy(a))
a = np.ones([2,3])
torch.from_numpy(a)
'''
tensor([2.0000, 3.3000], dtype=torch.float64)
tensor([[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
'''
未初始化的数据,非常随机不规则
# uninitialized
# Torch.empty()
# Torch.FloatTensor(d1, d2, d3)
# Torch.IntTensor(d1, d2, d3)
一些未初始化的例子
print(torch.empty(1))
print(torch.Tensor(2,3))
print(torch.IntTensor(2, 3))
print(torch.FloatTensor(2,3))
'''
tensor([1.4013e-45])
tensor([[0.0000e+00, 1.4764e-41, 5.4423e+22],
[2.1765e-04, 3.3091e+21, 2.1509e+23]])
tensor([[ 0, 10536, 1698194530],
[ 962869606, 1664312117, 1714827318]], dtype=torch.int32)
tensor([[0.0000e+00, 1.4764e-41, 5.4423e+22],
[2.1765e-04, 3.3091e+21, 2.1509e+23]])
'''
tensor默认类型
print(torch.tensor([1.2, 3]).type())
#设置默认类型 一般用在增强学习,高梯度
torch.set_default_tensor_type(torch.DoubleTensor)
print(torch.tensor([1.2,3]).type())
# 改回float默认类型
torch.set_default_tensor_type(torch.FloatTensor)
print(torch.tensor([1,2,3]).type())
'''
torch.FloatTensor
torch.DoubleTensor
torch.LongTensor
'''
rand [0,1]均匀分布
print(torch.rand(3,3))
a = torch.rand(3,3)
print(torch.rand_like(a))
#形状为[3,3], 最小值为1,最大值为9(左闭右开)整数
print(torch.randint(1,10,[3,3]))
'''
tensor([[0.9190, 0.2691, 0.9920],
[0.5854, 0.6713, 0.4939],
[0.4771, 0.8958, 0.0427]])
tensor([[0.5234, 0.8439, 0.5189],
[0.4048, 0.3987, 0.5754],
[0.8243, 0.6039, 0.9390]])
tensor([[2, 4, 5],
[6, 9, 5],
[7, 6, 2]])
'''
正态分布
print(torch.randn(3,3))
print(torch.normal(mean=torch.tensor(1.), std=torch.tensor(2.)))
torch.normal(mean=torch.full([10],0.), std=torch.arange(1, 0, -0.1))
'''
tensor([[ 0.2172, 0.3820, 0.1418],
[ 2.0482, 0.7290, 1.3084],
[ 0.9253, -0.0887, -1.1670]])
tensor(1.2668)
tensor([-1.2659, 0.6446, 0.4346, -0.0523, 0.1593, 0.0841, -0.5353, 0.0100,
0.2775, -0.0740])
'''
填充full
print(torch.full([2,3], 7))
torch.full([10], 0.)
torch.full([], 6)
'''
tensor([[7, 7, 7],
[7, 7, 7]])
tensor(6)
'''
循环arange\ range
torch.arange(10),torch.arange(2,10),torch.arange(0, 10, 2),torch.range(0, 10)
'''
(tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
tensor([2, 3, 4, 5, 6, 7, 8, 9]),
tensor([0, 2, 4, 6, 8]),
tensor([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]))
'''
切分linspace/logspace
print(torch.linspace(0, 10, steps=4))
print(torch.linspace(0, 10, steps=10))
print(torch.linspace(0, -10, steps=11))
# 0到-1切割10份,再10的多少次方
print(torch.logspace(0, -1, steps=10))
print(torch.logspace(0, 1, steps=4))
'''
tensor([ 0.0000, 3.3333, 6.6667, 10.0000])
tensor([ 0.0000, 1.1111, 2.2222, 3.3333, 4.4444, 5.5556, 6.6667, 7.7778,
8.8889, 10.0000])
tensor([ 0., -1., -2., -3., -4., -5., -6., -7., -8., -9., -10.])
tensor([1.0000, 0.7743, 0.5995, 0.4642, 0.3594, 0.2783, 0.2154, 0.1668, 0.1292,
0.1000])
tensor([ 1.0000, 2.1544, 4.6416, 10.0000])
'''
ones\zeros\eye(单位阵)
torch.ones(3,3), torch.zeros(3,3), torch.eye(3,4), torch.eye(4,2), torch.eye(4,4)
'''
(tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]]),
tensor([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]]),
tensor([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.]]),
tensor([[1., 0.],
[0., 1.],
[0., 0.],
[0., 0.]]),
tensor([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]]))
'''
_like 方法
a = torch.zeros(3,3)
torch.ones_like(a),torch.zeros_like(a), torch.full_like(a, 4)
'''
(tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]]),
tensor([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]]),
tensor([[4., 4., 4.],
[4., 4., 4.],
[4., 4., 4.]]))
'''
randperm, 类似于tf.gather
print(torch.randperm(10))
idx = torch.randperm(3)
a = torch.tensor([[1,1,1],
[2,2,2],
[3,3,3]])
print(a)
print(idx)
a[idx]
'''
tensor([7, 5, 6, 4, 0, 3, 9, 8, 2, 1])
tensor([[1, 1, 1],
[2, 2, 2],
[3, 3, 3]])
tensor([0, 2, 1])
tensor([[1, 1, 1],
[3, 3, 3],
[2, 2, 2]])
'''
索引、切片
索引、切片基本同tensorflow用法
a = torch.rand(4,3, 28, 28)
print(a[0].shape)
print(a[0,0].shape)
print(a[0,0,2,4])
print(a.shape)
print(a[:2, -1:, :, :].shape)
'''
torch.Size([3, 28, 28])
torch.Size([28, 28])
tensor(0.5597)
torch.Size([4, 3, 28, 28])
torch.Size([2, 1, 28, 28])
'''
index_select 索引
a = torch.rand(4, 3, 28, 28)
# 在0维度上,采取0,和2两个元素
print(a.index_select(0, torch.tensor([0, 2])).shape)
print(a.index_select(1, torch.tensor([1, 2])).shape)
print(a.index_select(2, torch.arange(28)).shape)
print(a.index_select(2, torch.arange(8)).shape)
print(a.shape)
'''
torch.Size([2, 3, 28, 28])
torch.Size([4, 2, 28, 28])
torch.Size([4, 3, 28, 28])
torch.Size([4, 3, 8, 28])
torch.Size([4, 3, 28, 28])
'''
。。。短省略号,表示自动填充
a = torch.randn(4, 3,28, 28)
print(a[...].shape)
print(a[2, ...].shape)
print(a[...,:2].shape)
print(a[2, ..., 3:].shape)
'''
torch.Size([4, 3, 28, 28])
torch.Size([3, 28, 28])
torch.Size([4, 3, 28, 2])
torch.Size([3, 28, 25])
'''
mask:masked_select\ge
x = torch.randn(3, 4)
print(x)
# 不小于0.5为True
mask = x.ge(0.5)
print(mask)
print(torch.masked_select(x, mask))
print(torch.masked_select(x, mask).shape)
x = torch.tensor([[0, -1, 2.],[0.5, 0.6, -1],[1, 2, 2]])
print(x)
mask = x.ge(0.5)
print(mask)
'''
tensor([[-1.5646, 2.8307, 0.6621, 2.8751],
[ 0.6734, 0.9292, -0.2518, -0.9087],
[-0.4124, 1.2675, -0.3262, -1.4600]])
tensor([[False, True, True, True],
[ True, True, False, False],
[False, True, False, False]])
tensor([2.8307, 0.6621, 2.8751, 0.6734, 0.9292, 1.2675])
torch.Size([6])
tensor([[ 0.0000, -1.0000, 2.0000],
[ 0.5000, 0.6000, -1.0000],
[ 1.0000, 2.0000, 2.0000]])
tensor([[False, False, True],
[ True, True, False],
[ True, True, True]])
'''
take 先打平,再找
src = torch.tensor([[4,3,2],
[2,5,9]])
torch.take(src,torch.tensor([0,3,5]))
'''
tensor([4, 2, 9])
'''
小结
1、学习了dim=0、1、2、3、4的tensor随机数生成,以及dim=0、1、2的手动构造。
2、学习了基本数据类型、张量的索引、切片,以及一些常用的方法。