C++builder中的人工智能(7)如何在C++中开发特别的AI激活函数?
在当今的AI开发中,人工智能模型正迅速增加。这些模型使用数学函数来执行和学习,以便在传播时优化最佳结果,或在反向传播时选择最佳解决方案。其中之一就是激活函数。也称为转移函数或阈值函数,它决定了神经元的激活值作为输出,这个值是通过输入的加权值之和计算得出的。在这篇文章中,我们将描述当今最常用的激活函数,并展示如何在C++中使用它们。
目录
- 什么是AI激活函数?
- 我们如何在AI中开发特别的激活函数?
- 恒等函数(y=x)
- 二进制步函数(Heaviside步函数)
- 逻辑函数(Logistic曲线)和Sigmoid函数
- 双曲正切函数(tanh)
- 指数线性单元(ELU)
- 缩放指数线性单元(SELU)
- 修正线性单元(ReLU)
- 高斯误差线性单元(GELU)
- SoftPlus激活函数
- 自我规则非单调(Mish)激活函数
- Softmax函数
什么是AI激活函数?
激活函数(phi())也称为转移函数或阈值函数。它从净输入函数的给定值(sum)中确定激活值(a = phi(sum))。在净输入函数中,sum是它们权重中的信号之和。激活函数是这个和的新值,具有给定的函数或条件。激活函数是一种将所有加权信号的和转换为该信号的新激活值的方法。有不同的激活函数,一些常见的有线性(恒等)、双极性和逻辑(sigmoid)。
在C++中,你可以创建自己的AI激活函数。注意,“sum”是净输入函数的结果,它计算所有加权信号的和。我们将使用sum作为输入函数的结果。在这里,人工神经元(输出值)的激活值可以通过激活函数如下所示写出:
通过使用这个sum净输入函数值和phi()激活函数,我们可以计算输出。
我们如何在AI中开发特别的激活函数?
在AI开发中,有不同类型的激活函数用于不同的目的。我们可以使用它们,或者我们可以开发一个特别的激活函数。现在让我们看看AI开发中的激活函数类型。
1. 恒等函数(y=x)
恒等函数,也称为恒等关系或恒等映射或恒等变换,是数学中的一个函数,它总是返回用作其参数的相同值。我们可以简单地说它是y=x函数或f(x)=x函数。这个函数也可以作为一些AI应用中的激活函数。
这是一个非常简单的激活函数,也是恒等函数:
float phi(float sum) {return sum; // 恒等函数,线性转移函数 f(sum)=sum
}
这个函数的返回值应该是浮点数(float, double, long double),因为权重通常在0和1.0之间。
2. 二进制步函数(Heaviside步函数)
二进制步函数,或Heaviside步函数,或单位步函数,是一个步函数,以奥利弗·海维赛德(1850-1925)命名,其值对于负参数为零,对于正参数为一。这意味着它作为布尔值结果为0或1。这个函数是步函数的一般类别的例子,所有这些都可以表示为这种函数的平移的线性组合。
因此,我们的二进制步函数应该如下所示。
bool phi(float sum) {return (sum > 0); // 二进制步函数,Heaviside步函数,单位步函数
}
这个激活函数如果sum>0则返回1(true),否则返回0(false)。
3. 逻辑函数(Logistic曲线)和Sigmoid函数
逻辑函数或Logistic曲线是一个常见的S形曲线(sigmoid曲线),其方程如下。
在这里,
L是曲线的最大值,
x0是曲线中点的值,
k是逻辑增长率或曲线的陡峭程度
最常用的逻辑函数是标准逻辑函数,也称为Sigmoid函数,其中L和k为1,x0=0。因此,我们的函数可以写成以下任一术语,
在C++中,Sigmoid激活函数可以写成如下:
double phi(double sum) {return (1/(1+std::exp(-1*sum))); // 标准逻辑函数,Sigmoid函数
}
注意,这里的除法比乘法消耗更多的CPU,因为在上面给出的函数中,我们可以使用带有tanh()的版本,如下:
double phi(double sum) {return (0.5*(1+std::tanh(0.5*sum))); // 标准逻辑函数,Sigmoid函数
}
如你所见,我们这里只有乘法和加法以及tanh()函数。如果网络的sum值在范围内,例如在(0-10)之间,为了获得更快的近似结果,可以使用数组结果。可能有一个包含10000个成员的y数组,例如y[1001]可以持有phi(1.0001)的预计算值。这将使你的神经网络更快,但也可能引起更多错误或难以达到期望的迭代次数。它应该与上面的一个标准sigmoid函数版本一起测试。
4. 双曲正切函数(tanh)
双曲正切是一个三角函数tanh(),如下,
这个函数有唯一的解到微分方程f' = 1 - f^2, with f(0) = 0。
一个激活函数可以作为双曲正切函数使用,如下,
double phi(double sum) {return (std::tanh(sum)); // 双曲正切函数
}
5. 指数线性单元(ELU)
**指数线性单元(ELU)**是另一种激活函数,由Djork-Arne Clevert, Thomas Unterthiner & Sepp Hochreiter开发并发表,标题为“FAST AND ACCURATE DEEP NETWORK LEARNING BY EXPONENTIAL LINEAR UNITS (ELUS)”。你可以通过点击这里找到论文的文本。
根据他们的研究,他们引入了“指数线性单元”(ELU),它加快了深度神经网络中的学习速度,并导致了更高的分类准确率。ELU激活函数通过对于正值的身份缓解了消失梯度问题,如修正线性单元(ReLUs),泄漏ReLUs(LReLUs)和参数化ReLUs(PReLUs)。他们还证明了与其他激活函数的单元相比,ELUs具有改进的学习特性。与ReLUs相比
指数线性单元(ELU)可以写成如下。
这个函数的导数可以写成:
在C和C++编程语言中,简单的指数线性单元函数可以写成如下
double alpha = 0.1; // 范围从0到1.0
double phi(double sum) {return (sum > 0 ? sum : alpha*(std::exp(sum) - 1)); // ELU函数
}
6. 缩放指数线性单元(SELU)
缩放指数线性单元是另一种激活函数,它是通过使用λ参数的ELU的缩放版本。缩放指数线性单元由Günter Klambauer, Thomas Unterthiner,
Andreas Mayr在2017年开发并发布,他们介绍了自归一化神经网络(SNNs),以实现高级抽象表示。SNNs的神经元激活自动收敛到零均值和单位方差,而批量归一化需要显式归一化。
SELU是ELU激活函数的缩放版本,通过乘以λ参数,所以我们可以简单地说这个,
SELU激活函数可以写成如下,
他们为α和λ求解并得到解α01 ≈ 1.6733和λ01 ≈ 1.0507,其中下标01表示这些是固定点(0, 1)的参数。根据这个解释,每个节点可能有不同的α和λ参数。所以我们可以定义神经元结构中的alfa和lambda参数,我们可以计算SELU如下。
double phi(double sum) {return (sum > 0 ? lambda * sum : lambda * alpha * (std::exp(sum) - 1)); // SELU函数
}
7. 修正线性单元(ReLU)
在人工神经网络中,修正线性单元函数或ReLU激活函数定义为其参数的正部分。可以写成f(x) = max(0, x),其中x是输入信号的加权和。ReLU函数也称为Ramp函数,类似于电气工程中的半波整流。
这个函数称为参数化ReLU函数。如果Beta是0.01,它被称为Leaky ReLU函数。
这是max-out ReLU函数,
如果Beta是0,那么f(x) = max(x, 0)。这个函数将总是返回正数。让我们用C编程语言编写maxout ReLU函数,
这里是一个例子,
double phi(double sum) {return (std::max(0, sum)); // ReLU函数
}
8. 高斯误差线性单元(GELU)
高斯误差线性单元是ReLU、ELU函数的替代品,由Dan Hendrycks和Kevin Gimpel在2016年定义和发布。它用于平滑ReLU和ELU激活(全文可以在这里找到)
高斯误差线性单元(GELU)是一种高性能的神经网络激活函数。GELU激活函数是xΦ(x),其中Φ(x)是标准高斯累积分布函数。GELU非线性通过它们的值加权输入,而不是像ReLUs(x>0)那样通过它们的符号门控输入。对GELU非线性与ReLU和ELU激活的实证评估已应用于所有考虑的计算机视觉、自然语言处理和语音任务,并有性能提升。
GELU函数可以写成
我们可以用以下方式近似GELU,
或者如果更大的前馈速度值得牺牲精确性,我们可以使用以下近似,
我们可以使用不同的CDFs,即我们可以使用逻辑函数,累积分布函数CDF σ(x)来获得激活值,这称为Sigmoid Linear Unit(SiLU) xσ(x)。
根据第二个公式,我们可以用GELU编写我们的phi()激活函数如下,
double sqrt_2divPI = std::sqrt(2.0/M_PI);
double phi(double sum) {return (0.5 * sum * (1 + std::tanh(sqrt_2divPI * (sum + 0.044715 * std::pow(sum, 3))))); // GeLU函数
}
9. SoftPlus激活函数
SoftPlus激活函数由Dugas等人在2001年开发和发布。全文可以在这里找到。简单来说,Softplus函数可以写成如下,
f(x) = log(1+exp(x));
根据他们的论文;他们提出的函数类别的基本思想是,他们用Softplus或sigmoid函数替换了求和的sigmoid,每个维度上都有一个(使用Softplus在凸维度上,sigmoid在其他维度上)。他们引入了类似于多层神经网络的新函数类别具有这些属性的概念。
另一项由Xavier Glorot、Antoine Bordes、Yoshua Bengio发表的研究,全文标题为“Deep Sparse Rectifier Neural Networks”,可以在这里找到。根据这项研究,在人工神经网络中,虽然逻辑sigmoid神经元比双曲正切神经元更符合生物学,但后者在训练多层神经网络时效果更好。
SoftPlus激活函数在C++中可以写成如下:
double phi(double sum) {return (std::log(1 + exp(sum))); // SoftPlus函数
}
10. 自我规则非单调(Mish)激活函数
自我规则非单调(Mish)激活函数受到Swish激活函数的启发。它是一个平滑、连续、自我规则、非单调的激活函数。这个函数由Diganta Misra在2019年发表的“Mish: A Self Regularized Non-Monotonic Activation Function”中发布。
根据这项研究,“Mish使用自门控属性,其中非调制输入与输入的非线性函数的输出相乘。由于保留了少量的负信息,Mish通过设计消除了Dying ReLU现象所需的先决条件。这种属性有助于更好的表达性和信息流动。由于Mish无界,它避免了饱和,这通常会因为梯度接近零而导致训练速度减慢。在下方有界也是有利的,因为它会产生强烈的规则效应。与ReLU不同,Mish是连续可微的,这是一个可取的属性,因为它避免了奇异性,因此,在执行基于梯度的优化时避免了不希望的副作用。”
我们之前解释了softplus()激活函数。Mish激活函数可以使用softplus()定义如下,
因此,Mish激活函数可以数学定义如下,
作者比较了Mish、ReLU、SoftPlus和Swish激活函数的输出,并比较了Mish和Swish的第一和第二导数。
Mish函数可以在C++中编码如下,
double phi(double sum) {return (sum * std::tanh(std::log(1 + std::exp(sum)))); // Mish函数
}
11. Softmax函数
在神经网络中,SoftMax函数通常用于基于神经网络的分类器的最后一层。这些网络通常在对数损失或交叉熵方法下进行训练,这些方法是多项式逻辑回归的非线性变体。Softmax函数用于软化输出在0和1之间,它也可以用作激活函数。
对于一个有n个成员的x向量(或数组),每个成员的Softmax可以写成如下,
这个函数可能会因为无限结果而溢出。为了避免这个,我们可以通过减去最大值m来调制x值。
相关文章:

