PyTorch|PyTorch教程(6)构建基本的神经网络模型

问题(1) 如何使用PyTorch构建基本的神经网络模型?
解决方案 在PyTorch中构建基本神经网络模型需要6个步骤:准备训练数据,初始化权值,创建基本网络模型,计算损失函数,选择学习率,优化模型参数对应的损失函数。
实操 让我们循序渐进的来创建一个基本的神经网络模型。

import numpy as np import torch import torch.nn as nndef pre_data(): train_X=np.asarray([13.4, 14.3,15.6,16.8,16.9,14.1,19.8,16.2,17.6]) train_Y=np.asarray([11.7, 12.8,12.1,13.2,17.1,15.0,20.0,16.1,17.2]) x=torch.from_numpy(train_X).to(dtype=torch.float32).view(9,1) y=torch.from_numpy(train_Y).to(dtype=torch.float32).view(9,1) return x,y

【PyTorch|PyTorch教程(6)构建基本的神经网络模型】为了显示神经网络模型,我们准备数据集并将数据类型更改为浮点张量。在一个项目中,构建它的数据准备是一个独立的活动。数据准备应以适当的方式进行。在前面的步骤中,train_X和train_Y是2个NumPy向量。接下来,我们将数据类型更改为浮点张量,因为这是矩阵乘法所必需的。下一步是将其转换为二维Tensor,在数据集中,我们有9个一维的数据。
def set_weights(): w = torch.randn(1, requires_grad=True) b = torch.randn(1, requires_grad=True) return w,bdef build_network(x): y_pred=torch.matmul(x,w) + b return y_pred

set_weight()函数的作用是:初始化神经网络模型权值。我们需要两个张量,权值和偏差。build_network()函数只是将权重与输入相乘,向其添加偏差,并生成预测值。这是我们建立的一个自定义函数。如果我们需要在PyTorch中实现相同的事情,那么当我们需要使用nn.Linear()进行线性回归时,使用它会简单得多。
def loss_calc(y,y_pred): loss=(y_pred.view(y.shape)-y).pow(2).sum() print(loss) for param in [w,b]: if not param.grad is None: param.grad.data.zero_() loss.backward() return loss.item()def optimize(lr): w.data -= lr*w.grad.data b.data -= lr*w.grad.data learning_rate=1e-4# 学习率x,y=pre_data()# 训练数据 w,b=set_weights()# 参数 for i in range(10): y_pred = build_network(x)# 计算wx+b的函数 loss=loss_calc(y,y_pred)# 损失计算 if i % 1000==0: print(loss) optimize(learning_rate) print(w, b) # 320.27197265625 # 22.407217025756836 # 22.407217025756836 # 22.407217025756836 # 22.407217025756836 # tensor([0.9180], requires_grad=True) tensor([0.3142], requires_grad=True)

一旦我们定义了网络结构,我们就需要将结果与输出进行比较,以评估预测结果。跟踪系统精度的度量是损失函数,我们希望它是最小的。损失函数可能有不同的形状。我们如何确切地知道哪里的损失最小,哪个迭代提供了最好的结果?要知道这一点,我们需要将优化函数应用到损失函数上; 它找到最小损失值。然后我们可以提取与该迭代相对应的参数。
import matplotlib.pyplot as plt x_numpy = x.data.numpy() y_numpy = y.data.numpy() y_pred = y_pred.data.numpy() plt.plot(x_numpy, y_numpy, "o") plt.plot(x_numpy, y_pred, '-') plt.show()

PyTorch|PyTorch教程(6)构建基本的神经网络模型
文章图片

问题(2) 什么是张量微分,它与使用PyTorch框架的计算图执行有什么关系?
解决方案 计算图网络由节点表示,并通过函数连接。有两种不同的节点:依赖的和独立的。依赖节点等待来自其他节点的结果来处理输入。独立的节点连接在一起,它们要么是常量,要么是结果。张量微分是在计算图环境中进行计算的一种有效方法。
实操 在计算图中,张量微分是非常有效的,因为张量可以被计算为并行节点、多进程节点或多线程节点。主要的深度学习和神经计算框架都包括这个张量微分。
Autograd是帮助执行张量微分的函数,这意味着计算损失函数的梯度或斜率,并通过神经网络反向传播损失,以微调权重和偏差。通过学习率和迭代,尽量减少损失值。
要应用张量微分,需要应用nn.backward()方法。让我们举个例子,看看损失梯度是如何反向传播的。为了更新损失函数的曲线,或者找到损失函数在哪里最小以及它在哪个方向移动,需要进行导数计算。张量微分是在计算图中计算函数斜率的一种方法。
import torch x1 = torch.ones(4,4, requires_grad=True) print(x1) # tensor([[1., 1., 1., 1.], #[1., 1., 1., 1.], #[1., 1., 1., 1.], #[1., 1., 1., 1.]], requires_grad=True) x = x1*12.5 x.retain_grad()# 默认只保存叶子节点的导数,如果需要保存中间变量的导数,需要设置.retain_grad() print(x) # tensor([[12.5000, 12.5000, 12.5000, 12.5000], #[12.5000, 12.5000, 12.5000, 12.5000], #[12.5000, 12.5000, 12.5000, 12.5000], #[12.5000, 12.5000, 12.5000, 12.5000]], grad_fn=) fn=2*(x*x)+5*x+6# 2x^2+5x+6 fn.backward(torch.ones(4,4)) print(x.grad) # tensor([[55., 55., 55., 55.], #[55., 55., 55., 55.], #[55., 55., 55., 55.], #[55., 55., 55., 55.]]) print(x.is_leaf) # False# x不是叶子节点

在这个脚本中,x是一个样本张量,需要进行自动梯度计算。fn是一个使用x变量创建的线性函数。使用backward 函数,我们可以执行向后传播计算。grad()函数保存了张量微分的最终输出。
总结 我们使用小样本张量创建了一个基本的神经网络模型,使用优化更新了权值,并生成了预测。

    推荐阅读