Pytorch 中神经网络的构建(简易版)-- Pytorch深度学习实战 Chapter 6

使用神经网络拟合函数

人工神经网络

线性变换 + 固定的非线性函数(激活函数),多次变换组成的就是多层神经网络。

激活函数的作用:

  1. 在模型内部,允许输出函数在不同值上有不同的斜率(这是线性函数做不到的)
    通过巧妙为许多输出设置不同的斜率,神经网络可以近似任意函数。
  2. 在网络最后一层的作用是将前面的线性运算的输出集中到给定的范围内。

限制输出范围

torch.nn.Hardtanh() 简单激活函数,默认范围是 -1 到 1。对输出值设置上限:大于1为1,小于-1为-1。

压缩输出范围

常使用torch.nn.Sigmoid(),包括各类激活函数。这些函数在x趋于负无穷时逐渐接近0或-1,随着x逐渐接近1,函数在x==0时具有基本恒定的斜率。
从概念上将,这类函数效果很好,因为在线性函数输出的中间有一块区域神经函数对其很敏感,而其他所有东西都集中在边界值旁边。

ReLU被认为是目前性能最好的通用激活函数之一。

Sigmoid激活函数也被称为logistic函数,在早期的深度学习中被广泛使用,除非明确希望将输出规范到0-1,例如当输出应该是一个概率的时候。

浅记录一下两函数的对比:
引入ReLU的原因是1:采用Sigmoid等函数算激活函数时(指数运算)计算量大,反向传播求误差梯度时涉及除法,计算量相对大,采用ReLU节约计算量。
2:深层网络 Sigmoid函数反向传播时容易出现梯度消失的情况(在sigmoid接近饱和区时,变换太缓慢,导数趋于0,这种情况会造成信息丢失无法完成深度网络的训练。
3:ReLU会使一部分神经元的输出为0,造成了网络的稀疏性,并减少了参数的相互依存关系,缓解了过拟合问题的发生。

参考链接:https://blog.csdn.net/lhyyhlfornew/article/details/97391967

随着问题维度的增长,输入输出关系变得复杂。物理学家或应用数学家的工作往往是从第一原理出发,对一种现象进行功能性描述,然后从测量中估计未知的参数,从而得到一个精确的、真实世界的模型。另一方面,深度神经网络是一组函数,能够近似出大范围的输入输出关系,而不需要对某一现象构建解释模型。
某种程度上,放弃解释来换取解决日益复杂问题的可能性。换句话说,有时缺乏能力、信息或计算资源来为我们所呈现的事物建立一个明确的模型,所以数据驱动是前进的唯一途径。

Python nn模块

该模块包含创建各种神经网络结构所需的构建块(层)。Pytorch模块派生自基类nn.Module,一个模块可以有一个或多个参数实例作为属性,这些参数实例是张量,它们的值在训练过程中国得到了优化。一个模块还可以有一个或多个子模块作为属性,并且它还能够追踪它们的参数。
子模块必须是顶级属性,而不是隐藏在列表或dict实例中,否则,优化器将无法定位子模块以及它们的参数。对于模型需要一列或一组子模块的情况,pytorch提供了nn.ModuleList和nn.ModuleDict。

可以找到nn.Module的一个子类 nn.Linear,通过参数属性、权重和偏置对输入应用仿射变换.

使用__call__()而不是 forward()

Pytorch提供的所有nn.Module的子类都定义了它们的__call__()方法。可以实例化一个nn.linear,并像调用函数一样调用它。

模块的输入

为了容纳多个样本,模块希望输入的第0维是批次中的样本数。

  1. 批量输入
    nn中的所有模块都被编写为可以同时为多个输入产生输出。
  2. 优化批次
    通过unsqueeze(a)在第a轴添加一个维度
    可以使用parameters()方法来访问任何nn.Module或它的子模块拥有的参数列表。
    调用optimizer.step()时,它将遍历每个参数,并按其grad属性中存储的内容的比例对其进行修改。
    nn包含几个常见的损失函数,其中包括nn.MSELoss()。可将其作为函数调用。

神经网络模型的构建

由于历史原因,第1个线性模型 + 激活层通常被称为隐藏层,因为它的输出并不是直接能够观察到的,而是被输入到下一层。输入和输出模型的大小都为1,第一个线性模块的输出大小通常大于1。
【除输入层和输出层以外的其他各层叫做隐藏层,隐藏层不直接接受外界的信号,也不直接向外界发送信号。

nn提供了一种通过 nn.Sequential 容器来连接模型的方式

参考链接:https://blog.csdn.net/Just_do_myself/article/details/124195393

一个序列容器,用于搭建神经网络的模块被按照被传入构造器的顺序添加到nn.Sequential()容器中。
除此之外,一个包含神经网络模块的OrderedDict也可以被传入nn.Sequential()容器中。利用nn.Sequential()搭建好模型架构,模型前向传播时调用forward()方法,
模型接收的输入首先被传入nn.Sequential()包含的第一个网络模块中。然后,第一个网络模块的输出传入第二个网络模块作为输入,按照顺序依次计算并传播,直到nn.Sequential()里的最后一个模块输出结果。
也就是将第1个模块所期望的输入指定为nn.Sequential的一个参数,将中间输出传递给后续模块,并产生最后一个模块返回的输出。

本节介绍了一些关于参数检查的方式,有需要就去看看~

posted @ 2022-10-31 16:55  芋圆院长  阅读(214)  评论(0编辑  收藏  举报