一、数据操作
1、创建Tensor
#创建⼀个5x3的未初始化的 Tensor
import torch
x=torch.empty(5, 3)
#创建⼀个5x3的随机初始化的 Tensor
x = torch.rand(5, 3)
#创建⼀个5x3的long型全0的 Tensor
x = torch.zeros(5, 3, dtype=torch.long)
#获取tensor的形状
print(x.size())
print(x.shape)
2、Tensor索引操作
- Tensor支持与numpy.ndarray类似的索引操作,语法上也类似
如无特殊说明,索引出来的结果与原tensor共享内存,即修改一个,另一 个会跟着修改
import torch as t
a = t.randn(3,4)
'''''tensor([[ 0.1986, 0.1809, 1.4662, 0.6693],
[-0.8837, -0.0196, -1.0380, 0.2927],
[-1.1032, -0.2637, -1.4972, 1.8135]])'''
print(a[0]) #第0行
'''''tensor([0.1986, 0.1809, 1.4662, 0.6693])'''
print(a[:,0]) #第0列
'''''tensor([ 0.1986, -0.8837, -1.1032])'''
print(a[0][2]) #第0行第2个元素,等价于a[0,2]
'''''tensor(1.4662)'''
print(a[0][-1]) #第0行最后一个元素
'''''tensor(0.6693)'''
print(a[:2,0:2]) #前两行,第0,1列
'''''tensor([[ 0.1986, 0.1809],
[-0.8837, -0.0196]])'''
print(a[0:1,:2]) #第0行,前两列
'''''tensor([[0.1986, 0.1809]])'''
print(a[0,:2]) #注意两者的区别,形状不同
'''''tensor([0.1986, 0.1809])'''
print(a>1)
'''''tensor([[0, 0, 1, 0],
[0, 0, 0, 0],
[0, 0, 0, 1]], dtype=torch.uint8)'''
print(a[a>1]) #等价于a.masked_select(a>1),选择结果与原tensor不共享内存空间
print(a.masked_select(a>1))
'''''tensor([1.4662, 1.8135])
tensor([1.4662, 1.8135])'''
print(a[t.LongTensor([0,1])])
'''''tensor([[ 0.1986, 0.1809, 1.4662, 0.6693],
[-0.8837, -0.0196, -1.0380, 0.2927]])'''
注意 a[0:1,:2] 以及a[0,:2] ,他们的形状是不同的,一个是二维,一个是一维。
3、改变形状
- 用view() 来改变 Tensor 的形状
注意 view() 返回的新tensor与源tensor共享内存(其实是同⼀个tensor),也即更改其中的⼀个,另
外⼀个也会跟着改变。(顾名思义,view仅仅是改变了对这个张量的观察⻆度
y = x.view(15)
z = x.view(-1, 5) # -1所指的维度可以根据其他维度的值推出来
print(x.size(), y.size(), z.size())
#输出结果为:
torch.Size([5, 3]) torch.Size([15]) torch.Size([3, 5])
- 以如果我们想返回⼀个真正新的副本(即不共享内存)该怎么办呢?Pytorch还提供了⼀个 reshape() 可以改变形状,但是此函数并不能保证返回的是其拷⻉,所以不推荐使⽤。推荐先⽤ clone 创造⼀个副本然后再使⽤ view 。
#x_cp与x相互不影响
x_cp = x.clone().view(15)
x -= 1
print(x)
print(x_cp)
- 另外⼀个常⽤的函数就是 item() , 它可以将⼀个标量 Tensor 转换成⼀个Python number:
x = torch.randn(1)
print(x)
print(x.item())
#输出如下:
tensor([2.3466])
2.3466382026672363
4、线性函数
5、广播机制
- 当对两个形状不同的 Tensor 按元素运算时,可能会触发⼴播(broadcasting)机制。先适当复制元素使这两个 Tensor 形状相同后再按元素运算。
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]])
由于 x 和 y 分别是1⾏2列和3⾏1列的矩阵,如果要计算 x + y ,那么 x 中第⼀⾏的2个元素被⼴播(复制)到了第⼆⾏和第三⾏,⽽ y 中第⼀列的3个元素被⼴播(复制)到了第⼆列。如此,就可以对2个3⾏2列的矩阵按元素相加。(复制成行和列都取数字较大的形状)
6、TENSOR 和NUMPY相互转换
- 易⽤ numpy() 和 from_numpy() 将 Tensor 和NumPy中的数组相互转换。但是需要注意的⼀点是: 这两个函数所产⽣的的 Tensor 和NumPy中的数组共享相同的内存(所以他们之间的转换很快),改变其中⼀个时另⼀个也会改变!!!
#使⽤ numpy() 将 Tensor 转换成NumPy数组:
#共享相同的内存,所以转换很快
#numpy()是将张量转化为numpy数组
a = torch.ones(5)
b = a.numpy()
print(a, b)
a += 1
print(a, b)
b += 1
print(a, b)
#使⽤ from_numpy() 将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)
注意:所有在CPU上的 Tensor (除了 CharTensor )都⽀持与NumPy数组相互转换。
- 还有⼀个常⽤的⽅法就是直接⽤ torch.tensor() 将NumPy数组转换成 Tensor ,需要注意的是该⽅法总是会进⾏数据拷⻉,返回的 Tensor 和原来的数据不再共享内存。