数据操作
在深度学习中,我们通常会频繁的去对数据进行操作。
创建Tensor(张量)
1)先介绍一下Tensor的最基本的功能,即Tensor的创建。
首先就是导入PyTorch:
1 2 3
| x = torch.empty(5, 3) print(x)
|
tensor([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
1 2 3
| x = torch.rand(5, 3) print(x)
|
tensor([[0.7852, 0.0743, 0.0271],
[0.6014, 0.5902, 0.8844],
[0.0410, 0.6901, 0.8871],
[0.0437, 0.0626, 0.5687],
[0.9419, 0.7970, 0.9925]])
1 2 3
| x = torch.zeros(5, 3, dtype = torch.long) print(x)
|
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
1 2 3
| x = torch.tensor([4.5, 3]) print(x)
|
tensor([4.5000, 3.0000])
1 2 3 4 5 6 7
|
x = x.new_ones(5, 3, dtype = torch.float64) print(x)
x = torch.randn_like(x, dtype = torch.float) print(x)
|
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
tensor([[ 0.5578, -0.0502, 2.0930],
[-0.9528, -0.6031, -0.0405],
[ 0.1853, -0.7159, -1.0291],
[ 1.0159, -0.3431, -0.3712],
[-0.1306, 0.7387, -0.6336]])
1 2 3 4 5
| print(x.size()) print(x.shape)
|
torch.Size([5, 3])
torch.Size([5, 3])
还有很多函数可以创建Tensor
,去翻翻官方API就知道了,下表给了一些常用的作参考。
函数 |
功能 |
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) |
随机排列 |
操作
这里学习Tensor的各种操作
算术操作
在PyTorch中,同一种操作可能有很多形式,下面使用加法作为例子。
1 2 3
| result = torch.empty(5, 3) torch.add(x, y, out = result) print(result)
|
索引
1)我们还可以使用类似NumPy的索引来操作访问Tensor的一部分,需要注意的是:索引出来的结果与元数据共享内存,也即修改一个,另一个也会跟着改变。
1 2 3 4
| y = x[0, :] y += 1 print(y) print(x[0, :])
|
2)处理常用的索引选择数据之外,PyTorch还提供了一些高级的选择函数:
函数 |
功能 |
index_select(input, dim, index) |
在指定维度dim上选取,比如选取某些行、某些列 |
masked_select(input, mask) |
例子如上,a[a>0],使用ByteTensor进行选取 |
nonzero(input) |
非0元素的下标 |
gather(input, dim, index) |
根据index,在dim维度上选取数据,输出的size与index一样 |
这里不详细介绍,用到了再查官方文档。
改变形状
用view()来改变Tensor的形状
1 2 3
| y = x.view(15) z = x.view(-1, 5) print(x.size(), y.size(), z.size())
|
注意view(),返回的新的Tensor与源Tensor虽然可能有些不同的size,但是是共享data的,也就是说,改变其中一个,另一个也会跟着改变。**(顾名思义,view仅仅是改变了对这个张量的观察角度,内部数据并未改变)**
1 2 3
| x += 1 print(x) print(y)
|
所以如果我们想返回一个真正新的副本(即不共享data内存)该怎么办呢?Pytorch还提供了一个reshape()
可以改变形状,但是此函数并不能保证返回的是其拷贝,所以不推荐使用。推荐先用clone
创造一个副本然后再使用view
1 2 3 4
| x_cp = x.clone().view(15) x -= 1 print(x) print(x_cp)
|