在这篇文章中,我们将探讨最受欢迎的激活函数之一——Sigmoid函数。我们将解释什么是Logistic函数,以及它与Sigmoid函数的区别,并展示如何在C++应用中使用这些函数。
目录
- 人工神经网络(ANN)中的激活函数是什么?
- Logistic函数(Logistic曲线)是什么?
- 标准Logistic函数(Sigmoid函数)是什么?
- Sigmoid函数(标准Logistic函数)的示例
人工神经网络(ANN)中的激活函数是什么?
激活函数(phi()),也称为转移函数或阈值函数,它根据净输入函数的给定值(sum)确定激活值(a = phi(sum))。在这里,sum是它们权重中的信号之和,激活函数是这个和的新值,具有给定的函数或条件。换句话说,激活函数是将所有加权信号的和转换为该信号的新激活值的方法。有不同类型的激活函数,通常使用的是线性(恒等)、双极性和逻辑(sigmoid)函数。
在C++(以及大多数编程语言)中,你可以创建自己的激活函数。注意,sum是净输入函数的结果,它计算所有加权信号的和。我们将使用sum作为输入函数的结果。在这里,人工神经元(输出值)的激活值可以通过激活函数如下所示,
通过使用这个sum净输入函数值和phi()激活函数,让我们看看C++中的一些激活函数;现在让我们看看如何在这个示例公式中使用二进制步进函数,
Logistic函数(Logistic曲线)是什么?
Logistic函数或Logistic曲线是一个常见的S形曲线(sigmoid曲线),其方程如下,
在这里,
- L是曲线的最大值,
- x0是曲线中点的值,
- k是Logistic增长率或曲线的陡峭程度。
在C或C++编程语言中,Logistic函数可以写成如下,
const double L = 1;
const double k = 0.8;
const double x0 = 0;
double phi(double sum) {
return(L / (1 + std::exp(-k * (sum - x0)))); // Logistic函数或Logistic曲线
}
如果L、k和x0是常数,如上所述,它们可以直接包含在函数中,如下例所示(注意值可能有所不同)
double phi(double sum) {
return(1 / (1 + std::exp(-0.8 * (sum)))); // Logistic函数或Logistic曲线
}
标准Logistic函数(Sigmoid函数)是什么?
最常用的Logistic函数是标准Logistic函数(Sigmoid函数),其中L和k为1,x0=0。因此,我们的函数可以写成如下,
double phi(double sum) {
return(1 / (1 + std::exp(-1 * sum))); // 标准Logistic函数,Sigmoid函数
}
注意,这里的除法比乘法消耗更多的CPU,因此我们可以使用带有tanh()的版本,如下,
double phi(double sum) {
return(0.5 * (1 + std::tanh(0.5 * sum))); // 标准Logistic函数,Sigmoid函数
}
如你所见,我们这里只有乘法和加法以及tanh()函数。如果网络的sum值在范围内,例如在(0-10)之间,为了获得更快的近似结果,可以使用数组结果。可能有一个包含10000个成员的y数组,例如y[1001]可以持有phi(1.0001)的预计算值。这将使你的神经网络更快,但也可能引起更多错误或难以达到期望的迭代次数。它应该与上面的一个标准sigmoid函数版本一起测试。
Sigmoid函数(标准Logistic函数)的示例
#include <iostream>
#define NN 2 // 神经元数量
class Tneuron { // 神经元类
public:
bool a; // 每个神经元的活动
float w[NN+1]; // 神经元之间连接的权重
Tneuron() {
a = 0;
for (int i = 0; i <= NN; i++) w[i] = -1; // 如果权重是负数,则表示没有连接
}
// 定义输出神经元的激活函数(或阈值)
double phi(double sum) {
return(0.5 * (1 + std::tanh(0.5 * sum))); // 标准Logistic函数,Sigmoid函数
}
};
Tneuron ne[NN+1]; // 神经元对象
void fire(int nn) {
float sum = 0;
for (int j = 0; j <= NN; j++) {
if (ne[j].w[nn] >= 0) sum += ne[j].a * ne[j].w[nn];
}
ne[nn].a = ne[nn].phi(sum);
}
int main() {
// 定义两个输入神经元(a0, a1)和一个输出神经元(a2)的活动
ne[0].a = 0;
ne[1].a = 1;
ne[2].a = 0;
// 定义来自两个输入神经元到输出神经元(0到2和1到2)的信号权重
ne[0].w[2] = 0.3;
ne[1].w[2] = 0.2;
// 激发我们的人工神经元活动,输出将是
fire(2);
printf("%d\n", ne[2].a);
getchar();
return 0;
}
Logistic函数通常用于ANN应用中引入发展模型中的非线性,或者用于将信号限制在指定区间内。ANN元素计算其输入信号的线性组合,并应用有界的Logistic函数作为激活函数作为输出(激活值)。这可以被定义为经典阈值神经元的平滑版本。最常用的激活函数选择,用于将大振幅的信号剪辑以保持神经网络的响应有界。
这是Logistic函数。Wikipedia上有更多关于Logistic函数的信息。