Pytorch_2.2_数据结构
2.2 数据结构
- torch.Tensor 是存储和变换数据的主要工具
2.2.1 创建TENSOR
首先导入PyTorch
import torch
创建一个5x3的未初始化的Tensor
x = torch.empty(5,3)
print(x)
tensor([[9.2755e-39, 1.0561e-38, 1.0929e-38],
[1.0102e-38, 9.7347e-39, 4.2246e-39],
[1.0286e-38, 1.0653e-38, 1.0194e-38],
[8.4490e-39, 1.0469e-38, 9.3674e-39],
[9.9184e-39, 8.7245e-39, 9.2755e-39]])
创建一个5x3的随机初始化Tencor
x = torch.rand(5,3)
print(x)
tensor([[0.8809, 0.5242, 0.8139],
[0.1677, 0.4035, 0.3680],
[0.4707, 0.9393, 0.5377],
[0.7676, 0.7518, 0.4257],
[0.7233, 0.4705, 0.3036]])
创建一个全0的long型Tensor
x = torch.zeros(5,3,dtype = torch.long)
print(x)
print(x[1][1])
print(type(x[1][1]))
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
tensor(0)
<class 'torch.Tensor'>
还可以根据数据直接创建Tensor
x = torch.tensor([6.6,8])
print(x)
tensor([6.6000, 8.0000])
通过现有的Tensor 来创建新的数据
y =x.new_ones(5,3,dtype = torch.float64)
print(y)
z = torch.randn_like(y,dtype = torch.float)
print(z)
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
tensor([[ 0.3913, 1.5179, 1.6415],
[ 1.2150, -0.1650, -0.7815],
[-0.2489, 0.5252, -1.2605],
[ 0.5305, 0.1410, -0.6449],
[-1.4771, 0.1270, 0.6471]])
可以通过shape 或者 size() 来获取Tensor 的数据形状
print(y.size())
print(y.shape)
# torch.size 的类型是 tuple
torch.Size([5, 3])
torch.Size([5, 3])
函数 | 功能 |
---|---|
Tensor(*sizes) | 基础构造函数 |
tensor(data,) | 类似np.array的构造函数 |
ones(*sizes) | 全1Tensor |
zeros(*sizes) | 全0Tensor |
eye(*sizes) | 对⻆线为1,其他为0 |
arange(s,e,step) | 从s到e,步⻓为step |
linspace(s,e,steps) | 从s到e,均匀切分成steps份 |
rand/randn(*sizes) | 均匀/标准分布 |
normal(mean,std)/uniform(from,to) | 正态分布/均匀分布 |
randperm(m) | 随机排列 |
2.2.2 操作
算数操作
- 加法 直接利用加号
x = torch.rand(5,3)
y = torch.rand(5,3)
print(x + y)
tensor([[1.4692, 0.7374, 0.7234],
[0.8925, 0.7805, 1.3061],
[0.8631, 1.8786, 1.5237],
[0.9812, 0.9703, 1.0981],
[1.1590, 0.7849, 1.1890]])
print(torch.add(x,y))
tensor([[1.4692, 0.7374, 0.7234],
[0.8925, 0.7805, 1.3061],
[0.8631, 1.8786, 1.5237],
[0.9812, 0.9703, 1.0981],
[1.1590, 0.7849, 1.1890]])
- 还可以指定输出
result = torch.empty(5,3)
torch.add(x,y,out = result)
print(result)
# 可以直接指定
result = torch.add(x,y)
print(result)
tensor([[1.4692, 0.7374, 0.7234],
[0.8925, 0.7805, 1.3061],
[0.8631, 1.8786, 1.5237],
[0.9812, 0.9703, 1.0981],
[1.1590, 0.7849, 1.1890]])
tensor([[1.4692, 0.7374, 0.7234],
[0.8925, 0.7805, 1.3061],
[0.8631, 1.8786, 1.5237],
[0.9812, 0.9703, 1.0981],
[1.1590, 0.7849, 1.1890]])
- 另一种加法
y.add(x)
print(y)
tensor([[0.5895, 0.4489, 0.3473],
[0.0495, 0.6829, 0.5846],
[0.2628, 0.9495, 0.9024],
[0.3175, 0.9222, 0.5868],
[0.1993, 0.7389, 0.7718]])
索引
可以利用类似NumPy的索引方式访问Tensor的一部分。索引的结果和原数据共享一个内存
y = x[0,:]
y += 1
print(y)
print(x[0,:])
# 索引的数据修改后也改变了原数据
tensor([1.8798, 1.2886, 1.3761])
tensor([1.8798, 1.2886, 1.3761])
其他一些函数
函数 | 功能 |
---|---|
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⼀样 |
改变Tensor的形状
可以用view()来改变Tensor的形状,就是改变矩阵的行列
y = x.view(15) # 将5行3列的矩阵改变为一维行向量
z = x.view(-1,5) # -1 表示该位置自动识别,后面是5列 所以-1位置应该为3
print(x.size(),y.size(),z.size())
torch.Size([5, 3]) torch.Size([15]) torch.Size([3, 5])
这里的新tensor与原tensor共享内存,一改则都改
如果需要复制可以使用clone再使用view
x_cp = x.clone().view(15)
x -= 1
print(x)
print(x_cp)
tensor([[ 0.8798, 0.2886, 0.3761],
[-0.1569, -0.9025, -0.2784],
[-0.3997, -0.0710, -0.3788],
[-0.3363, -0.9519, -0.4887],
[-0.0403, -0.9539, -0.5827]])
tensor([1.8798, 1.2886, 1.3761, 0.8431, 0.0975, 0.7216, 0.6003, 0.9290, 0.6212,
0.6637, 0.0481, 0.5113, 0.9597, 0.0461, 0.4173])
item() 可以将标量的Tensor转换成Python number
x = torch.randn(1)
print(x)
print(x.item())
tensor([-0.5851])
-0.585087776184082
- torch.rand() 与 torch.randn()
torch.rand() 是均匀分布([0,1]之间随机抽取)
torch.randn() 是标准正态分布(均值为0 方差为1)
线性代数
函数 | 功能 |
---|---|
trace | 对⻆线元素之和(矩阵的迹) |
diag | 对⻆线元素 |
triu/tril | 矩阵的上三⻆/下三⻆,可指定偏移量 |
mm/bmm | 矩阵乘法, batch的矩阵乘法 |
addmm/addbmm/addmv/addr/badbmm.. | 矩阵运算 |
t | 转置 |
dot/cross | 内积/外积 |
inverse | 求逆矩阵 |
svd | 奇异值分解 |
x = torch.rand(3,3)
print(x)
print('x的对角元素之和为:{}'.format(x.trace()))
print('x的对角元素为:{}'.format(x.diag()))
print('x的上三角:{}'.format(x.triu()))
print('x的转置:{}'.format(x.t()))
tensor([[0.8447, 0.7846, 0.1641],
[0.5459, 0.4649, 0.9806],
[0.1267, 0.0251, 0.9043]])
x的对角元素之和为:2.2139716148376465
x的对角元素为:tensor([0.8447, 0.4649, 0.9043])
x的上三角:tensor([[0.8447, 0.7846, 0.1641],
[0.0000, 0.4649, 0.9806],
[0.0000, 0.0000, 0.9043]])
x的转置:tensor([[0.8447, 0.5459, 0.1267],
[0.7846, 0.4649, 0.0251],
[0.1641, 0.9806, 0.9043]])
2.2.3 广播机制
所谓广播机制,就是在处理数据维度不相等的数据时,会自动将数据补全成相同大小
例如:
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]])
2.2.4 运算的内存开销
利用Python中自带的id函数 验证前面的内存地址差异
x = torch.tensor([1,2])
y = torch.tensor([3,4])
print(id(y))
y = y + x # 赋值运算 所以开辟新内存
print(id(y))
y += x # 不开辟新内存 也可以使用.add()
print(id(y))
print(y)
torch.add(x,y,out = y)
# y.add_(x)
print(id(y))
print(y)
1714379452136
1714379449544
1714379449544
tensor([5, 8])
1714379449544
tensor([ 6, 10])
区分一下add(x,y,out = y) 和 .add()
前者在torch下
2.2.5 Tensor和Numpy 互相转换
利用 numpy() 和 from_numpy() 可以实现Tensor 和 Numpy的数组互相转换
转换后数据共享内存
- Tensor转为Numpy
a = torch.ones(5)
b = a.numpy()
print(a,b)
a += 1
print(a,b)
b += 1
print(a,b)
tensor([1., 1., 1., 1., 1.]) [1. 1. 1. 1. 1.]
tensor([2., 2., 2., 2., 2.]) [2. 2. 2. 2. 2.]
tensor([3., 3., 3., 3., 3.]) [3. 3. 3. 3. 3.]
- Numpy 转为 Tensor
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
print(a,b)
a += 1
print(a,b)
b += 1
print(a,b)
[1. 1. 1. 1. 1.] tensor([1., 1., 1., 1., 1.], dtype=torch.float64)
[2. 2. 2. 2. 2.] tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
[3. 3. 3. 3. 3.] tensor([3., 3., 3., 3., 3.], dtype=torch.float64)
【总结】
主要介绍了Tensor 的创建于使用
posted on 2020-01-31 16:18 wangxiaobei2019 阅读(139) 评论(0) 编辑 收藏 举报