第一课(上) 常用基础操作

一、什么是PyTorch、Tensors?

PyTorch是一个基于Python科学计算库
类似于NumPy,但是它可以使用GPU
可以用它定义深度学习模型,可以灵活地进行深度学习模型的训练和使用

Tensor类似与NumPy的ndarray,唯一的区别是Tensor可以在GPU上加速运算

二、PyTorch中的一系列基本操作

1,导入torch库

import torch

2,创建一个未初始化的5×3矩阵

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]])
"""

3,随机初始化创建一个[0,1)之间的矩阵

y = torch.rand(2,4)
print(y)
"""
tensor([[0.5464, 0.6362, 0.3216, 0.5563],
        [0.4070, 0.4151, 0.0393, 0.0841]])
"""

4,创建一个全为0,类型为long的矩阵

因为是全为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
"""

5,自定义tensor

自定义一个一维矩阵,里面包含两个元素
其实几维矩阵就看两端有几个中括号,默认情况下,为torch.float32类型

x = torch.tensor([2.2,5])
print(x,x.dtype)
"""
tensor([2.2000, 5.0000]) torch.float32
"""

①x.new_ones(2,3),应用和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)
"""

②torch.randn_like(x,dtype=torch.double),随机创建一个和x矩阵同规格大小类型为double的矩阵

上面使用的x矩阵是一个1×2的矩阵
randn:随机

x3 = torch.randn_like(x,dtype=torch.double)
print(x3)
"""
tensor([-0.6062, -1.7242], dtype=torch.float64)
"""

③x.shap或者x.size(),得到x这个tensor的形状

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元组

6,常用的tensor运算

①加法运算为例

Ⅰ、+运算符

随机生成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]])
"""

Ⅱ、z = torch.add(x,y)

和上述操作一致

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]])
"""

Ⅲ、torch.add(x,y,out=z),将x+y赋值给z

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加法运算

任何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]])
"""

Ⅴ、各种类似NumPy的indexing都可以在PyTorch tensor上面使用

a,可以使用Numpy中的切片操作
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]])
"""
b,x.torch.view(2,3),把x矩阵reshap成(2,3)的矩阵,前提x可分成(2,3)
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]])
"""
c,x.item(),若x矩阵是单一的,可以将其转换为一个数值
x = torch.randn(1)
dir(x)# 显示x所可以使用的属性,例如:x.data
print(x)
"""
tensor([0.6425])
"""
x.data
"""
tensor([0.6425])
"""
x.item()
"""
0.642534613609314
"""

更多操作,可查看PyTorch官方文档,多练,别懒!

7,Numpy和Tensor之间的转化

①y = x.numpy(),Torch Tensor转NumPy Array

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)
"""

②y = torch.from_numpy(x),NumPy Array转Torch Tensor

import numpy as np

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到这里应该没什么问题,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变成了新的内存空间了

8,CUDA Tensors

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为GPU
    x = 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进行切换操作

猜你喜欢

转载自blog.csdn.net/qq_41264055/article/details/129435802
今日推荐