TensorFlow 1.x 版本中提供了多种内置的激活函数,这些函数广泛用于神经网络模型中以引入非线性特性。以下是 TensorFlow 1.x 中常用激活函数及其使用方法:
### 常用激活函数列表及使用方法
#### 1. `tf.nn.relu`
`tf.nn.relu(x)` 是 Rectified Linear Unit(ReLU)函数,定义为 `f(x) = max(0, x)`,它在深度学习中被广泛使用。
```python
import tensorflow as tf
x = tf.constant([-2.0, -1.0, 0.0, 1.0, 2.0])
result = tf.nn.relu(x)
with tf.Session() as sess:
print(sess.run(result)) # 输出 [0. 0. 0. 1. 2.]
```
#### 2. `tf.nn.sigmoid`
`tf.nn.sigmoid(x)` 是 Sigmoid 函数,定义为 `f(x) = 1 / (1 + exp(-x))`,常用于二分类问题的输出层。
```python
x = tf.constant([-2.0, -1.0, 0.0, 1.0, 2.0])
result = tf.nn.sigmoid(x)
with tf.Session() as sess:
print(sess.run(result)) # 输出 [0.11920292 0.26894143 0.5 0.7310586 0.88079708]
```
#### 3. `tf.nn.tanh`
`tf.nn.tanh(x)` 是双曲正切函数,定义为 `f(x) = tanh(x)`,其输出范围为 [-1, 1]。
```python
x = tf.constant([-2.0, -1.0, 0.0, 1.0, 2.0])
result = tf.nn.tanh(x)
with tf.Session() as sess:
print(sess.run(result)) # 输出 [-0.9640276 -0.7615942 0. 0.7615942 0.9640276]
```
#### 4. `tf.nn.elu`
`tf.nn.elu(x)` 是 Exponential Linear Unit 函数,定义为:
- `f(x) = x` if `x > 0`
- `f(x) = alpha * (exp(x) - 1)` if `x <= 0`
```python
x = tf.constant([-2.0, -1.0, 0.0, 1.0, 2.0])
result = tf.nn.elu(x)
with tf.Session() as sess:
print(sess.run(result)) # 输出 [-1.2642411 -0.63212055 0. 1. 2. ]
```
#### 5. `tf.nn.crelu`
`tf.nn.crelu(x)` 是 Concatenated ReLU 函数,它同时返回 `relu(x)` 和 `relu(-x)`,输出维度是输入的两倍。
```python
x = tf.constant([-2.0, -1.0, 0.0, 1.0, 2.0])
result = tf.nn.crelu(x)
with tf.Session() as sess:
print(sess.run(result)) # 输出 [0. 0. 0. 1. 2. 2. 1. 0. 0. 0.]
```
#### 6. `tf.nn.relu6`
`tf.nn.relu6(x)` 是 ReLU6 函数,定义为 `f(x) = min(max(0, x), 6)`,适用于移动端模型。
```python
x = tf.constant([-2.0, -1.0, 0.0, 1.0, 6.0, 7.0])
result = tf.nn.relu6(x)
with tf.Session() as sess:
print(sess.run(result)) # 输出 [0. 0. 0. 1. 6. 6.]
```
#### 7. `tf.nn.softplus`
`tf.nn.softplus(x)` 是 Softplus 函数,定义为 `f(x) = log(1 + exp(x))`,是 ReLU 的平滑近似。
```python
x = tf.constant([-2.0, -1.0, 0.0, 1.0, 2.0])
result = tf.nn.softplus(x)
with tf.Session() as sess:
print(sess.run(result)) # 输出 [0.12692801 0.31326166 0.6931472 1.3132616 2.126928 ]
```
#### 8. `tf.nn.dropout`
`tf.nn.dropout(x, keep_prob)` 是 Dropout 函数,用于在训练过程中随机丢弃神经元,防止过拟合。
```python
x = tf.constant([[1.0, 2.0], [3.0, 4.0]])
result = tf.nn.dropout(x, keep_prob=0.5)
with tf.Session() as sess:
print(sess.run(result)) # 输出可能为 [[2. 0.], [0. 8.]]
```
#### 9. `tf.nn.bias_add`
`tf.nn.bias_add(value, bias)` 用于将偏置项加到张量上。
```python
value = tf.constant([[1.0, 2.0], [3.0, 4.0]])
bias = tf.constant([0.5, 1.0])
result = tf.nn.bias_add(value, bias)
with tf.Session() as sess:
print(sess.run(result)) # 输出 [[1.5 3. ] [3.5 5. ]]
```
#### 10. `tf.nn.softsign`
`tf.nn.softsign(x)` 是 Softsign 函数,定义为 `f(x) = x / (abs(x) + 1)`。
```python
x = tf.constant([-2.0, -1.0, 0.0, 1.0, 2.0])
result = tf.nn.softsign(x)
with tf.Session() as sess:
print(sess.run(result)) # 输出 [-0.6666667 -0.5 0. 0.5 0.6666667]
```
#### 11. `tf.keras.activations.linear`
`linear(x)` 是线性激活函数,直接返回输入值,常用于回归问题的输出层。
```python
x = tf.constant([-2.0, -1.0, 0.0, 1.0, 2.0])
result = tf.keras.activations.linear(x)
with tf.Session() as sess:
print(sess.run(result)) # 输出 [-2. -1. 0. 1. 2.]
```
### 可视化激活函数
以下代码可用于绘制激活函数的图像,以 `sigmoid` 为例:
```python
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-10, 10, 0.01)
xt = tf.convert_to_tensor(x)
sess = tf.Session()
y = sess.run(tf.sigmoid(xt))
ax = plt.gca()
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))
plt.plot(x, y)
plt.title('Sigmoid Function')
plt.xlabel('x')
plt.ylabel('Sigmoid(x)')
plt.grid(True)
plt.show()
```
### 优缺点分析
- **ReLU** 优点是计算效率高,但存在“死亡 ReLU”问题(某些神经元不再激活)。
- **Sigmoid** 优点是输出范围 [0, 1],适合二分类问题,但容易导致梯度消失。
- **Tanh** 输出范围 [-1, 1],比 Sigmoid 更适合中心化数据,但同样存在梯度消失问题。
- **ELU** 解决了 ReLU 的负值问题,但在计算上稍复杂。
- **Dropout** 有助于防止过拟合,但会增加训练时间。
通过选择合适的激活函数,可以显著提升神经网络模型的性能和收敛速度。[^1]
---