pytorch入门

it2022-05-05  136

背景

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


最新回复(0)