当前位置: 首页 > news >正文

神经网络基础--激活函数

🕹️学习目标

🕹️什么是神经网络 

1.神经网络概念

 2.人工神经网络

🕹️网络非线性的因素 

🕹️常见的激活函数 

1.sigmoid激活函数

2.tanh激活函数 

 3.ReLU激活函数

4.softmax激活函数

🕹️总结 


🕹️学习目标

  • 知道人工神经网络
  • 理解非线性因素
  • 知道常见激活函数 

🕹️什么是神经网络 

1.神经网络概念

人工神经网络( Artificial Neural Network, 简写为ANN)也简称为神经网络(NN),是一种模仿生物神经网络结构和功能的 计算模型。人脑可以看做是一个生物神经网络,由众多的神经元连接而成。各个神经元传递复杂的电信号,树突接收到输入信号,然后对信号进行处理,通过轴突输出信号。下图是生物神经元示意图:

当电信号通过树突进入到细胞核时,会逐渐聚集电荷。达到一定的电位后,细胞就会被激活,通过轴突发出电信号。 

 2.人工神经网络

我们通过图像来帮助我们更好的理解

🏓这个流程就像,来源不同树突(树突都会有不同的权重)的信息, 进行的加权计算, 输入到细胞中做加和,再通过激活函数输出细胞值。

接下来,我们使用多个神经元来构建神经网络,相邻层之间的神经元相互连接,并给每一个连接分配一个强度,如下图所示:

🏓同一层的神经元之间没有连接。 第 N 层的每个神经元和第 N-1层 的所有神经元相连(这就是full connected的含义), 第N-1层神经元的输出就是第N层神经元的输入。每个连接都有一个权值。 


🕹️网络非线性的因素 

激活函数用于对每层的输出数据进行变换, 进而为整个网络结构结构注入了非线性因素。此时, 神经网络就可以拟合各种曲线。如果不使用激活函数,整个网络虽然看起来复杂,其本质还相当于一种线性模型,如下公式所示:

  • 没有引入非线性因素的网络等价于使用一个线性模型来拟合
  • 通过给网络输出增加激活函数, 实现引入非线性因素, 使得网络模型可以逼近任意函数, 提升网络对复杂问题的拟合能力.

增加激活函数之后, 对于线性不可分的场景,神经网络的拟合能力更强。 

🕹️常见的激活函数 

1.sigmoid激活函数

sigmoid激活函数的函数图像如下: 

 sigmoid函数的优缺点:

  • 优点:输入值在 [-6, 6] 之间输出值才会有明显差异,输入值在 [-3, 3] 之间才会有比较好的效果
  • 缺点:通过上述导数图像,我们发现导数数值范围是 (0, 0.25),当输入 <-6 或者 >6 时,sigmoid 激活函数图像的导数接近为 0,此时网络参数将更新极其缓慢,或者无法更新,一般来说, sigmoid 网络在 5 层之内就会产生梯度消失现象。

sigmoid函数一般只用于二分类的输出层 

在 PyTorch 中使用 sigmoid 函数的示例代码如下:

import torch
import matplotlib.pyplot as plt
import torch.nn.functional as Fdef test():_, axes = plt.subplots(1, 2)# 函数图像x = torch.linspace(-20, 20, 1000)y = F.tanh(x)axes[0].plot(x, y)axes[0].grid()axes[0].set_title('Sigmoid 函数图像')# 导数图像x = torch.linspace(-20, 20, 1000, requires_grad=True)torch.sigmoid(x).sum().backward()axes[1].plot(x.detach(), x.grad)axes[1].grid()axes[1].set_title('Sigmoid 导数图像')plt.show()if __name__ == '__main__':test()

2.tanh激活函数 

 Tanh 叫做双曲正切函数,其公式如下:

Tanh的函数图像,导数图像如下:

与 Sigmoid 相比,它是以 0 为中心的,使得其收敛速度要比 Sigmoid 快,减少迭代次数。然而,从图中可以看出,Tanh 两侧的导数也为 0,同样会造成梯度消失。

代码实现:

import torch
import matplotlib.pyplot as plt
import torch.nn.functional as Fdef test():_, axes = plt.subplots(1, 2)# 函数图像x = torch.linspace(-20, 20, 1000)y = F.tanh(x)axes[0].plot(x, y)axes[0].grid()axes[0].set_title('Tanh 函数图像')# 导数图像x = torch.linspace(-20, 20, 1000, requires_grad=True)F.tanh(x).sum().backward()axes[1].plot(x.detach(), x.grad)axes[1].grid()axes[1].set_title('Tanh 导数图像')plt.show()if __name__ == '__main__':test()

 3.ReLU激活函数

ReLU的激活函数公式如下:

函数图像如下:

  • 从上述函数图像可知,ReLU 激活函数将小于 0 的值映射为 0,而大于 0 的值则保持不变,它更加重视正信号,而忽略负信号,这种激活函数运算更为简单,能够提高模型的训练效率。
  • 但是,如果我们网络的参数采用随机初始化时,很多参数可能为负数,这就使得输入的正值会被舍去,而输入的负值则会保留,这可能在大部分的情况下并不是我们想要的结果。