C++builder中的人工智能(7)如何在C++中开发特别的AI激活函数?
在当今的AI开发中,人工智能模型正迅速增加。这些模型使用数学函数来执行和学习,以便在传播时优化最佳结果,或在反向传播时选择最佳解决方案。其中之一就是激活函数。也称为转移函数或阈值函数,它决定了神经元的激活值作为输出&…...

更改lvgl图片的分辨率(减少像素)达到减小内存占用的目的
lvgl的内存占比过大,更改图片的分辨率(减少像素)达到减小内存占用的目的,可以用更多的空间去开发其他的功能 -- 由于lvgl中图片占的内存过大,所以需要更改图片的分辨率(降低像素的方式) --注意…...
python的socket库的基本使用总目录
章节总目录 一、Python 实现UDP通讯的简单模型 二、Python 实现TCP通讯的简单模型 三、Python 实现TCP和UDP通讯代码的区别...
golang学习3
Go 语言之旅...
Python解力扣算法题(六)(详解+注释)
# 1.学校打算为全体学生拍一张年度纪念照。根据要求,学生需要按照 非递减 的高度顺序排成一行。 # 排序后的高度情况用整数数组 expected 表示,其中 expected[i] 是预计排在这一行中第 i 位的学生的高度(下标从 0 开始)。 # 给你一…...

