专栏首页机器学习爱好者社区【PyTorch】PyTorch如何构建和实验神经网络

【PyTorch】PyTorch如何构建和实验神经网络

作者 | Tirthajyoti Sarkar

来源 | Medium

编辑 | 代码医生团队

介绍

在本文中,将展示一个简单的分步过程,以在PyTorch中构建2层神经网络分类器(密集连接),从而阐明一些关键功能和样式。

PyTorch为程序员提供了极大的灵活性,使其可以在张量流过网络时创建,组合和处理张量……

核心组成

用于构建神经分类器的PyTorch的核心组件是

  • 张量(在PyTorch中央数据结构)
  • Tensor 的Autograd功能
  • nn.Module 类,用来建立任何其他神经类分类
  • 优化器
  • 损失函数

使用这些组件,将通过五个简单的步骤构建分类器

  • 将神经网络构造为自定义类(从该类继承nn.Module),其中包含隐藏层张量以及forward通过各种层和激活函数传播输入张量的方法
  • 使用此forward方法通过网络传播特征(从数据集)张量-得到一个output张量
  • 计算了loss通过比较output在地上真相,并使用内置的损失函数
  • 传播的梯度loss使用自动分化能力(Autograd)与backward方法
  • 使用损耗的梯度来更新网络的权重(这是通过执行所谓的优化器的一个步骤来实现的)optimizer.step()。

这个五步过程构成了一个完整的训练时期。只重复一遍,以降低损失并获得较高的分类精度。

包含五个核心组件的五步过程

在PyTorch,定义了一个神经网络作为一个自定义类,从而可以收获的全部好处Ø bject-Orineted编程(OOP)范例。

张量

torch.Tensor是一个多维矩阵,其中包含单个数据类型的元素。它是框架的中央数据结构。可以从Numpy数组或列表创建Tensor,并执行各种操作,例如索引,数学,线性代数。

张量支持一些其他增强功能,从而使其具有独特性。除CPU外,它们还可以加载到GPU中(只需极其简单的代码更改)即可进行更快的计算。并且它们支持形成一个向后图,该图跟踪使用动态计算图(DCG)应用于它们的每个操作以计算梯度。

Autograd

对于复杂的神经网络,都不擅长微积分。高维空间使头脑混乱。幸运的是有Autograd。

要处理14维空间中的超平面,请可视化3D空间并大声对自己说“十四”。每个人都做得到– Geoffrey Hinton

Tensor对象支持神奇的Autograd功能,即自动区分,这是通过跟踪和存储在Tensor流经网络时执行的所有操作来实现的。

nn.Module类

在PyTorch中,通过将其定义为自定义类来构建神经网络。然而不是从原来的Python派生object从该类继承nn.Module类。这为神经网络类注入了有用的属性和强大的方法。将在本文中看到此类定义的完整示例。

损失函数

损失函数定义了神经网络的预测与地面真实情况之间的距离,而损失的定量度量则帮助驱动网络更接近对给定数据集进行最佳分类的配置。

PyTorch提供了用于分类和回归任务的所有常见损失函数

  • 二元和多类交叉熵,
  • mean squared and mean absolute errors
  • smooth L1 loss
  • neg log-likelihood loss
  • Kullback-Leibler divergence

优化器

权重的优化以实现最低的损失是用于训练神经网络的反向传播算法的核心。PyTorch提供了大量的优化器来完成这项工作,这些优化器通过torch.optim模块公开

  • 随机梯度下降(SGD),
  • Adam, Adadelta, Adagrad, SpareAdam,
  • L-BFGS,
  • RMSprop

“五步过程构成了完整的训练时期。只重复一遍。”

神经网络类与训练

数据

对于此示例任务,首先使用Scikit-learn函数使用二进制类创建一些合成数据。在以下图表中,数据类别通过颜色区分。显然,数据集无法通过简单的线性分类器进行分离,而神经网络是解决此问题的合适机器学习工具。

用于分类示例的综合数据集

架构

选择了一个简单的完全连接的2隐藏层体系结构。如下图所示

类的定义

