前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PyTorch 学习笔记

PyTorch 学习笔记

作者头像
caoqi95
发布2019-05-13 20:12:54
4650
发布2019-05-13 20:12:54
举报

Tensor

在 PyTorch 中 Tensor 代替了 NumPy 中的 Array,且可以使用 GPU 来加速计算。下面是一些例子。

代码语言:javascript
复制
# 构造一个 5x3 的矩阵
In [2]: x = torch.empty(5, 3)

In [3]: x
Out[3]:
tensor([[0.0000e+00, 0.0000e+00, 0.0000e+00],
        [0.0000e+00, 0.0000e+00, 0.0000e+00],
        [0.0000e+00, 0.0000e+00, 0.0000e+00],
        [0.0000e+00, 1.6591e-42, 0.0000e+00],
        [0.0000e+00, 0.0000e+00, 0.0000e+00]])
代码语言:javascript
复制
# 创建一个随机初始化的矩阵
In [4]: x = torch.rand(5, 3)

In [5]: x
Out[5]:
tensor([[0.1827, 0.6145, 0.4705],
        [0.9300, 0.1851, 0.8518],
        [0.6496, 0.9484, 0.9402],
        [0.3485, 0.1584, 0.4074],
        [0.8732, 0.4362, 0.3022]])
代码语言:javascript
复制
# 直接创建一个 tensor

In [8]: x = torch.tensor([5.5, 3])

In [9]: x
Out[9]: tensor([5.5000, 3.0000])
代码语言:javascript
复制
# 也可以在已存在的 tensor 的基础上创建一个变量
In [11]: x = x.new_ones(5, 3, dtype=torch.double)

In [12]: x
Out[12]:
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]], dtype=torch.float64)

In [13]: x = torch.randn_like(x, dtype=torch.float)

In [14]: x
Out[14]:
tensor([[-0.4083,  0.3295,  2.0638],
        [-0.1591,  2.4042, -0.1991],
        [ 0.1514, -0.3264,  0.6047],
        [ 0.2679,  0.1346,  0.4984],
        [-0.3599,  1.1166, -1.6757]])

In [15]: x.size()
Out[15]: torch.Size([5, 3])

原地计算

基本的加减乘除等等操作都支持的,且在 PyTorch 中支持 in-place, 即原地计算操作。任何使原地调整张量的操作都使用 _ 后缀。

Note: Any operation that mutates a tensor in-place is post-fixed with an _. For example: x.copy_(y), x.t_(), will change x.

代码语言:javascript
复制
In [16]: x = x.new_ones(5, 3)

In [17]: x
Out[17]:
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]])

In [19]: y = torch.rand(5, 3)

In [20]: y
Out[20]:
tensor([[0.7964, 0.3754, 0.4626],
        [0.0144, 0.7200, 0.8935],
        [0.8000, 0.6143, 0.1074],
        [0.4493, 0.2590, 0.3288],
        [0.8548, 0.2911, 0.9160]])

In [21]: y.add_(x)
Out[21]:
tensor([[1.7964, 1.3754, 1.4626],
        [1.0144, 1.7200, 1.8935],
        [1.8000, 1.6143, 1.1074],
        [1.4493, 1.2590, 1.3288],
        [1.8548, 1.2911, 1.9160]])

调整 shape

与其他框架不同,PyTorch 中使用 x.size() 来查看 shape,用 x.view() 来调整 shape。也支持 .shape().reshape()

代码语言:javascript
复制
In [22]: x = torch.randn(4,4)

In [23]: x
Out[23]:
tensor([[-0.5509, -1.7114, -0.7114,  0.7159],
        [ 1.0975,  0.8329,  0.6897,  1.1666],
        [ 0.4866, -0.3604,  0.2418,  0.6123],
        [ 0.7343,  0.2889,  0.3440, -0.4988]])

In [24]: y = x.view(16)

In [25]: y
Out[25]:
tensor([-0.5509, -1.7114, -0.7114,  0.7159,  1.0975,  0.8329,  0.6897,  1.1666,
         0.4866, -0.3604,  0.2418,  0.6123,  0.7343,  0.2889,  0.3440, -0.4988])

In [26]: y.size()
Out[26]: torch.Size([16])

In [27]: z = x.view(-1, 8)

In [28]: z
Out[28]:
tensor([[-0.5509, -1.7114, -0.7114,  0.7159,  1.0975,  0.8329,  0.6897,  1.1666],
        [ 0.4866, -0.3604,  0.2418,  0.6123,  0.7343,  0.2889,  0.3440, -0.4988]])

In [29]: z.size()
Out[29]: torch.Size([2, 8])

NumPy Array 与 PyTorch Tensor 互换

  • tensor 转换为 array:使用 .numpy()
代码语言:javascript
复制
In [30]: a = torch.ones(5)

In [31]: a
Out[31]: tensor([1., 1., 1., 1., 1.])