【C++】继承和多态常见的面试问题
文章目录 继承笔试面试题1. 什么是菱形继承?菱形继承的问题是什么?2. 什么是菱形虚拟继承?如何解决数据冗余和二义性?3. 继承和组合的区别?什么时候用继承?什么时候用组合? 选择题 多态概念考察…...

入门网络安全工程师要学习哪些内容(详细教程)
🤟 基于入门网络安全/黑客打造的:👉黑客&网络安全入门&进阶学习资源包 大家都知道网络安全行业很火,这个行业因为国家政策趋势正在大力发展,大有可为!但很多人对网络安全工程师还是不了解,不知道网…...

【游戏引擎之路】登神长阶(十二)——DirectX11教程:If you‘re going through hell, keep going!
【游戏引擎之路】登神长阶(十二)——DirectX11教程:If youre going through hell, keep going! 2024年 5月20日-6月4日:攻克2D物理引擎。 2024年 6月4日-6月13日:攻克《3D数学基础》。 2024年 6月13日-6月20日&#x…...

Python列表(一图秒了)
一、概念 所谓的列表是由一些列按照顺序存储的元素组成,区别于C语言中的数组,可以存储多种类型的数据,其中元素之间是没有任何关系的。 注意: 元素放在[]里面的,多个元素之间用 逗号 隔开列表的元素可以修改 定义 …...

