# 使用門和激活函數
現在我們可以將操作門連接在一起,我們希望通過激活函數運行計算圖輸出。在本節中,我們將介紹常見的激活函數。
## 做好準備
在本節中,我們將比較和對比兩種不同的激活函數:S 形和整流線性單元(ReLU)。回想一下,這兩個函數由以下公式給出:


在這個例子中,我們將創建兩個具有相同結構的單層神經網絡,除了一個將通過 sigmoid 激活并且一個將通過 ReLU 激活。損失函數將由距離值 0.75 的 L2 距離控制。我們將從正態分布`(Normal(mean=2, sd=0.1))` 中隨機抽取批量數據,然后將輸出優化為 0.75。
## 操作步驟
我們按如下方式處理秘籍:
1. 我們將首先加載必要的庫并初始化圖。這也是我們可以提出如何使用 TensorFlow 設置隨機種子的好點。由于我們將使用 NumPy 和 TensorFlow 中的隨機數生成器,因此我們需要為兩者設置隨機種子。使用相同的隨機種子集,我們應該能夠復制結果。我們通過以下輸入執行此操作:
```py
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
sess = tf.Session()
tf.set_random_seed(5)
np.random.seed(42)
```
1. 現在我們需要聲明我們的批量大小,模型變量,數據和占位符來輸入數據。我們的計算圖將包括將我們的正態分布數據輸入到兩個相似的神經網絡中,這兩個神經網絡的區別僅在于激活函數。結束,如下所示:
```py
batch_size = 50
a1 = tf.Variable(tf.random_normal(shape=[1,1]))
b1 = tf.Variable(tf.random_uniform(shape=[1,1]))
a2 = tf.Variable(tf.random_normal(shape=[1,1]))
b2 = tf.Variable(tf.random_uniform(shape=[1,1]))
x = np.random.normal(2, 0.1, 500)
x_data = tf.placeholder(shape=[None, 1], dtype=tf.float32)
```
1. 接下來,我們將聲明我們的兩個模型,即 sigmoid 激活模型和 ReLU 激活模型,如下所示:
```py
sigmoid_activation = tf.sigmoid(tf.add(tf.matmul(x_data, a1), b1))
relu_activation = tf.nn.relu(tf.add(tf.matmul(x_data, a2), b2))
```
1. 損失函數將是模型輸出與值 0.75 之間的平均 L2 范數,如下所示:
```py
loss1 = tf.reduce_mean(tf.square(tf.subtract(sigmoid_activation, 0.75)))
loss2 = tf.reduce_mean(tf.square(tf.subtract(relu_activation, 0.75)))
```
1. 現在我們需要聲明我們的優化算法并初始化我們的變量,如下所示:
```py
my_opt = tf.train.GradientDescentOptimizer(0.01)
train_step_sigmoid = my_opt.minimize(loss1)
train_step_relu = my_opt.minimize(loss2)
init = tf.global_variable_initializer()
sess.run(init)
```
1. 現在,我們將針對兩個模型循環我們的 750 次迭代訓練,如下面的代碼塊所示。我們還將保存損失輸出和激活輸出值,以便稍后進行繪圖:
```py
loss_vec_sigmoid = []
loss_vec_relu = []
activation_sigmoid = []
activation_relu = []
for i in range(750):
rand_indices = np.random.choice(len(x), size=batch_size)
x_vals = np.transpose([x[rand_indices]])
sess.run(train_step_sigmoid, feed_dict={x_data: x_vals})
sess.run(train_step_relu, feed_dict={x_data: x_vals})
loss_vec_sigmoid.append(sess.run(loss1, feed_dict={x_data: x_vals}))
loss_vec_relu.append(sess.run(loss2, feed_dict={x_data: x_vals}))
activation_sigmoid.append(np.mean(sess.run(sigmoid_activation, feed_dict={x_data: x_vals})))
activation_relu.append(np.mean(sess.run(relu_activation, feed_dict={x_data: x_vals})))
```
1. 要繪制損失和激活輸出,我們需要輸入以下代碼:
```py
plt.plot(activation_sigmoid, 'k-', label='Sigmoid Activation')
plt.plot(activation_relu, 'r--', label='Relu Activation')
plt.ylim([0, 1.0])
plt.title('Activation Outputs')
plt.xlabel('Generation')
plt.ylabel('Outputs')
plt.legend(loc='upper right')
plt.show()
plt.plot(loss_vec_sigmoid, 'k-', label='Sigmoid Loss')
plt.plot(loss_vec_relu, 'r--', label='Relu Loss')
plt.ylim([0, 1.0])
plt.title('Loss per Generation')
plt.xlabel('Generation')
plt.ylabel('Loss')
plt.legend(loc='upper right')
plt.show()
```
激活輸出需要繪制,如下圖所示:

