pytorch学习笔记(二):pytorch基础知识介绍

pytorch基础知识介绍

1. 张量

在pytorch中,得到的数据都需要处理为张量类型的数据,那什么是张量呢?

几何代数中定义的张量是基于向量和矩阵的推广,比如我们可以将标量视为零阶张量,矢量可以视为一阶张量,矩阵就是二阶张量。

  • 0维张量/标量 标量是一个数字
  • 1维张量/向量 1维张量称为“向量”。
  • 2维张量 2维张量称为矩阵
  • 3维张量 公用数据存储在张量 时间序列数据 股价 文本数据 彩色图片(RGB)

张量是现代机器学习的基础。它的核心是一个数据容器,多数情况下,它包含数字,有时候它也包含字符串,但这种情况比较少。因此可以把它想象成一个数字的水桶。

这里有一些存储在各种类型张量的公用数据集类型:

  • 3维=时间序列
  • 4维=图像
  • 5维=视频

在PyTorch中, torch.Tensor 是存储和变换数据的主要工具。如果你之前用过NumPy,你会发现 Tensor 和NumPy的多维数组非常类似。然而,Tensor 提供GPU计算和自动求梯度等更多功能,这些使 Tensor 这一数据类型更加适合深度学习。

下面介绍一下pytorch中简单的tensor操作

'''
这里的张量构造均类似于Numpy中的构造方法
'''

import torch
# 构造随机初始化矩阵
x = torch.rand(4, 3)
print("x: ", x)

# 构造一个矩阵全为0,而且数据类型是long
y = torch.zeros(4, 3, dtype = torch.long)
print("y: ", y)

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

#基于已经存在的tensor,创建一个tensor

p = x.new_ones(4, 3, dtype = torch.double)
print("p: ", p)
p = torch.randn_like(x, dtype = torch.float)
print("p: ", p)

print(p.size())
print(x.shape)

# 相关操作

# 加法操作
#方式一
x = torch.rand(4, 3)
y = torch.rand(4, 3)
print(x + y)

# 方式二
print(torch.add(x, y))

# 方式三 提供一个输出tensor作为参数
result = torch.empty(4, 3)
torch.add(x, y, out = result)
print("result: ", result)

# 方式四 In-place
y.add_(x)
print("y: ", y)


# 索引操作: 类似于numpy
# 需要注意的是:索引出来的结果与原数据共享内存,也即修改一个,另一个会跟着修改。
# 取第二列
print(x[:,1])


y = x[0, :]
y += 1
print(y == x[0, :])    #   源tensor也被改了

# 改变大小: 使用view方法改变tensor大小或者形状,类似于numpy的reshape方法
x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8) # -1是指这一维的维数由其他维度决定
print(x.size(), y.size(), z.size())

'''
注意 view()返回的新tensor与源tensor共享内存(其实是同一个tensor),
也即更改其中的一个,另外一个也会跟着改变。(顾名思义,view仅仅是改变了对这个张量的观察⻆度)  
'''
x += 1
print(x)
print(y)


# 广播机制,可以使不同形状的Tensor按元素进行运算,适当复制元素使得这两个tensor形状相同后再按元素运算

x = torch.arange(1, 3).view(1, 2)
print(x)
y = torch.arange(1, 4).view(3, 1)
print(y)
print(x + y)

2. 自动求导

PyTorch 中,所有神经网络的核心是 autograd 包。autograd包为张量上的所有操作提供了自动求导机制。它是一个在运行时定义 ( define-by-run )的框架,这意味着反向传播是根据代码如何运行来决定的,并且每次迭代可以是不同的。

torch.Tensor 是这个包的核心类。如果设置它的属性 .requires_gradTrue,那么它将会追踪对于该张量的所有操作。当完成计算后可以通过调用 .backward(),来自动计算所有的梯度。这个张量的所有梯度将会自动累加到.grad属性。

注意:在 y.backward() 时,如果 y 是标量,则不需要为 backward() 传入任何参数;否则,需要传入一个与 y 同形的Tensor。

要阻止一个张量被跟踪历史,可以调用.detach()方法将其与计算历史分离,并阻止它未来的计算记录被跟踪。为了防止跟踪历史记录(和使用内存),可以将代码块包装在 with torch.no_grad(): 中。在评估模型时特别有用,因为模型可能具有 requires_grad = True 的可训练的参数,但是我们不需要在此过程中对他们进行梯度计算。

还有一个类对于autograd的实现非常重要:FunctionTensor Function 互相连接生成了一个无环图 (acyclic graph),它编码了完整的计算历史。每个张量都有一个.grad_fn属性,该属性引用了创建 Tensor 自身的Function(除非这个张量是用户手动创建的,即这个张量的grad_fnNone )。

如果需要计算导数,可以在 Tensor 上调用 .backward()。如果 Tensor 是一个标量(即它包含一个元素的数据),则不需要为 backward() 指定任何参数,但是如果它有更多的元素,则需要指定一个gradient参数,该参数是形状匹配的张量。

import torch


# 创建张量,并设置requires_grad = True
x = torch.ones(2, 2, requires_grad = True)
print(x)

y = x**2
print(y.grad_fn)

z = y * y * 3
out = z.mean()
print(z, out)

# 缺失情况下默认 requires_grad = False
a = torch.randn(2, 2)
a = ((a * 3) / (a - 1))
print(a.requires_grad)
# 将requires_grad修改为True
a.requires_grad_(True)
print(a.requires_grad)
b = (a * a).sum()
print(b.grad_fn)

# 反向传播
out.backward()

# 输出倒数d(out)/dx
print(x.grad)

out2 = x.sum()
out2.backward()
print(x.grad)

#  注意:grad在反向传播过程中是累加的(accumulated),这意味着每一次运行反向传播,梯度都会累加之前的梯度,所以一般在反向传播之前需把梯度清零。
out3 = x.sum()
x.grad.data.zero_()
out3.backward()
print(x.grad)

3. Pytorch的并行计算

下面一图大致介绍了Pytorch并行计算的大致内容以及现在主流方法的简单介绍。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值