n_input = X.shape[1] # Must match the shape of the input features
n_hidden1 = 8 # Number of neurons in the 1st hidden layer
n_hidden2 = 4 # Number of neurons in the 2nd hidden layer
n_output = 1 # Number of output units (for example 1 for binary classification)

定义与该架构相对应的变量,然后定义主类。神经网络类定义如下所示。如前所述,它从nn.Module基类继承。

该代码几乎没有解释,带有添加的注释。在方法的定义中,forward,与Keras对模型的定义有很强的相似性。

另外,请注意使用内置线性代数运算nn.Linear(如在各层之间)和激活函数(如nn.ReLU和nn.Sigmoid在各层的输出处)。

如果实例化一个模型对象并打印它,将看到结构(与Keras的model.summary()方法平行)。

model = Network()
print(model)

Network(
  (hidden1): Linear(in_features=5, out_features=8, bias=True)
  (hidden2): Linear(in_features=8, out_features=4, bias=True)
  (relu): ReLU()
  (output): Linear(in_features=4, out_features=1, bias=True)
  (sigmoid): Sigmoid()
)

损失函数,优化器和训练

为此任务选择二进制交叉熵损失,并将其定义如下(按照惯例,损失函数通常criterion在PyTorch中调用)

criterion = nn.BCELoss() # Binary cross-entropy loss

在这一点上,通过定义的神经网络模型运行输入数据集,即一次向前通过并计算输出概率。由于权重已初始化为随机,因此将看到随机输出概率(大多数接近0.5)。该网络尚未训练。

logits = model.forward(X) # Output of the forward pass (logits i.e. probabilities)

如果打印出前10个概率,将得到类似的结果,

tensor([[0.5926],[0.5854],[0.5369],[0.5802],[0.5905],[0.6010],[0.5723],[0.5842],[0.5971],[0.5883]], grad_fn=<SliceBackward>)

所有输出概率看起来都接近0.5,

平均损失的计算方法很简单,

loss = criterion(logits,y)

对于优化程序,选择简单的随机梯度下降(SGD),并将学习率指定为0.1,

from torch import optim
optimizer = optim.SGD(model.parameters(),lr=0.1)

现在进行训练。再次遵循五个步骤

  • 将渐变重置为零(以防止渐变累积)
  • 将张量向前穿过层
  • 计算损失张量
  • 计算损失的梯度
  • 通过将优化器增加一级(沿负梯度的方向)来更新权重

令人惊讶的是,如果阅读了上面的五个步骤,这正是在神经网络的所有理论讨论(以及所有教科书)中看到的。而且借助PyTorch,可以一步一步使用看似简单的代码来实现此过程。

没有任何东西隐藏或抽象。会感到用五行Python代码实施神经网络训练过程的原始力量和兴奋!

# Resets the gradients i.e. do not accumulate over passes
optimizer.zero_grad()
# Forward pass
output = model.forward(X)
# Calculate loss
loss = criterion(output,y)
# Backward pass (AutoGrad)
loss.backward()
# One step of the optimizer
optimizer.step()

训练多个时期

那只是一个时期。现在很清楚一个时期不会削减它,是吗?要运行多个时期,只需使用循环即可。

epochs = 10
for i,e in enumerate(range(epochs)):
    optimizer.zero_grad() # Reset the grads
    output = model.forward(X) # Forward pass
    loss = criterion(output.view(output.shape[0]),y) # Calculate loss
    print(f"Epoch - {i+1}, Loss - {round(loss.item(),3)}")  # Print loss
    loss.backward() # Backpropagation
    optimizer.step() # Optimizer one step

当运行1000个时期时,可以轻松生成所有熟悉的损耗曲线。

想看看概率随时间变化吗?

PyTorch能够进行实验,探查,弄碎和晃动物品。

只是为了好玩,如果想检查输出层概率在多个时期内如何演变,只需对前面的代码进行简单的修改就可以了,

显然未经训练的网络输出都接近1,即在正类别和负类别之间没有区别。随着训练的继续,概率彼此分离,通过调整网络的权重逐渐尝试匹配地面真理的分布。

PyTorch使您能够进行实验,探查,弄碎和晃动物品。

还有其他流行的想法吗?试试

