PyTorch教程1

三大要素支撑起了近十年 Deep Leanring 的发展浪潮: DL algorithm, Big data, Computation power. 从本节起,我们学习一下 PyTorch 的使用。

创建Tensor

首先,什么是Tensor?Tensor是一个任意维度的矩阵 (从标量开始). 而编写神经网络 (NN) 的过程其实就是一个构建一个Tensor的计算图的过程。其中,所有参与计算的变量都要以Tensor的形式存在。 创建一个Tensor也很简单:

  1. 直接创建 torch.Tensor
import torch
# torch.Tensor(data, dtype=None, device= None, requires_grad = False)
t1 = torch.Tensor([[1,2],[3,4]])

device – 可以看到,这样初始化的tensor是没有指定device的。device取值可以是 ‘cpu’ 或 ‘cuda’ 其中 cuda还可以有不同的设备index 比如 ‘cuda:0’ ‘cuda:1’ 等等. 如果没有设备device那它就放在 torch.cuda.current_device() 中一般是第0个device。而初始化没有指定device那就放在cpu中,我们也可以把它放进cuda中

device1 = torch.device('cuda:0')
t2 = t1.to(device1)
print(t1.device) >>> device(type='cpu')
print(t2.device) >>> device(type='cuda:0')

可以看到, t1 仍然在cpu中,而新生成的 t2 在cuda中。
grad – 一个Tensor由两部分组成,data 和 grad。分别用来存放数据和数据的gradient。初始的Tensor requires_grad = False,因此我们需要把它的 requires_grad = True 才会在back propagation时为它计算gradient。

特别的,t1.data 和 t1.grad 也是一个 Tensor. 因此,如果我们直接取值print的结果都是tensor,而一种拿到标量值的方式就是item() (注意,只能对标量tensor使用):

t1.requires_grad = True
print(t1) >>> tensor
print(t1.data) >>> tensor
print(t1[0]) >>> tensor
print(t1[0][0].item()) >>> scalar = 1
  1. 从 numpy 转换到 Tensor
data1 = np.array([1,2,3,4])
t2 = torch.from_numpy(data1)
t3 = torch.from_numpy(data1).to(device1)

注意,cpu中的tensor t2 和 data1 是共享内存的,如果修改了其中一个另一个相应也会改变;而 t3 显然和他俩都不共享内存毕竟设备都不同。

  1. 直接创建特定形式的 Tensor
    我们还可以用torch直接产生特定形式的Tensor,比如
torch.zeros(*sizes, out=None, ..) #返回大小为sizes的零矩阵
torch.zeros_like(input, ..) # 返回与input相同size的零矩阵
torch.eye(n, m=None, out=None,) #返回2-D 的单位对角矩阵
torch.empty_like(input,) # 返回与input相同size,并被未初始化的数值填充的tensor
torch.normal(mean, std, out=None)
torch.rand(*size, out=None, dtype=None,) #返回[0,1]之间均匀分布的随机数值
torch.rand_like(input, dtype=None,) #返回与input相同size的tensor, 填充均匀分布的随机数值
torch.randperm(n, out=None, dtype=torch.int64) # 返回0到n-1的数列的随机排列

可以参考 https://zhuanlan.zhihu.com/p/36233589 中的总结。

一个例子

下面我们来看一个例子,强化一下刚刚的内容(注意其中的注释)

import torch
w = torch.Tensor([0.1]) # 初始化tensor
w.requires_grad = True # 需要设定grad因为等下需要

def forward(x):
    return w * x # simple linear model
    # 注意,由于 w 是Tensor,input x 标量会被强制转换为Tensor且 * 也变成Tensor乘

def loss(x,y):
    predicted = forward(x)
    return (predicted-y) ** 2 # MSE loss

x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]

for epoch in range(20):
    for x, y in zip(x_data, y_data):
        # 这一步对Tensor的操作实际上就是在构建一个计算图
        l = loss(x, y) # 给定一组数据先算loss
        l.backward() # 这一步就是在计算所有gradients 并存在w里
        # 梯度计算完成了计算图就被释放了,下次调用loss就会再重新构建一个计算图
        # 取Tensor的data计算不会建立计算图,虽然w.data也是Tensor
        w.data = w.data - 0.01 * w.grad.data # 纯数值修改
        # 由backward()计算的梯度会持续累积,所以每次必须清零
        w.grad.data.zero_()
    print("process:", epoch, l.item())
    
print(forward(3).item())

另一个例子

import torch
# 神经网络
class LineaModel(torch.nn.Module):
    def __init__(self):
        super(LineaModel, self).__init__()
        self.linear = torch.nn.Linear(1, 1)
    def forward(self, x):
        predicted = self.linear(x)
        return predicted

model = LineaModel()
criterion = torch.nn.MSELoss(size_average = loss)
optimizer = torch.optim.SGD(model.parameters(), lr =  0.01)

x_data = torch.Tensor([[1.],[2.],[3.]])
y_data = torch.Tensor([[2.],[4.],[6.]])

for epoch in range(10000):
    y_predicted = model(x_data)
    loss = criterion(y_predicted, y_data)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    
print(model(torch.Tensor([0.4])))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值