ReLU的导数图像如下:

🏓与sigmoid相比

RELU的优势是采用sigmoid函数,计算量大(指数运算),反向传播求误差梯度时,求导涉及除法,计算量相对大,而采用Relu激活函数,整个过程的计算量节省很多。 sigmoid函数反向传播时,很容易就会出现梯度消失的情况,从而无法完成深层网络的训练。 Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。

缺点也很突出,随着训练的推进,部分输入会落入小于0区域,导致对应权重无法更新。这种现象被称为“神经元死亡”。

4.softmax激活函数

softmax用于多分类过程中,它是二分类函数sigmoid在多分类上的推广,目的是将多分类的结果以概率的形式展现出来。

计算方法如下图所示:

Softmax 直白来说就是将网络输出的 logits 通过 softmax 函数,就映射成为(0,1)的值,而这些值的累和为1(满足概率的性质),那么我们将它理解成概率,选取概率最大(也就是值对应最大的)节点,作为我们的预测目标类别。 

代码实现:

import torchif __name__ == '__main__':scores = torch.tensor([0.2, 0.02, 0.15, 0.15, 1.3, 0.5, 0.06, 1.1, 0.05, 3.75])probabilities = torch.softmax(scores, dim=0)print(probabilities)

程序输出结果:

tensor([0.0212, 0.0177, 0.0202, 0.0202, 0.0638, 0.0287, 0.0185, 0.0522, 0.0183,0.7392])

🕹️总结 

本小节带着同学们了解下常见的激活函数,以及对应的 API 的使用。除了上述的激活函数,还存在很多其他的激活函数,如下图所示:

这么多激活函数, 我们应该如何选择呢?

对于隐藏层:

  1. 优先选择RELU激活函数

  2. 如果ReLu效果不好,那么尝试其他激活,如Leaky ReLu等。

  3. 如果你使用了Relu, 需要注意一下Dead Relu问题, 避免出现大的梯度从而导致过多的神经元死亡。

  4. 不要使用sigmoid激活函数,可以尝试使用tanh激活函数

对于输出层

  1. 二分类问题选择sigmoid激活函数

  2. 多分类问题选择softmax激活函数

  3. 回归问题选择identity激活函数

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 深拷贝——JSON.stringify()序列化和JSON.prase()反序列化
  • 【C语言】Top K问题【建小堆】
  • 浙大版《C语言程序设计(第3版)》题目集
  • JavaScript 继承百花齐放:从原型链到 ES6 类
  • 软设之TCP/IP协议
  • 软科中国大学排名爬虫+数据可视化
  • 图片管理组建
  • Flink 实时数仓(三)【DWD 层搭建(一)】
  • 《人性的枷锁:菲利普的人生探索能解开枷锁吗?》
  • 树套树模板
  • PYTHON专题-(5)类的专有方法
  • 每日学术速递8.3
  • Xilinx管脚验证流程及常见问题
  • conda环境pip 安装Tensorflow-gpu 2.10.2提示nbconvert 的包依赖冲突
  • OpenStack Yoga版安装笔记(十二)nova安装(下)
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • Android Studio:GIT提交项目到远程仓库
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • E-HPC支持多队列管理和自动伸缩
  • GraphQL学习过程应该是这样的
  • Less 日常用法
  • Mybatis初体验
  • Phpstorm怎样批量删除空行?
  • 动态规划入门(以爬楼梯为例)
  • 欢迎参加第二届中国游戏开发者大会
  • 经典排序算法及其 Java 实现
  • 开源SQL-on-Hadoop系统一览
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 三分钟教你同步 Visual Studio Code 设置
  • ​​​​​​​开发面试“八股文”:助力还是阻力?
  • ​Redis 实现计数器和限速器的
  • ​zookeeper集群配置与启动
  • # centos7下FFmpeg环境部署记录
  • #android不同版本废弃api,新api。
  • #java学习笔记(面向对象)----(未完结)
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (32位汇编 五)mov/add/sub/and/or/xor/not
  • (4)logging(日志模块)
  • (C++二叉树05) 合并二叉树 二叉搜索树中的搜索 验证二叉搜索树
  • (MTK)java文件添加简单接口并配置相应的SELinux avc 权限笔记2
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (剑指Offer)面试题34:丑数
  • (算法二)滑动窗口
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (转载)Google Chrome调试JS
  • .mysql secret在哪_MYSQL基本操作(上)
  • .NET : 在VS2008中计算代码度量值
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .net程序集学习心得
  • .NET上SQLite的连接
  • .NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
  • .vue文件怎么使用_vue调试工具vue-devtools的安装
  • ??如何把JavaScript脚本中的参数传到java代码段中
  • @antv/g6 业务场景:流程图
  • @WebService和@WebMethod注解的用法