当前位置: 代码迷 >> 综合 >> PyTorch基础教程学习笔记(一):基本知识
  详细解决方案

PyTorch基础教程学习笔记(一):基本知识

热度:74   发布时间:2023-12-12 01:09:40.0

介绍

PyTorch是一个基于Torch的Python开源机器学习库,用于自然语言处理等应用程序。它主要由Facebookd的人工智能小组开发,不仅能够 实现强大的GPU加速,同时还支持动态神经网络,PyTorch提供了两个高级功能:

  1. 具有强大的GPU加速的张量计算(如Numpy)
  2. 包含自动求导系统的深度神经网络

除了Facebook之外,Twitter、GMU和Salesforce等机构都采用了PyTorch。

优势

  • 支持GPU
  • 灵活,支持动态神经网络
  • 底层代码易于理解
  • 命令式体验
  • 自定义扩展

张量Tensor

Tensors 类似于 NumPy ndarrays ,同时 Tensors 可以使用 GPU 进行计算。
from __future__ import print_function
import torchtorch.manual_seed(0) #为CPU设置种子用于生成随机数,以使得结果是确定的
torch.cuda.manual_seed(0)#为当前GPU设置随机种子;如果使用多个GPU,应该使用
#torch.cuda.manual_seed_all()为所有的GPU设置种子。

在开头加上from __future__ import print_function这句之后,即使在python2.X,使用print就得像python3.X那样加括号使用。python2.X中print不需要括号,而在python3.X中则需要。

更广泛来说,如果某个版本中出现了某个新的功能特性,而且这个特性和当前版本中使用的不兼容,也就是它在该版本中不是语言标准,那么如果想要使用的话就需要从future模块导入。

  • 构造一个5x3矩阵,不初始化
x = torch.empty(5, 3)
print(x)

输出为:

tensor([[1.6255e-43, 1.5554e-43, 1.5975e-43],[1.3873e-43, 1.4574e-43, 6.4460e-44],[1.4153e-43, 1.5274e-43, 1.5695e-43],[1.6255e-43, 1.6956e-43, 5.6052e-44],[7.4269e-44, 6.1657e-44, 4.4842e-44]])
  • 构造一个随机初始化的矩阵
x = torch.rand(5, 3)
print(x)

输出为:

tensor([[0.3983, 0.0756, 0.3885],[0.5530, 0.0550, 0.0197],[0.7664, 0.1477, 0.9955],[0.2368, 0.3034, 0.8063],[0.3418, 0.6183, 0.1371]])
  • 构造一个矩阵全为 0,而且数据类型是 long
x = torch.zeros(5, 3, dtype=torch.long)
print(x)

输出:

tensor([[ 0,  0,  0],[ 0,  0,  0],[ 0,  0,  0],[ 0,  0,  0],[ 0,  0,  0]])
  • 构造一个张量,直接使用数据:
x = torch.tensor([5.5, 3])
print(x)

输出:

tensor([ 5.5000,  3.0000])
  • 通过现有的Tensor来创建,此方法会默认重用输入Tensor的一些属性,例如数据类型,除非自定义数据类型
    x = x.new_ones(5, 3, dtype=torch.float64)      # 返回的tensor默认具有相同的torch.dtype和torch.deviceprint(x)x = torch.randn_like(x, dtype=torch.float)    # 指定新的数据类型print(x)                                    输出为:tensor([[1., 1., 1.],[1., 1., 1.],[1., 1., 1.],[1., 1., 1.],[1., 1., 1.]], dtype=torch.float64)tensor([[ 0.6035,  0.8110, -0.0451],[ 0.8797,  1.0482, -0.0445],[-0.7229,  2.8663, -0.5655],[ 0.1604, -0.0254,  1.0739],[ 2.2628, -0.9175, -0.2251]])
  • 获取维度信息

 

print(x.size())
或
print(x.shape)
输出:
torch.Size([5, 3])

注意:返回的torch.Size其实就是一个tuple, 支持所有tuple的操作。


操作

算术操作

  • 加法形式一
y = torch.rand(5, 3)
print(x + y)
输出为:
tensor([[1.9224, 1.8943, 1.7366],[1.9281, 1.8129, 1.3018],[1.4944, 1.0350, 1.6745],[1.1145, 1.0914, 1.0394],[1.5441, 1.6155, 1.3457]])
  • 加法形式二
print(torch.add(x, y))
输出
tensor([[1.9224, 1.8943, 1.7366],[1.9281, 1.8129, 1.3018],[1.4944, 1.0350, 1.6745],[1.1145, 1.0914, 1.0394],[1.5441, 1.6155, 1.3457]])

或者另外提供一个 tensor 作为输出参数

result = torch.empty(5, 3)
torch.add(x, y, out=result)
print(result)
输出:
tensor([[1.9224, 1.8943, 1.7366],[1.9281, 1.8129, 1.3018],[1.4944, 1.0350, 1.6745],[1.1145, 1.0914, 1.0394],[1.5441, 1.6155, 1.3457]])
  • 加法形式三:inplace