PyTorch从其早期版本开始就非常受欢迎,尤其是在学术研究人员和初创公司中。这背后的原因很简单-它可以通过简单的代码重构尝试疯狂的想法。实验是任何科学领域新思想发展的核心,当然,深度学习也不例外。

与两个激活功能混在一起吗?

只是为了(有点)疯狂,假设想将其与两个不同的激活函数-ReLU和Hyperbolic tangent(tanh)混合在一起。想将张量分成两个平行的部分,分别对它们应用这些激活,添加结果张量,然后正常地传播它。

看起来复杂吗?实现所期望的代码。将输入张量(例如X)传递通过第一个隐藏层,然后通过使结果张量流经单独的激活函数来创建两个张量X1和X2 。只需将结果张量加起来,然后使其通过第二个隐藏层即可。

可以执行此类实验性工作,并使用PyTorch轻松更改网络的体系结构。

实验是任何科学领域新思想发展的核心,当然,深度学习也不例外。

尝试自己的自定义损失函数?

可能会想尝试自己的自定义损失函数。自高中时代起,都使用均方误差。尝试对回归问题进行四次方次幂运算怎么样?

只需定义功能...

然后在代码中使用它(请注意reg_model,可以通过在Network类输出中关闭S型激活来构造新模型。

现在,有这种感觉吗?

结论

可以在Github存储库中找到此演示的所有代码。

https://github.com/tirthajyoti/PyTorch_Machine_Learning

在本文中,总结了一些关键步骤,可以遵循这些关键步骤来快速构建用于分类或回归任务的神经网络。还展示了如何使用此框架轻松地尝试巧妙的想法。

本文分享自微信公众号 - 机器学习爱好者社区(ML_shequ)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-02-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 机器学习常用损失函数小结

    转载自:https://zhuanlan.zhihu.com/p/77686118

    lujohn3li
  • 【连载22】OverFeat

    计算机视觉有三大任务:分类(识别)、定位、检测,从左到右每个任务是下个任务的子任务,所以难度递增。OverFeat是2014年《OverFeat:Integra...

    lujohn3li
  • 大小仅1MB!超轻量级的人脸识别模型火爆Github

    近日,用户Linzaer在Github上开源了一款适用于边缘计算设备、移动端设备以及 PC 的超轻量级通用人脸检测模型,该模型文件大小仅1MB,一经开源就霸榜G...

    lujohn3li
  • PyTorch如何构建和实验神经网络

    在本文中,将展示一个简单的分步过程,以在PyTorch中构建2层神经网络分类器(密集连接),从而阐明一些关键功能和样式。

    代码医生工作室
  • 谷歌GAN 实验室来了!迄今最强可视化工具,在浏览器运行GAN

    Google AI和乔治亚理工学院的研究人员发布了一个学习GAN的交互式网站:GAN Lab!由TensorFlow.js 驱动,在浏览器就可以运行GAN,非常...

    新智元
  • scala 学习笔记(07) 一等公民的函数

    在scala中一切皆对象,一切皆函数,函数跟Int,String、Class等其它类型是处于同等的地位,换句话说,使用函数跟使用普通的类型一样,没什么区别,因此...

    菩提树下的杨过
  • 有一种生意双方都觉得亏

    正好,最近我的学徒也分享了他在分析他们课题组数据项目的一个感悟,值得分享给大家,大家可以思考一下,为什么会有这样的生意,交易双方都觉得血亏呢?

    生信技能树
  • 一行代码自动调参,支持模型压缩指定大小,Facebook升级FastText

    FastText 是 Facebook 开源的一款自然语言处理机器学习框架。通过这套工具,用户可以快速完成诸如文本分类等的相关任务,而且不需要设计模型架构。近日...

    机器之心
  • Intellij Idea非常6的10个姿势!

    1、智能IDE 自动提示你可能要定义的变量及类的类型。 Maven dependency自动提示本地已经有的依赖。 类或者方法显示具体的参数名称。 CTRL +...

    Java技术栈
  • Ittiam优化VP9,turnaround时间大幅减少

    libvpx是Google开发的视频编解码器VP8和VP9的开源软件实现库。libvpx中包含了VP9视频编码算法,相比H.264/AVC,在高...

    用户1324186

扫码关注云+社区

领取腾讯云代金券