圖 2:來自具有 S 形激活的網絡和具有 ReLU 激活的網絡的計算圖輸出
兩個神經網絡使用類似的架構和目標(0.75),但有兩個不同的激活函數,sigmoid 和 ReLU。重要的是要注意 ReLU 激活網絡收斂到比 sigmoid 激活所需的 0.75 目標更快,如下圖所示:

圖 3:該圖描繪了 S 形和 ReLU 激活網絡的損耗值。注意迭代開始時 ReLU 損失的極端程度
## 工作原理
由于 ReLU 激活函數的形式,它比 sigmoid 函數更頻繁地返回零值。我們認為這種行為是一種稀疏性。這種稀疏性導致收斂速度加快,但失去了受控梯度。另一方面,S 形函數具有非常良好控制的梯度,并且不會冒 ReLU 激活所帶來的極值的風險,如下圖所示:
| 激活函數 | 好處 | 缺點 |
| --- | --- | --- |
| Sigmoid | 不太極端的產出 | 收斂速度較慢 |
| RELU | 更快地融合 | 極端輸出值可能 |
## 更多
在本節中,我們比較了神經網絡的 ReLU 激活函數和 S 形激活函數。還有許多其他激活函數通常用于神經網絡,但大多數屬于兩個類別之一;第一類包含形狀類似于 sigmoid 函數的函數,如 arctan,hypertangent,heavyiside step 等;第二類包含形狀的函數,例如 ReLU 函數,例如 softplus,leaky ReLU 等。我們在本節中討論的關于比較這兩個函數的大多數內容都適用于任何類別的激活。然而,重要的是要注意激活函數的選擇對神經網絡的收斂和輸出有很大影響。
- TensorFlow 入門
- 介紹
- TensorFlow 如何工作
- 聲明變量和張量
- 使用占位符和變量
- 使用矩陣
- 聲明操作符
- 實現激活函數
- 使用數據源
- 其他資源
- TensorFlow 的方式
- 介紹
- 計算圖中的操作
- 對嵌套操作分層
- 使用多個層
- 實現損失函數
- 實現反向傳播
- 使用批量和隨機訓練
- 把所有東西結合在一起
- 評估模型
- 線性回歸
- 介紹
- 使用矩陣逆方法
- 實現分解方法
- 學習 TensorFlow 線性回歸方法
- 理解線性回歸中的損失函數
- 實現 deming 回歸
- 實現套索和嶺回歸
- 實現彈性網絡回歸
- 實現邏輯回歸
- 支持向量機
- 介紹
- 使用線性 SVM
- 簡化為線性回歸
- 在 TensorFlow 中使用內核
- 實現非線性 SVM
- 實現多類 SVM
- 最近鄰方法
- 介紹
- 使用最近鄰
- 使用基于文本的距離
- 使用混合距離函數的計算
- 使用地址匹配的示例
- 使用最近鄰進行圖像識別
- 神經網絡
- 介紹
- 實現操作門
- 使用門和激活函數
- 實現單層神經網絡
- 實現不同的層
- 使用多層神經網絡
- 改進線性模型的預測
- 學習玩井字棋
- 自然語言處理
- 介紹
- 使用詞袋嵌入
- 實現 TF-IDF
- 使用 Skip-Gram 嵌入
- 使用 CBOW 嵌入
- 使用 word2vec 進行預測
- 使用 doc2vec 進行情緒分析
- 卷積神經網絡
- 介紹
- 實現簡單的 CNN
- 實現先進的 CNN
- 重新訓練現有的 CNN 模型
- 應用 StyleNet 和 NeuralStyle 項目
- 實現 DeepDream
- 循環神經網絡
- 介紹
- 為垃圾郵件預測實現 RNN
- 實現 LSTM 模型
- 堆疊多個 LSTM 層
- 創建序列到序列模型
- 訓練 Siamese RNN 相似性度量
- 將 TensorFlow 投入生產
- 介紹
- 實現單元測試
- 使用多個執行程序
- 并行化 TensorFlow
- 將 TensorFlow 投入生產
- 生產環境 TensorFlow 的一個例子
- 使用 TensorFlow 服務
- 更多 TensorFlow
- 介紹
- 可視化 TensorBoard 中的圖
- 使用遺傳算法
- 使用 k 均值聚類
- 求解常微分方程組
- 使用隨機森林
- 使用 TensorFlow 和 Keras