# adds x to y
y.add_(x)
print(y)
输出:
tensor([[1.9224, 1.8943, 1.7366],[1.9281, 1.8129, 1.3018],[1.4944, 1.0350, 1.6745],[1.1145, 1.0914, 1.0394],[1.5441, 1.6155, 1.3457]])

注意 任何使张量会发生变化的操作都有一个后缀 '_'。如x.copy_(y)x.t_(), 将会改变 x.

索引

可以使用类似NumPy的索引操作来访问Tensor的一部分,需要注意的是:索引出来的结果与原数据共享内存,也即修改一个,另一个会跟着修改。

    y = x[0, :]y += 1print(y)print(x[0, :]) # 源tensor也被改了输出为:tensor([1.6035, 1.8110, 0.9549])tensor([1.6035, 1.8110, 0.9549])
  • 改变一个 tensor 的大小或者形状,可以使用 torch.view
x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8)  # -1所指的维度可以根据其他维度的值推出来
print(x.size(), y.size(), z.size())
torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])

注意view()返回的新tensor与源tensor共享内存,也即更改其中的一个,另外一个也会跟着改变。

x += 1
print(x)
print(y) # 也加了1
输出为:
tensor([[2.6035, 2.8110, 1.9549],[1.8797, 2.0482, 0.9555],[0.2771, 3.8663, 0.4345],[1.1604, 0.9746, 2.0739],[3.2628, 0.0825, 0.7749]])
tensor([2.6035, 2.8110, 1.9549, 1.8797, 2.0482, 0.9555, 0.2771, 3.8663, 0.4345,1.1604, 0.9746, 2.0739, 3.2628, 0.0825, 0.7749])

如果不想共享内存,推荐先用clone创造一个副本然后再使用view

x_cp = x.clone().view(15)
x -= 1
print(x)
print(x_cp)
输出为:
tensor([[ 1.6035,  1.8110,  0.9549],[ 0.8797,  1.0482, -0.0445],[-0.7229,  2.8663, -0.5655],[ 0.1604, -0.0254,  1.0739],[ 2.2628, -0.9175, -0.2251]])
tensor([2.6035, 2.8110, 1.9549, 1.8797, 2.0482, 0.9555, 0.2771, 3.8663, 0.4345,1.1604, 0.9746, 2.0739, 3.2628, 0.0825, 0.7749])
  • 另外一个常用的函数就是item(), 它可以将一个标量Tensor转换成一个Python number,获得Tensor的value
x = torch.randn(1)
print(x)
print(x.item())
输出:
tensor([-0.2508])
-0.25081250071525574

广播机制

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

Tensor和NumPy相互转换

numpy()from_numpy()这两个函数产生的Tensor和NumPy array实际是使用的相同的内存,改变其中一个时另一个也会改变

Tensor转NumPy

a = torch.ones(5)
b = a.numpy()
print(a, b)a += 1
print(a, b)
b += 1
print(a, b)
输出为:
tensor([1., 1., 1., 1., 1.]) [1. 1. 1. 1. 1.]
tensor([2., 2., 2., 2., 2.]) [2. 2. 2. 2. 2.]
tensor([3., 3., 3., 3., 3.]) [3. 3. 3. 3. 3.]

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)
输出为;
[1. 1. 1. 1. 1.] tensor([1., 1., 1., 1., 1.], dtype=torch.float64)
[2. 2. 2. 2. 2.] tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
[3. 3. 3. 3. 3.] tensor([3., 3., 3., 3., 3.], dtype=torch.float64)

直接用torch.tensor()将NumPy数组转换成Tensor该方法总是会进行数据拷贝,返回的Tensor和原来的数据不再共享内存

    # 用torch.tensor()转换时不会共享内存c = torch.tensor(a)a += 1print(a, c)输出为:[4. 4. 4. 4. 4.] tensor([3., 3., 3., 3., 3.], dtype=torch.float64)

Tensor on GPU

# 以下代码只有在PyTorch GPU版本上才会执行
if torch.cuda.is_available():device = torch.device("cuda")          # GPUy = torch.ones_like(x, device=device)  # 直接创建一个在GPU上的Tensorx = x.to(device)                       # 等价于 .to("cuda")z = x + yprint(z)print(z.to("cpu", torch.double))       # to()还可以同时更改数据类型
输出:
tensor([0.7492], device='cuda:0')
tensor([0.7492], dtype=torch.float64)

torch.ones_like(input, dtype=None, layout=None, device=None, requires_grad=False) → Tensor

返回一个填充了标量值1的张量,其大小与之相同 input。

torch.ones_like(input)相当于 torch.ones(input.size(), dtype=input.dtype, layout=input.layout, device=input.device)

Parameters:
input (Tensor) – the size of input will determine size of the output tensor
dtype (torch.dtype, optional) – the desired data type of returned Tensor. Default: if None, defaults to the dtype of input.
layout (torch.layout, optional) – the desired layout of returned tensor. Default: if None, defaults to the layout of input.
device (torch.device, optional) – the desired device of returned tensor. Default: if None, defaults to the device of input.
requires_grad (bool, optional) – If autograd should record operations on the returned tensor. Default: False.

  相关解决方案