标量由只有一个元素的张量表示
import torch
x=torch.tensor([3.0])
y=torch.tensor([2.0])
x+y,x*y,x/y,x**y
#输出(tensor([5.]), tensor([6.]), tensor([1.5000]), tensor([9.]))
可以将向量视为标量值组成的列表
x=torch.arange(4)
x
#输出tensor([0, 1, 2, 3])
通过张量的索引来访问任一元素
x[3]
#输出tensor(3)
访问张量的长度
len(x)
#4
只有一个轴的张量,形状只有一个元素
x.shape
#torch.Size([4])
通过指定两个分量m和n来创建一个形状为m*n的矩阵
A=torch.arange(20).reshape(5,4)
A
'''输出tensor([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19]])
'''
B=torch.tensor([[1,2,3],[2,0,4],[3,4,5]])
B
#输出:tensor([[1, 2, 3],
# [2, 0, 4],
# [3, 4, 5]])
B==B.T
#tensor([[True, True, True],
# [True, True, True],
# [True, True, True]])
A=torch.arange(20,dtype=torch.float32).reshape(5,4)
B=A.clone() #通过分配新内存,将A的一个副本分配给B
A,A+B
'''(tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]]),
tensor([[ 0., 2., 4., 6.],
[ 8., 10., 12., 14.],
[16., 18., 20., 22.],
[24., 26., 28., 30.],
[32., 34., 36., 38.]]))'''
A*B #两个矩阵的按元素乘法称为哈达玛积
'''tensor([[ 0., 1., 4., 9.],
[ 16., 25., 36., 49.],
[ 64., 81., 100., 121.],
[144., 169., 196., 225.],
[256., 289., 324., 361.]])'''
两个矩阵的按元素乘法称为哈达玛积
a=2
X=torch.arange(24).reshape(2,3,4)
a+X,(a*X).shape
'''
(tensor([[[ 2, 3, 4, 5],
[ 6, 7, 8, 9],
[10, 11, 12, 13]],
[[14, 15, 16, 17],
[18, 19, 20, 21],
[22, 23, 24, 25]]]),
torch.Size([2, 3, 4]))'''
计算其元素的和
x=torch.arange(4,dtype=torch.float32)
x,x.sum(),x.shape
#(tensor([0., 1., 2., 3.]), tensor(6.)), torch.Size([4]))
A_sum_axis0=A.sum(axis=0)
A_sum_axis0,A_sum_axis0.shape
# axis=0表示按列相加
#(tensor([40, 45, 50, 55]), torch.Size([4]))
A_sum_axis1=A.sum(axis=1)
A_sum_axis1,A_sum_axis1.shape
#axis=1表示按行相加
#(tensor([ 6, 22, 38, 54, 70]), torch.Size([5]))
A.sum(axis=[0,1])
#相当于A.sum
#tensor(190)
A=torch.arange(20,dtype=torch.float32).reshape(5,4)
A
'''
输出tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]])
'''
A.mean(),A.sum()/A.numel()
#求均值,求和除以个数
#输出(tensor(9.5000),tensor(9.5000))
A.mean(axis=0),A.sum(axis=0)/A.shape[0]
#输出(tensor([ 8., 9., 10., 11.]), tensor([ 8., 9., 10., 11.]))
#求列均值,求列和除以个数
按待定轴求和
axis等于1,则把1的元素去掉
如shape[2,5,4]
axis=1,[2,4]
axis=2,[2,5]
axis=[1,2],[4]
如果keepdims = True,则保留该列为1
axis=1,keepdims = True,[2,1,4]
计算总和或均值时保持轴数不变
sum_A=A.sum(axis=1,keepdims=True)
sum_A
'''输出tensor([[ 6.],
[22.],
[38.],
[54.],
[70.]])'''
#keepdims=True保持维度
A.cumsum(axis=0)
'''tensor([[ 0., 1., 2., 3.],
[ 4., 6., 8., 10.],
[12., 15., 18., 21.],
[24., 28., 32., 36.],
[40., 45., 50., 55.]])'''
#某个轴计算A元素的累积总和
点积
x=torch.arange(4,dtype=torch.float32)
y=torch.ones(4,dtype=torch.float32)
x,y,torch.dot(x,y)
#(tensor([0., 1., 2., 3.]), tensor([1., 1., 1., 1.]), tensor(6.))
#我们也可以执行按元素乘法,然后进行求和来表示两个向量的点积
torch.sum(x*y)
#tensor(6.)
矩阵向量积Ax
A.shape,x.shape,torch.mv(A,x)
#输出(torch.Size([5, 4]), torch.Size([4]), tensor([ 14., 38., 62., 86., 110.]))
向量积AB
B=torch.ones(4,3)
torch.mm(A,B)
'''输出tensor([[ 6., 6., 6.],
[22., 22., 22.],
[38., 38., 38.],
[54., 54., 54.],
[70., 70., 70.]])
'''
这个讲的很清楚:Python深拷贝和浅拷贝详解 (biancheng.net)
共享data的内存地址,数据会同步变化
指的是重新分配一块内存,创建一个新的对象,但里面的元素是原对象中各个子对象的引用。
a.numpy()
# Tensor—>Numpy array.view()
#改变tensor的形状,但共享数据内存,不要直接使用id进行判断y = x[:]
# 索引torch.from_numpy()
# Numpy array—>Tensortorch.as_tensor()
#任意的Python类型的数据—>Tensortorch.detach()
# 新的tensor会脱离计算图,不会牵扯梯度计算model.forward()
还有很多选择函数也是数据共享内存,如index_select()
, masked_select()
, gather()
。
(来源:PyTorch中的拷贝 - 知乎 (zhihu.com))
会在内存中也创建一个副本
深拷贝,是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联。
拷贝数值、指针和指针指向的深层次内存空间,拷贝了父对象及其子对象。
torch.clone()
# 新的tensor会保留在计算图中,参与梯度计算torch.clone()
函数可以返回一个完全相同的tensor,新的tensor开辟新的内存,但是仍然留在计算图中。torch.clone()
操作在不共享数据内存的同时支持梯度回溯,所以常用在神经网络中某个单元需要重复使用的场景下。torch.Tensor()
# 类的构造方法torch.tensor()
# 工厂函数