跳至内容

拾光小记

深度学习-激活函数

我们可以对上文感知机中的函数 $$y=\begin{cases}0 (x1w1 + x2w2 + b \le 0 )\ 1 (x1w1 + x2w2 + b > 0)\end{cases}$$ 做如下调整。将每次计算结果定义为a $$a=x1w1 + x2w2 + b$$ 然后定义函数$$h(a)$$ $$ h(a) = \begin{cases}0 (a \le 0 )\ 1 (xa> 0)\end{cases}$$ 将$$h(a)$$定义为更加通用的形式 $$h(x) = \begin{cases}0 (x \le 0 )\ 1 (x > 0)\end{cases}$$ 那么$$h(x)$$即为感知机的激活函数。

# 激活函数的作用

激活函数的作用是将感知机的输出值转换为更加有用的形式。在感知机中,激活函数的作用是将感知机的输出值转换为0或1。在神经网络中,激活函数的作用是将神经网络的输出值转换为更加有用的形式。

# 常用的激活函数

## 阶跃函数

上面讲到的激活函数以阈值为界,一旦输入超过阈值,就切换输出。 这样的函数称为“阶跃函数”。因此,可以说感知机中使用了阶跃函数作为 激活函数。也就是说,在激活函数的众多候选函数中,感知机使用了阶跃函数。

### 阶跃函数的实现和图示

# 阶跃函数
import numpy as np 
import matplotlib.pylab as plt

def step_function(x):
    return np.array(x > 0, dtype=int)

x = np.arange(-5.0, 5.0, 0.1)
y = step_function(x) 
plt.plot(x, y) 
plt.ylim(-0.1, 1.1) # 指定y轴的范围 
plt.show()

## sigmoid函数

sigmoid函数是神经网络中最常用的激活函数之一。sigmoid函数的定义如下: $$\sigma(x) = \frac{1}{1 + e^{-x}}$$

### sigmoid函数的实现和图示

import numpy as np 
import matplotlib.pylab as plt

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

x = np.arange(-5.0, 5.0, 0.1)
y = sigmoid(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1) # 指定y轴的范围
plt.show()

### 阶跃函数和sigmoid函数的比较

阶跃函数和sigmoid函数都是非线性函数。但是,阶跃函数是一个“阶跃函数”,输出值只能是0或1。而sigmoid函数的输出值是连续的,可以取任意值。这是因为sigmoid函数的导数是一个连续函数,因此可以用梯度法来学习神经网络的权重参数。而阶跃函数的导数是一个不连续的函数,因此不能用梯度法来学习神经网络的权重参数。但是,两个函数的趋势是相似的,都是输入信号比较小时,输出值接近0,输入信号比较大时,输出值接近1。因此,sigmoid函数也可以用来代替阶跃函数。 我们将两个函数的输出值绘制在同一张图中,可以看到两个函数的趋势是相似的。

import numpy as np 
import matplotlib.pylab as plt

# 阶跃函数
def step_function(x):
    return np.array(x > 0, dtype=int)

# sigmoid函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

x = np.arange(-5.0, 5.0, 0.1)
y = sigmoid(x)

y1 = step_function(x)
plt.plot(x, y)
plt.plot(x, y1)
plt.ylim(-0.1, 1.1) # 指定y轴的范围
plt.show()

## ReLU函数

ReLU函数是神经网络中最常用的激活函数之一。ReLU函数的定义如下: $$h(x) = \begin{cases}x (x > 0 )\ 0 (x \le 0)\end{cases}$$ 相较于sigmoid函数,ReLU函数的计算速度更快。因为ReLU函数只需要判断输入是否大于0即可,而sigmoid函数需要进行指数运算。因此,ReLU函数在神经网络中被广泛使用。

### ReLU函数的实现和图示

import numpy as np
import matplotlib.pylab as plt

def relu(x):
    return np.maximum(0, x)

x = np.arange(-5.0, 5.0, 0.1)
y = relu(x)
plt.plot(x, y)
plt.ylim(-0.1, 5.1) # 指定y轴的范围
plt.show()

在神经网络中,激活函数都是非线性的。这是因为,如果激活函数是线性的,那么神经网络就是多层的线性函数,无论神经网络有多少层,输出都是输入的线性组合。因此,激活函数必须是非线性的函数。比如,激活函数为$$h(x) = ax$$,那么传递到第3层时的激活函数是$$y(x) = h(h(h(x))) = a^3x$$,无论神经网络有多少层,输出都是输入的线性组合。这样,神经网络的层级就没有意义了。因此,激活函数必须是非线性的函数。

## 激活函数的选择

激活函数的选择是神经网络的重要的设计问题。在神经网络中,激活函数一般使用ReLU函数。但是,如果输出层是二元分类问题,那么输出层的激活函数一般使用sigmoid函数。如果输出层是多元分类问题,那么输出层的激活函数一般使用softmax函数。