深度学习中的S型激活函数:Python实现教程

这是文章《S型激活函数 – Python 实现》的第1部分(共5部分)。

在本教程中,我们将学习Sigmoid激活函数。Sigmoid函数始终返回介于0和1之间的输出。

在完成本教程后,你将会了解到:

  • 什么是激活函数?
  • 如何在Python中实现Sigmoid函数?
  • 如何在Python中绘制Sigmoid函数?
  • 我们在哪里使用Sigmoid函数?
  • Sigmoid激活函数会导致哪些问题?
  • Sigmoid激活函数的更好替代方案。

什么是激活函数?

激活函数是控制神经网络输出的数学函数。激活函数有助于确定神经元是否应该被激活。

一些常见的激活函数包括:

  • 二进制阶跃函数(Binary Step)
  • 线性函数(Linear)
  • Sigmoid函数
  • 双曲正切函数(Tanh)
  • ReLU函数
  • Leaky ReLU函数
  • Softmax函数

激活函数负责为神经网络模型的输出引入非线性。如果没有激活函数,神经网络只是一个线性回归模型。

神经网络输出的数学公式为:

Sigmoid Activation Function formula

在这个教程中,我们将专注于sigmoid激活函数。这个函数源自数学中的sigmoid函数。

让我们从讨论函数的公式开始。

Sigmoid激活函数的公式

数学上可以把Sigmoid激活函数表示为:

Formula

你可以看到分母总是大于1,因此输出将始终在0和1之间。

在Python中实现Sigmoid激活函数

第二部分:S型激活函数的Python实现

在这一部分中,我们将学习如何在Python中实现Sigmoid激活函数。

我们可以在Python中定义函数为:

import numpy as np 
def sig(x):
 return 1/(1 + np.exp(-x))

让我们尝试在一些输入上运行这个函数。

import numpy as np 
def sig(x):
 return 1/(1 + np.exp(-x))


x = 1.0
print('在(%.1f)上应用Sigmoid激活函数得到%.1f' % (x, sig(x)))

x = -10.0
print('在(%.1f)上应用Sigmoid激活函数得到%.1f' % (x, sig(x)))

x = 0.0
print('在(%.1f)上应用Sigmoid激活函数得到%.1f' % (x, sig(x)))

x = 15.0
print('在(%.1f)上应用Sigmoid激活函数得到%.1f' % (x, sig(x)))

x = -2.0
print('在(%.1f)上应用Sigmoid激活函数得到%.1f' % (x, sig(x)))

输出结果:

在(1.0)上应用Sigmoid激活函数得到0.7
在(-10.0)上应用Sigmoid激活函数得到0.0
在(0.0)上应用Sigmoid激活函数得到0.5
在(15.0)上应用Sigmoid激活函数得到1.0
在(-2.0)上应用Sigmoid激活函数得到0.1

使用Python绘制Sigmoid激活函数的图表

为了绘制S型激活函数,我们将使用Numpy库。

import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-10, 10, 50)   
p = sig(x)
plt.xlabel("x") 
plt.ylabel("Sigmoid(x)")  
plt.plot(x, p) 
plt.show()

输出结果

Sigmoid函数图像

从图像中我们可以看到,S型函数的输出值始终在0和1之间。

由于概率值始终在0和1之间,因此S型函数通常用于概率预测任务。

S型函数的一个缺点是在其末端区域(即输入值非常大或非常小的时候),Y值对X值的变化反应非常微弱。

这导致了一个被称为梯度消失问题的难题。

梯度消失会降低神经网络学习过程的速度,因此在深度学习模型中是不可取的。

接下来,让我们讨论一些能够克服这个问题的替代激活函数方案。

ReLU 激活函数

解决梯度消失问题的一个更好选择是使用ReLU(修正线性单元)激活函数。

如果输入为负数,则ReLU激活函数返回0;否则返回输入本身。

数学上,ReLU函数的表示方法为:

ReLU函数数学表达式

你可以用Python来实现,步骤如下:

def relu(x):
    return max(0.0, x)

让我们看看它在一些输入上的运行方式。

def relu(x):
    return max(0.0, x)
 
x = 1.0
print('对(%.1f)应用ReLU得到%.1f' % (x, relu(x)))
x = -10.0
print('对(%.1f)应用ReLU得到%.1f' % (x, relu(x)))
x = 0.0
print('对(%.1f)应用ReLU得到%.1f' % (x, relu(x)))
x = 15.0
print('对(%.1f)应用ReLU得到%.1f' % (x, relu(x)))
x = -20.0
print('对(%.1f)应用ReLU得到%.1f' % (x, relu(x)))

输出:

对(1.0)应用ReLU得到1.0
对(-10.0)应用ReLU得到0.0
对(0.0)应用ReLU得到0.0
对(15.0)应用ReLU得到15.0
对(-20.0)应用ReLU得到0.0

ReLU的问题在于负输入的梯度为零。

这再次引出了负输入的梯度消失(零梯度)的问题。

为了解决这个问题,我们还有另一种选择,被称为泄漏线性整流激活函数(Leaky ReLU)。

泄漏线性整流激活函数

通过给负数输入一个极小的线性成分,带有泄漏的ReLU解决了负数梯度为零的问题。

数学上我们可以将其定义为:

f(x) = 0.01x, x<0
    = x,    x>=0

你可以用Python实现它。

def leaky_relu(x):
  if x>0 :
    return x
  else :
    return 0.01*x
  
x = 1.0
print('对(%.1f)应用Leaky ReLU得到%.1f' % (x, leaky_relu(x)))

x = -10.0
print('对(%.1f)应用Leaky ReLU得到%.1f' % (x, leaky_relu(x)))

x = 0.0
print('对(%.1f)应用Leaky ReLU得到%.1f' % (x, leaky_relu(x)))

x = 15.0
print('对(%.1f)应用Leaky ReLU得到%.1f' % (x, leaky_relu(x)))

x = -20.0
print('对(%.1f)应用Leaky ReLU得到%.1f' % (x, leaky_relu(x)))

输出结果:

对(1.0)应用Leaky ReLU得到1.0
对(-10.0)应用Leaky ReLU得到-0.1
对(0.0)应用Leaky ReLU得到0.0
对(15.0)应用Leaky ReLU得到15.0
对(-20.0)应用Leaky ReLU得到-0.2

结论

这个教程是关于Leaky ReLU激活函数的。我们学习了如何在Python中实现和应用该函数。

bannerAds