雷池社区版 7.1.0 LTS 发布了
LTS(Long Term Support,长期支持版本)是软件开发中的一个概念,表示该版本将获得较长时间的支持和更新,通常包含稳定性、性能改进和安全修复,但不包含频繁的新特性更新。 作为最受欢迎的社区waf,…...

推荐一款功能强大的数据库开发管理工具:SQLite Expert Pro
SQLite Expert Professional是一个功能强大的工具,旨在简化SQLite3数据库的开发。 它是SQLite的一个功能丰富的管理和开发工具,旨在满足所有用户从编写简单SQL查询到开发复杂数据库的需求。 图形界面支持所有SQLite功能。 它包括一个可视化查询构建器&a…...

动态规划 之 路径问题 算法专题
一. 不同路径 不同路径 状态表示 dp[i][j] 表示走到[i][j]位置, 有几种不同的路径状态转移方程 以离[i][j] 最近的位置划分问题 1.从[i - 1][j] 到[i][j], 到[i][j]位置的不同路径数 就是和 到[i - 1][j]位置的不同路径数相同, 即dp[i][j] dp[i - 1][j] 2.从[i][j - 1] 到[i…...

从office套件接入GPT4谈自动化测试的前景
微软前几天发布了集成了GPT-4模型的office套件,从演示视频看,大概可以做这样一些事情 输入指令自动做表输入指令写邮件输入指定自动做ppt,而且一做就是好多页,挺震撼的 稍微了解了一下原理,大概流程是 用户发送prom…...
CentOS操作系统安装过程简介
以下是在CentOS(以CentOS 7为例)中使用Anaconda安装器的一般步骤: 1. 准备工作 - 首先,需要获取CentOS 7的安装介质,可以是光盘或者制作好的USB启动盘。然后将计算机设置为从对应的安装介质启动。 2. 启动安装程序 -…...

基于Multisim光控夜灯LED电路(含仿真和报告)
【全套资料.zip】光控夜灯LED电路设计Multisim仿真设计数字电子技术 文章目录 功能一、Multisim仿真源文件二、原理文档报告资料下载【Multisim仿真报告讲解视频.zip】 功能 1.采用纯数字电路,非单片机。 2.通过检测周围光线,光线暗且有声音时自动开灯…...

导师双选系统开发:Spring Boot技术详解
第一章 绪论 1.1 选题背景 如今的信息时代,对信息的共享性,信息的流通性有着较高要求,尽管身边每时每刻都在产生大量信息,这些信息也都会在短时间内得到处理,并迅速传播。因为很多时候,管理层决策需要大量信…...

双11花了“一部手机钱”买手机壳的年轻人,究竟在买什么?
【潮汐商业评论/原创】 这个双十一,Elsa在天猫多了一笔新支出——手机壳。和大家都熟悉的“义乌制造”不同的是,她的手机壳支出单件就已经到了500块,加上配套的手机链、支架、卡包、耳机壳,总共1000多元,足够买一部学…...
rediss数据结构及其底层实现
Redis 是一个基于内存的高性能键值对数据库,它支持多种数据结构,每种数据结构都有其特定的底层实现。以下是Redis中一些主要数据结构及其底层实现: 字符串(String): Redis的字符串类型使用简单动态字符串&a…...

自动化测试中使用Pytest Fixture?推荐10种常见用法!
Pytest 是一个功能强大的 Python 测试框架,其中的Fixture 是 Pytest 中的一个重要功能。它允许你设置一些特定的测试环境或准备测试数据,这些环境和数据可以在多个测试用例中重复使用。通过使用fixture,你可以避免在每个测试函数中编写重复的…...
Spring中的ConversionService,为Spring提供数据转换服务
在Spring中经常需要各种数据类型之间进行转换,比如配置文件中的数据转换为代码所需要的数据类型,在使用SpringMvc的时候,将前台传来的参数自动转换为我们接收参数时定义的类型。 Spring中的ConversionService就是提供这种服务的 1.DefaultC…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...