Sigmoid 函数介绍
Sigmoid 函数(Logistic 函数)是神经网络中非常常用的激活函数,它的数学表示如下:
- 由于
e
x
e^x
ex
幂运算
是非常耗时
的计算,因此尝试通过替换
sigmoid中的 e x e^x ex运算,来提高运行效率,同时不影响计算精度。 - 同理
softmax
激活函数,也可以通过替换 e x e^x ex运算来提升运行速度。
Fast sigmoid 和sigmoid 对比
#include<iostream>
#include<ctime>
#include <cmath>
using namespace std;
const int N = 1e6;
inline float fast_exp(float x)
{
union
{
uint32_t i;
float f;
} v{};
v.i = (1 << 23) * (1.4426950409 * x + 126.93490512f);
return v.f;
}
inline float sigmoid_fast(float x)
{
return 1.0f / (1.0f + fast_exp(-x));
}
inline float sigmoid(float x)
{
return 1.0f / (1.0f + exp(-x));
}
int main(){
float a =sigmoid(1.5);
float b =sigmoid_fast(1.5);
printf("sigmoid result = %f\n", a);
printf("Fast sigmoid result= %f\n", b);
clock_t start_fast, end_fast,start, end;
start_fast= clock();
for(int i = 0 ; i < N ; i ++){
sigmoid_fast(10);
}
end_fast= clock();
// printf("End:sigmoid_fast= %ld\n",end_fast);
double elapsedTime = static_cast<double>(end_fast-start_fast) / CLOCKS_PER_SEC ;
//clock()以毫秒的形式展现,因此需要除以 CLOCKS_PER_SEC 来实现转换
//static_cast<double>的作用是将结果转换为double类型
printf("sigmoid_fast TIME: %f",elapsedTime);
start = clock();
//printf("\nStart: %ld\n",start);
for(int i = 0 ; i < N ; i ++){
sigmoid(10);
}
end = clock();
//printf("End:sigmoid= %ld\n",end);
elapsedTime = static_cast<double>(end-start) / CLOCKS_PER_SEC ;
//clock()以毫秒的形式展现,因此需要除以 CLOCKS_PER_SEC 来实现转换
//static_cast<double>的作用是将结果转换为double类型
printf("\nsigmoid TIME: %f",elapsedTime);
}
- 可以看到
sigmoid(1.5)
的计算结果为0.817554
,sigmoid_fast(1.5)
的计算结果为0.818761
, 计算结果非常接近。 - 而运行速度方面,在重复运行
1
0
6
10^6
106次,
sigmoid fast
耗时为0.002s
, 而sigmoid
耗时为0.038
, 计算速度方面Fast sigmoid比 sigmoid 快了19倍
- 同理
Fast Softmax
也可以通过替换 e x e^x ex运算,来提升计算效率