In [32]: b = a.numpy()

In [33]: b
Out[33]: array([1., 1., 1., 1., 1.], dtype=float32)

且在 a 的基础上修改,b 的值也会变化:

代码语言:javascript
复制
In [34]: a.add_(a)
Out[34]: tensor([2., 2., 2., 2., 2.])

In [35]: b
Out[35]: array([2., 2., 2., 2., 2.], dtype=float32)
  • array 转换成 tensor:使用 .from_numpy()
代码语言:javascript
复制
In [36]: import numpy as np

In [37]: a = np.ones(5)

In [38]: a
Out[38]: array([1., 1., 1., 1., 1.])

In [39]: b = torch.from_numpy(a)

In [40]: b
Out[40]: tensor([1., 1., 1., 1., 1.], dtype=torch.float64)

然后需要注意的是:除了字符 tensor 之外,CPU 上的所有 tensors 都支持转换为 NumPy 的 array。

CUDA Tensors

使用 .to 可以将 tensor 移动到任何设备上(GPU 或者 CPU)。

  • 确认 CUDA 是否可用:
代码语言:javascript
复制
In [41]: torch.cuda.is_available()
Out[41]: True
  • 将设备定义为 cuda
代码语言:javascript
复制
In [42]: device = torch.device("cuda")
  • 直接在 cuda 上创建变量:
代码语言:javascript
复制
In [43]: y = torch.ones_like(x, device=device)

In [44]: y
Out[44]:
tensor([[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.]], device='cuda:0')

自动求导机制

PyTorch 中神经网络的核心就在于自动求导机制,即 autograd 这个包。

torch.Tensorautograd 这个包的核心类:

  • 如果将 torch.Tensor 的属性 .requires_grad 设置为 True,那么将会追踪基于这个 tensor 的所有的操作。当完成计算后,你可以调用 .backend() 来自动计算所有的梯度。然后所有关于该 tensor 的梯度都会被累积在 .grad 这个属性中。
  • 想停止追踪一个 tensor,可以调用 .detach() 将其从计算历史中脱离出来,并防止未来的计算被追踪。
  • 要防止跟踪历史记录(和使用内存),还可以使用 torch.no_grad(): 包装代码块,这在评估模型时,可能特别有用,因为模型可能具有 requires_grad = True 的可训练参数,但我们不需要改变梯度。

还有 Function 这个类对自动梯度的实现非常重要:

  • TensorFunction 互联并建立一个非周期的计算图,然后编码成一个完整的计算历史。每个张量都有一个 .grad_fn 属性,该属性引用已创建 TensorFunction(除了用户创建的 Tensors - 它们的 grad_fnNone)。
  • 如果想要计算导数,可以在一个 tensor 上调用 .backend() 。如果该 tensor 是一个标量,则不需要为 .backend()指定任何的参数;如果不是标量,则需要为 .backend() 指定 gradient 这个参数,且该参数和 tensor 的形状需要匹配。
代码语言:javascript
复制
# 设定 requires_grad = True
In [45]: x = torch.ones(2, 2, requires_grad=True)

In [46]: x
Out[46]:
tensor([[1., 1.],
        [1., 1.]], requires_grad=True)

# 原地修改 requires_grad 属性
In [55]: a = torch.randn(2, 2)

In [56]: a = ((a*3)/(a-1))

In [57]: print(a.requires_grad)
False

In [58]: a.requires_grad_(True)
Out[58]:
tensor([[ 1.4352, -1.8208],
        [ 0.7062, 15.4992]], requires_grad=True)
In [59]: a.requires_grad
Out[59]: True
代码语言:javascript
复制
# 求梯度
In [60]: x = torch.ones(2, 2, requires_grad=True)

In [61]: x
Out[61]:
tensor([[1., 1.],
        [1., 1.]], requires_grad=True)

In [62]: y = x + 2

In [63]: y
Out[63]:
tensor([[3., 3.],
        [3., 3.]], grad_fn=<AddBackward0>)

In [64]: print(y.grad_fn)
<AddBackward0 object at 0x000001BED14C2D30>

In [65]: z = y * y * 3

In [66]: out = z.mean()

In [67]: out
Out[67]: tensor(27., grad_fn=<MeanBackward1>)

In [68]: out.backward()

In [69]: print(x.grad)
tensor([[4.5000, 4.5000],
        [4.5000, 4.5000]])
代码语言:javascript
复制
# 使用 with torch.no_grad() 关闭 requires_grad
In [70]: x.requires_grad
Out[70]: True

In [71]: (x ** 2).requires_grad
Out[71]: True

In [72]: with torch.no_grad():
    ...:     print((x ** 2).requires_grad)
    ...:
False
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.05.01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Tensor
  • 原地计算
  • 调整 shape
  • NumPy Array 与 PyTorch Tensor 互换
  • CUDA Tensors
  • 自动求导机制
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档