pytorch入门

背景

Numpy也可以实现神经网络(前向和后向传递都是手工实现),缺点是不Numpy能利用GPU加速,而且对于复杂的网络,反向传递环节很难编写。

Autograd

Pytorch的Autograd可以使用自动微分 来自动计算神经网络中的后向传递。使用autograd时,网络的正向传递将定义 计算图形 ; 图中的节点将是张量,边将是从输入张量产生输出张量的函数
1.设置requires_grad 为 True,那么将会追踪所有对于该张量的操作。
2.每个张量都有一个.grad_fn属性,这个属性引用了一个创建了Tensor的Function(除非这个张量是用户手动创建的,即,这个张量的 grad_fn 是 None)。
如果需要计算导数,你可以在Tensor上调用.backward()。 如果Tensor是一个标量(即它包含一个元素数据)则不需要为backward()指定任何参数, 但是如果它有更多的元素,你需要指定一个gradient 参数来匹配张量的形状。
3.为了防止跟踪历史记录(和使用内存),可以将代码块包装在with torch.no_grad():中。 在评估模型时特别有用,因为模型可能具有requires_grad = True的可训练参数,但是我们不需要梯度计算

神经网络

1.神经网络的典型训练过程如下:

定义包含一些可学习的参数(或者叫权重)神经网络模型;
在数据集上迭代;
通过神经网络处理输入;
计算损失(输出结果和正确值的差值大小);
将梯度反向传播回网络的参数;
更新网络的参数,主要使用如下简单的更新原则: weight = weight - learning_rate * gradient

2.重要的知识点:
1.nn.Module:神经网络模块。封装参数、移动到GPU上运行、导出、加载等。

#利用nn实现网络
model = torch.nn.Sequential(
    torch.nn.Linear(D_in, H),
    torch.nn.ReLU(),
    torch.nn.Linear(H, D_out),
)

有时候需要需要指定比现有模块序列更复杂的模型,可以通过子类化nn.Module和定义forward接收输入Tensors并使用其他模块或Tensors上的其他autograd操作生成输出Tensors 来定义自己的模块

class TwoLayerNet(torch.nn.Module):
    def __init__(self, D_in, H, D_out):
        """
        In the constructor we instantiate two nn.Linear modules and assign them as
        member variables.
        """
        super(TwoLayerNet, self).__init__()
        self.linear1 = torch.nn.Linear(D_in, H)
        self.linear2 = torch.nn.Linear(H, D_out)

    def forward(self, x):
        """
        In the forward function we accept a Tensor of input data and we must return
        a Tensor of output data. We can use Modules defined in the constructor as
        well as arbitrary operators on Tensors.
        """
        h_relu = self.linear1(x).clamp(min=0)
        y_pred = self.linear2(h_relu)
        return y_pred
        
model = TwoLayerNet(D_in, H, D_out)

2.nn.Parameter:一种变量,当把它赋值给一个Module时,被 自动 地注册为一个参数(返回可被学习的参数(权重)列表和值)。
3.将所有参数的梯度缓存清零,然后进行反向传播。
4.nn包里可以调用很多损失函数。

criterion = nn.MSELoss()
loss = criterion(output, target)
#follow loss in the backward direction, using its .grad_fn attribute
print(loss.grad_fn)  # MSELoss
print(loss.grad_fn.next_functions[0][0])  # Linear

5.调用loss.backward()获得反向传播的误差。
从PyTorch的设计原理上来说,在每次进行前向计算得到pred时,会产生一个用于梯度回传的计算图,这张图储存了进行back propagation需要的中间结果,当调用了.backward()后,会从内存中将这张图进行释放。
注:在调用前需要清除已存在的梯度,否则梯度将被累加到已存在的梯度,也有少数不清楚的操作,一般用于内存不够等情况,慎用
有两种:net.zero_grad()和optimizer.zero_grad()
6.更新权重,常用的是SGD,optim提供了各种不同的更新规则,如Adam等

#weight = weight - learning_rate * gradient
for f in net.parameters():
    f.data.sub_(f.grad.data * learning_rate)
*************************************************
import torch.optim as optim
# create your optimizer
optimizer = optim.SGD(net.parameters(), lr=0.01)
# in your training loop:
optimizer.zero_grad()   # zero the gradient buffers
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step()    # Does the update

参考文献

https://pytorch.org/tutorials/beginner/pytorch_with_examples.html
https://github.com/zergtant/pytorch-handbook

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值