PyTorch是一个基于Python的科学计算库
类似于NumPy,但是它可以使用GPU
可以用它定义深度学习模型,可以灵活地进行深度学习模型的训练和使用
Tensor类似与NumPy的ndarray,唯一的区别是Tensor可以在GPU上加速运算
import torch
x = torch.empty(5,3)
print(x)
"""
tensor([[9.2755e-39, 1.0561e-38, 7.0715e-39],[7.3470e-39, 8.4490e-39, 9.6428e-39],[1.1112e-38, 9.5511e-39, 1.0102e-38],[1.0286e-38, 1.0194e-38, 9.6429e-39],[9.2755e-39, 9.1837e-39, 9.3674e-39]])
"""
y = torch.rand(2,4)
print(y)
"""
tensor([[0.5464, 0.6362, 0.3216, 0.5563],[0.4070, 0.4151, 0.0393, 0.0841]])
"""
因为是全为0,故是复数,及zeros
若不指定dtype,默认为torch.float32类型
z = torch.zeros(3,4)
print(z)
"""
tensor([[0., 0., 0., 0.],[0., 0., 0., 0.],[0., 0., 0., 0.]])
"""
print(z.dtype)
"""
torch.float32
"""
设定dtype=torch.long,则为torch.int64类型
z1 = torch.zeros(3,4,dtype=torch.long)
print(z1,"\n",z1.dtype)
"""
tensor([[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]]) torch.int64
"""
也可以直接对默认的torch.float32类型进行强转
z2 = torch.zeros(3,4).long()
print(z2)
print(z2.dtype)
"""
tensor([[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]])
torch.int64
"""
自定义一个一维矩阵,里面包含两个元素
其实几维矩阵就看两端有几个中括号,默认情况下,为torch.float32类型
x = torch.tensor([2.2,5])
print(x,x.dtype)
"""
tensor([2.2000, 5.0000]) torch.float32
"""
x矩阵同数据类型
,进行创建(2,3)的全1
矩阵ones:全1矩阵
x1 = x.new_ones(2,3)
print(x1)
print(x1.dtype)
"""
tensor([[1., 1., 1.],[1., 1., 1.]])
torch.float32
"""
当然,也可以通过dtype来重新指定数据类型
x2 = x.new_ones(2,3,dtype=torch.double)
print(x2)
"""
tensor([[1., 1., 1.],[1., 1., 1.]], dtype=torch.float64)
"""
随机
创建一个和x矩阵同规格大小
的类型为double
的矩阵上面使用的x矩阵是一个1×2的矩阵
randn:随机
x3 = torch.randn_like(x,dtype=torch.double)
print(x3)
"""
tensor([-0.6062, -1.7242], dtype=torch.float64)
"""
print(x.shape,x.size())
print(x1.shape,x1.size())
print(x2.shape,x2.size())
print(x3.shape,x3.size())
"""
torch.Size([2]) torch.Size([2])
torch.Size([2, 3]) torch.Size([2, 3])
torch.Size([2, 3]) torch.Size([2, 3])
torch.Size([2]) torch.Size([2])
"""
注意:torch.Size返回的是一个tuple元组
+
运算符随机生成2×3维矩阵x和y,相加
x = torch.randn(2,3)
y = torch.randn(2,3)
print(x)
print(y)
"""
tensor([[ 0.7453, -0.4681, 0.1118],[ 1.3190, -0.5605, 0.4602]])
tensor([[ 0.2022, 0.2319, -1.0052],[-0.1519, 1.3988, -0.0243]])
"""
z = x + y
print(z)
"""
tensor([[ 0.9475, -0.2362, -0.8934],[ 1.1670, 0.8383, 0.4358]])
"""
和上述操作一致
x = torch.randn(2,3)
y = torch.randn(2,3)
print(x)
print(y)
"""
tensor([[ 0.4894, -2.5748, -0.8209],[-0.5150, 0.4347, -0.8788]])
tensor([[ 0.5133, -0.8305, -0.4655],[-1.1071, -1.4777, -0.4736]])
"""
z1 = torch.add(x,y)
print(z1)
"""
tensor([[ 1.0027, -3.4053, -1.2864],[-1.6221, -1.0430, -1.3524]])
"""
x = torch.randn(2,3)
y = torch.randn(2,3)
print(x)
"""
tensor([[-0.1856, 0.3997, -0.4359],[ 0.1850, -0.4738, -0.8569]])
"""
print(y)
"""
tensor([[-1.0152, -0.4140, -1.9967],[ 0.5528, 1.5418, -1.1663]])
"""
torch.add(x,y,out=z)
z
"""
tensor([[-1.2008, -0.0143, -2.4326],[ 0.7378, 1.0681, -2.0232]])
"""
任何in-place的运算都会以_
结尾,也就是会改变原来本身的数值
# 随机生成一个2×3的矩阵
x = torch.randn(2,3)
y = torch.randn(2,3)
print(x)
"""
tensor([[-0.2821, -0.3595, -0.9248],[-0.2517, -1.9226, -0.4992]])
"""
print(y)
"""
tensor([[ 0.3206, 0.1855, 1.2988],[ 1.0456, -0.6818, 0.2500]])
"""# 将x加到y上面,把该值赋给z
z = y.add(x)
print(z)
"""
tensor([[ 0.0385, -0.1740, 0.3741],[ 0.7939, -2.6044, -0.2492]])
"""# 很明显,y的值,虽然通过y.add(x)加上x,但y的本质并没有发生变化,还是之前随机生成的初始y
y.add(x)
print(y)
"""
tensor([[ 0.3206, 0.1855, 1.2988],[ 1.0456, -0.6818, 0.2500]])
"""# 若变为y.add_(x),此时的y的值会发生变化,即y的内容改变了,这就是in-place操作
y.add_(x)
print(y)
"""
tensor([[ 0.0385, -0.1740, 0.3741],[ 0.7939, -2.6044, -0.2492]])
"""
x = torch.randn(5,4)
print(x)
print(x[1:,2:3])#左闭右开[2,3)
"""
tensor([[ 0.8863, -0.5580, -0.1271, -1.2557],[ 0.5441, 1.3141, 1.0707, 0.0248],[-0.0266, 1.1872, -0.4304, 0.3810],[-1.7742, -0.6298, 0.3557, 1.0469],[-1.8024, 1.1225, -0.2816, 0.3743]])
tensor([[ 1.0707],[-0.4304],[ 0.3557],[-0.2816]])
"""
x = torch.randn(3,4)
y = x.view(2,6)
z = x.view(4,-1)# -1的话,会自动算出另一个数值大小,前提能进行整除;只能写一个-1,不能写两个-1,因为系统不知道你想算啥了
print(x)
"""
tensor([[ 2.2263, 2.5442, 0.7730, 0.3228],[ 0.1635, -1.0602, 2.5772, 1.3220],[-0.7451, 1.1982, -0.0515, -1.1222]])
"""
print(y)
"""
tensor([[ 2.2263, 2.5442, 0.7730, 0.3228, 0.1635, -1.0602],[ 2.5772, 1.3220, -0.7451, 1.1982, -0.0515, -1.1222]])
"""
print(z)
"""
tensor([[ 2.2263, 2.5442, 0.7730],[ 0.3228, 0.1635, -1.0602],[ 2.5772, 1.3220, -0.7451],[ 1.1982, -0.0515, -1.1222]])
"""
数值
x = torch.randn(1)
dir(x)# 显示x所可以使用的属性,例如:x.data
print(x)
"""
tensor([0.6425])
"""
x.data
"""
tensor([0.6425])
"""
x.item()
"""
0.642534613609314
"""
x是一个tensor,通过x.numpy()可转化为array类型,此时的x和y同属一块内存空间
,任意改变其中一个变量,另一个也会发生变化
x = torch.ones(8)
x
"""
tensor([1., 1., 1., 1., 1., 1., 1., 1.])
"""
y = x.numpy()
y
"""
array([1., 1., 1., 1., 1., 1., 1., 1.], dtype=float32)
"""
x[3] = 5
x
"""
tensor([1., 1., 1., 5., 1., 1., 1., 1.])
"""
y
"""
array([1., 1., 1., 5., 1., 1., 1., 1.], dtype=float32)
"""
import numpy as npx = np.ones(9)
y = torch.from_numpy(x)
x
"""
array([1., 1., 1., 1., 1., 1., 1., 1., 1.])
"""
y
"""
tensor([1., 1., 1., 1., 1., 1., 1., 1., 1.], dtype=torch.float64)
"""# x和y到这里应该没什么问题,np.add(x,1,out=x),此时的x和y都指向同一块内存空间
# 现在来进行测试,让x进行add操作,看y的值是否也发生变化
np.add(x,1,out=x)
x
"""
array([2., 2., 2., 2., 2., 2., 2., 2., 2.])
"""
y
"""
tensor([2., 2., 2., 2., 2., 2., 2., 2., 2.], dtype=torch.float64)
"""
#至此,可以证明np.add(x,1,out=x)操作,x和y指向的是同一块内存空间
注:np.add(x,1,out=x) 和 x = x + 1 区别
x = np.ones(9)
y = torch.from_numpy(x)
x
"""
array([1., 1., 1., 1., 1., 1., 1., 1., 1.])
"""
y
"""
tensor([1., 1., 1., 1., 1., 1., 1., 1., 1.], dtype=torch.float64)
"""# x和y到这里应该没什么问题
# 现在来进行测试,让x+1操作,看y的值是否也发生变化
x = x + 1
x
"""
array([2., 2., 2., 2., 2., 2., 2., 2., 2.])
"""
y
"""
tensor([1., 1., 1., 1., 1., 1., 1., 1., 1.], dtype=torch.float64)
"""
# x发生了变化,很正常,但是y并未发生改变,可以证明,x = x + 1操作,会对x重新分配一次空间,此时的y还是原来内存地址,x变成了新的内存空间了
device = torch.device(“cuda”),指定GPU
x.to(device):指定使用GPU
GPU虽然运算速度快,但是,进行其他操作受限
例如:无法对GPU运算对象进行numpy操作,需要通过.to("cpu")
方法转换为CPU
numpy()是一个在CPU上的操作运算,在GPU上不可以进行操作运算
if torch.cuda.is_available():x = torch.ones(8) # 默认使用CPU运算device = torch.device("cuda") # 指定CUDA设备y = torch.ones_like(x, device=device) # y的结构和x一致,但使用device为GPUx = x.to(device) # 将x也使用GPU运算z = x + y # 因为x和y都是GPU,故z也通过GPU进行运算print(z)print(z.to("cpu", torch.double)) # 将z从GPU转换为CPU
定义模型的时候也可以通过 model.cuda() 将模型转到GPU上
模型其实就是一堆参数的集合
目前为止,使用PyTorch比较傻的操作就是得来回在GPU和CPU进行切换操作