# 导入 torch 模块
import torch
# 导入 numpy 模块
import numpy as np
——————————————————————————————————————
生成张量
# 从python数组构建
a = [[1,2,3],[4,5,6]]
t = torch.Tensor(a)
print(t)
tensor([[1., 2., 3.],
[4., 5., 6.]])
# 从列表构建张量
x = torch.Tensor([[1,2]])
print(x)
tensor([[1., 2.]])
# 生成零张量
z = torch.zeros(1,2)
print(z)
tensor([[0., 0.]])
# 根据随机分布生成张量
z = torch.rand(1,2) # 均匀分布 U[0,1]
h = torch.randn(3,2) # 正态分布 N(0,1)
print(z)
print(h)
tensor([[0.8609, 0.7623]])
tensor([[-0.6099, 0.1189],
[ 1.0732, -1.6297],
[ 1.5443, -0.8227]])
# 查询 tensor 中元素个数
print(x.numel()) # 等价于x.nelement()
# tensor size
print(x.size())
2
torch.Size([1, 2])
——————————————————————————————————————————————————————————————————————
类型转化
x = torch.rand(2,2)*10
y = x.double()
z = x.int()
print('type of x: ', type(x))
print('type of y: ', type(y))
print('type of z: ', type(z))
type of x: <class 'torch.Tensor'>
type of y: <class 'torch.Tensor'>
type of z: <class 'torch.Tensor'>
# CPU 与 GPU 张量相互转化
# 检查是否支持CUDA
torch.cuda.is_available()
True
x = torch.randn(2,2)
y = x.cuda() # 需要 GPU 支持
z = x.cpu()
print('type of x: ', type(x))
print('type of y: ', type(y))
print('type of z: ', type(z))
type of x: <class 'torch.Tensor'>
type of y: <class 'torch.Tensor'>
type of z: <class 'torch.Tensor'>
# numpy 数组 和 torch 张量相互转换
x = np.random.rand(2,2)
y = torch.from_numpy(x)
z = y.numpy()
print('type of x: ', type(x))
print('type of y: ', type(y))
print('type of z: ', type(z))
type of x: <class 'numpy.ndarray'>
type of y: <class 'torch.Tensor'>
type of z: <class 'numpy.ndarray'>
# tensor----> array
x = torch.randn(2,2)
y = x.numpy()
print(type(y))
# array ---> numpy
z = torch.from_numpy(y)
print(type(z))
<class 'numpy.ndarray'>
<class 'torch.Tensor'>
# numpy 与 torch 的转换时非常快的,因为其底层内存是共享的
x = torch.rand(1,2)
print(x)
y = x.numpy() # 不会分配新的内存
y.fill(0) # 因为内存共享,这个操作会改变 x 的值
print(x)
print(y)
tensor([[0.8027, 0.8068]])
tensor([[0., 0.]])
[[0. 0.]]
张量运算
重点掌握:四则运算, torch.max torch.min torch.mean torch.sum
torch.sqrt 三角函数
x = torch.Tensor([1,2]).view(1,2)
y = torch.Tensor([3,4]).view(1,2)
z = x*y # 逐点相乘
h = torch.mm(x, y.transpose(0,1))# 矩阵乘法
# 0,1维度相互转换
print(z)
print(h)
tensor([[3., 8.]])
tensor([[11.]])
inplace 操作。所有以“_”结尾的函数表示 inplace 操作,即运算结果直接覆盖原来的Tensor不分配原来的内存。
x = torch.randn(2,2)
print(x)
x.mul(10) # x 加 10 但是不修改 x
print(x) # x 加 10 在原来内存上修改
x.mul_(10)
print(x)
tensor([[ 0.0304, -0.6806],
[ 0.0477, -1.3126]])
tensor([[ 0.0304, -0.6806],
[ 0.0477, -1.3126]])
tensor([[ 0.3038, -6.8058],
[ 0.4770, -13.1262]])
####### tensor 加法的不同形式
x = torch.Tensor([1,2])
y = torch.Tensor([3,4])
# 方法一
print(x+y)
# 方法二
print(torch.add(x,y))
# 方法三:计算结果储存在 z 上
z = torch.Tensor(1,2) # 生成1*2张量
torch.add(x,y,out = z)
print(z)
# 方法四: 运算结果覆盖y(inplace操作)
y.add_(x)
print(y)
tensor([4., 6.])
tensor([4., 6.])
tensor([4., 6.])
tensor([4., 6.])
————————————————————————————————————
索引(indexing)和切片(slicing)
# torch 张量的索引以及切片规则与Numpy基本一致
# 索引出来的结果与原结果共享
x = torch.rand(2,3,4)
print(x[1].shape)
y = x[1,0:2,:]
print(y.shape)
z = x[:,0,::2]
print(z.shape)
torch.Size([3, 4])
torch.Size([2, 4])
torch.Size([2, 2])
print(x)
print(z)
tensor([[[0.0231, 0.1160, 0.9725, 0.1994],
[0.9047, 0.4319, 0.9163, 0.7421],
[0.3240, 0.9103, 0.0024, 0.9348]],
[[0.2423, 0.1626, 0.2431, 0.6533],
[0.9368, 0.0300, 0.1535, 0.0286],
[0.0796, 0.5773, 0.6786, 0.2632]]])
tensor([[0.0231, 0.9725],
[0.2423, 0.2431]])
张量变形
torch.view
torch.resize
torch.squeeze, torch.unsqueeze
torch.transpose
# torch.view 可以改变 tensor 的形状,但是必须保证前后元素总数一致
x = torch.rand(3,1,2)
y = x.view(6)
print('shape of x', x.shape)
print('shape of y', y.shape)
print(x)
print(y)
shape of x torch.Size([3, 1, 2])
shape of y torch.Size([6])
tensor([[[0.8635, 0.7824]],
[[0.5868, 0.0500]],
[[0.4196, 0.3078]]])
tensor([0.8635, 0.7824, 0.5868, 0.0500, 0.4196, 0.3078])
# torch.resize 是另一个用来改变 tensor 形状的方法,与view不同的是他可以改变tensor的大小
# 如果新规格大于原规格,会分配新的内存空间,如果新规小于原规格,则会保存之前的数据
x = torch.rand(3,1,2)
print(x)
print(x.resize_(8))
tensor([[[0.7427, 0.4825]],
[[0.5664, 0.1080]],
[[0.2545, 0.9431]]])
tensor([0.7427, 0.4825, 0.5664, 0.1080, 0.2545, 0.9431, 0.0000, 1.6181])
# tensor.squeeze 和 unsqueeze 主要用于需要减少维度的情况
x = torch.rand(3,2,4)
y = x.transpose(1,2) # 维度索引从 0 开始
print('shape of x' ,x.shape)
print('shape of y' ,y.shape)
shape of x torch.Size([3, 2, 4])
shape of y torch.Size([3, 4, 2])