# 實現不同的層
了解如何實現不同的層非常重要。在前面的秘籍中,我們實現了完全連接的層。在本文中,我們將進一步擴展我們對各層的了解。
## 做好準備
我們已經探索了如何連接數據輸入和完全連接的隱藏層,但是 TensorFlow 中有更多類型的層是內置函數。最常用的層是卷積層和 maxpool 層。我們將向您展示如何使用輸入數據和完全連接的數據創建和使用此類層。首先,我們將研究如何在一維數據上使用這些層,然后在二維數據上使用這些層。
雖然神經網絡可以以任何方式分層,但最常見的用途之一是使用卷積層和完全連接的層來首先創建特征。如果我們有太多的特征,通常會有一個 maxpool 層。在這些層之后,通常引入非線性層作為激活函數。我們將在[第 8 章](../Text/61.html)卷積神經網絡中考慮的卷積神經網絡(CNN)通常具有卷積,maxpool,激活,卷積,maxpool 和激活形式。
## 操作步驟
我們將首先看一維數據。我們需要使用以下步驟為此任務生成隨機數據數組:
1. 我們首先加載我們需要的庫并開始圖會話,如下所示:
```py
import tensorflow as tf
import numpy as np
sess = tf.Session()
```
1. 現在我們可以初始化我們的數據(長度為`25`的 NumPy 數組)并創建占位符,我們將通過以下代碼提供它:
```py
data_size = 25
data_1d = np.random.normal(size=data_size)
x_input_1d = tf.placeholder(dtype=tf.float32, shape=[data_size])
```
1. 接下來,我們將定義一個將構成卷積層的函數。然后我們將聲明一個隨機過濾器并創建卷積層,如下所示:
> 請注意,許多 TensorFlow 的層函數都是為處理 4D 數據而設計的(`4D = [batch size, width, height, and channels]`)。我們需要修改輸入數據和輸出數據,以擴展或折疊所需的額外維度。對于我們的示例數據,我們的批量大小為 1,寬度為 1,高度為 25,通道大小為 1.要擴展尺寸,我們使用`expand_dims()`函數,并且為了折疊尺寸,我們使用`squeeze()`函數。另請注意,我們可以使用`output_size=(W-F+2P)/S+1`公式計算卷積層的輸出尺寸,其中`W`是輸入尺寸,`F`是濾鏡尺寸,`P`是填充尺寸,`S`是步幅大小。
```py
def conv_layer_1d(input_1d, my_filter):
# Make 1d input into 4d
input_2d = tf.expand_dims(input_1d, 0)
input_3d = tf.expand_dims(input_2d, 0)
input_4d = tf.expand_dims(input_3d, 3)
# Perform convolution
convolution_output = tf.nn.conv2d(input_4d, filter=my_filter, strides=[1,1,1,1], padding="VALID")
# Now drop extra dimensions
conv_output_1d = tf.squeeze(convolution_output)
return(conv_output_1d)
my_filter = tf.Variable(tf.random_normal(shape=[1,5,1,1]))
my_convolution_output = conv_layer_1d(x_input_1d, my_filter)
```
1. 默認情況下,TensorFlow 的激活函數將按元素方式執行。這意味著我們只需要在感興趣的層上調用激活函數。我們通過創建激活函數然后在圖上初始化它來完成此操作,如下所示:
```py
def activation(input_1d):
return tf.nn.relu(input_1d)
my_activation_output = activation(my_convolution_output)
```
1. 現在我們將聲明一個 maxpool 層函數。此函數將在我們的一維向量上的移動窗口上創建一個 maxpool。對于此示例,我們將其初始化為寬度為 5,如下所示:
> TensorFlow 的 maxpool 參數與卷積層的參數非常相似。雖然 maxpool 參數沒有過濾器,但它確實有 size,stride 和 padding 選項。由于我們有一個帶有有效填充的 5 的窗口(沒有零填充),因此我們的輸出數組將減少 4 個條目。
```py
def max_pool(input_1d, width):
# First we make the 1d input into 4d.
input_2d = tf.expand_dims(input_1d, 0)
input_3d = tf.expand_dims(input_2d, 0)
input_4d = tf.expand_dims(input_3d, 3)
# Perform the max pool operation
pool_output = tf.nn.max_pool(input_4d, ksize=[1, 1, width, 1], strides=[1, 1, 1, 1], padding='VALID')
pool_output_1d = tf.squeeze(pool_output)
return pool_output_1d
my_maxpool_output = max_pool(my_activation_output, width=5)
```
1. 我們將要連接的最后一層是完全連接的層。在這里,我們想要創建一個多特征函數,輸入一維數組并輸出指示的數值。還要記住,要使用 1D 數組進行矩陣乘法,我們必須將維度擴展為 2D,如下面的代碼塊所示:
```py
def fully_connected(input_layer, num_outputs):
# Create weights
weight_shape = tf.squeeze(tf.stack([tf.shape(input_layer), [num_outputs]]))
weight = tf.random_normal(weight_shape, stddev=0.1)
bias = tf.random_normal(shape=[num_outputs])
# Make input into 2d
input_layer_2d = tf.expand_dims(input_layer, 0)
# Perform fully connected operations
full_output = tf.add(tf.matmul(input_layer_2d, weight), bias)
# Drop extra dimensions
full_output_1d = tf.squeeze(full_output)
return full_output_1d
my_full_output = fully_connected(my_maxpool_output, 5)
```
1. 現在我們將初始化所有變量,運行圖并打印每個層的輸出,如下所示:
```py
init = tf.global_variable_initializer()
sess.run(init)
feed_dict = {x_input_1d: data_1d}
# Convolution Output
print('Input = array of length 25')
print('Convolution w/filter, length = 5, stride size = 1, results in an array of length 21:')
print(sess.run(my_convolution_output, feed_dict=feed_dict))
# Activation Output
print('Input = the above array of length 21')
print('ReLU element wise returns the array of length 21:')
print(sess.run(my_activation_output, feed_dict=feed_dict))
# Maxpool Output
print('Input = the above array of length 21')
print('MaxPool, window length = 5, stride size = 1, results in the array of length 17:')
print(sess.run(my_maxpool_output, feed_dict=feed_dict))
# Fully Connected Output
print('Input = the above array of length 17')
print('Fully connected layer on all four rows with five outputs:')
print(sess.run(my_full_output, feed_dict=feed_dict))
```
1. 上一步應該產生以下輸出:
```py
Input = array of length 25
Convolution w/filter, length = 5, stride size = 1, results in an array of length 21:
[-0.91608119 1.53731811 -0.7954089 0.5041104 1.88933098
-1.81099761 0.56695032 1.17945457 -0.66252393 -1.90287709
0.87184119 0.84611893 -5.25024986 -0.05473572 2.19293165
-4.47577858 -1.71364677 3.96857905 -2.0452652 -1.86647367
-0.12697852]
Input = the above array of length 21
ReLU element wise returns the array of length 21:
[ 0\. 1.53731811 0\. 0.5041104 1.88933098
0\. 0\. 1.17945457 0\. 0\.
0.87184119 0.84611893 0\. 0\. 2.19293165
0\. 0\. 3.96857905 0\. 0\.
0\. ]
Input = the above array of length 21
MaxPool, window length = 5, stride size = 1, results in the array of length 17:
[ 1.88933098 1.88933098 1.88933098 1.88933098 1.88933098
1.17945457 1.17945457 1.17945457 0.87184119 0.87184119
2.19293165 2.19293165 2.19293165 3.96857905 3.96857905
3.96857905 3.96857905]
Input = the above array of length 17
Fully connected layer on all four rows with five outputs:
[ 1.23588216 -0.42116445 1.44521213 1.40348077 -0.79607368]
```
> 對于神經網絡,一維數據非常重要。時間序列,信號處理和一些文本嵌入被認為是一維的并且經常在神經網絡中使用。
我們現在將以相同的順序考慮相同類型的層,但是對于二維數據:
1. 我們將從清除和重置計算圖開始,如下所示:
```py
ops.reset_default_graph()
sess = tf.Session()
```
1. 然后我們將初始化我們的輸入數組,使其為 10x10 矩陣,然后我們將為具有相同形狀的圖初始化占位符,如下所示:
```py
data_size = [10,10]
data_2d = np.random.normal(size=data_size)
x_input_2d = tf.placeholder(dtype=tf.float32, shape=data_size)
```
1. 就像在一維示例中一樣,我們現在需要聲明卷積層函數。由于我們的數據已經具有高度和寬度,我們只需要將其擴展為二維(批量大小為 1,通道大小為 1),以便我們可以使用`conv2d()`函數對其進行操作。對于濾波器,我們將使用隨機 2x2 濾波器,兩個方向的步幅為 2,以及有效填充(換句話說,沒有零填充)。因為我們的輸入矩陣是 10x10,我們的卷積輸出將是 5x5,如下所示:
```py
def conv_layer_2d(input_2d, my_filter):
# First, change 2d input to 4d
input_3d = tf.expand_dims(input_2d, 0)
input_4d = tf.expand_dims(input_3d, 3)
# Perform convolution
convolution_output = tf.nn.conv2d(input_4d, filter=my_filter, strides=[1,2,2,1], padding="VALID")
# Drop extra dimensions
conv_output_2d = tf.squeeze(convolution_output)
return(conv_output_2d)
my_filter = tf.Variable(tf.random_normal(shape=[2,2,1,1]))
my_convolution_output = conv_layer_2d(x_input_2d, my_filter)
```
1. 激活函數在逐個元素的基礎上工作,因此我們現在可以創建激活操作并使用以下代碼在圖上初始化它:
```py
def activation(input_2d):
return tf.nn.relu(input_2d)
my_activation_output = activation(my_convolution_output)
```
1. 我們的 maxpool 層與一維情況非常相似,只是我們必須聲明 maxpool 窗口的寬度和高度。就像我們的卷積 2D 層一樣,我們只需要擴展到兩個維度,如下所示:
```py
def max_pool(input_2d, width, height):
# Make 2d input into 4d
input_3d = tf.expand_dims(input_2d, 0)
input_4d = tf.expand_dims(input_3d, 3)
# Perform max pool
pool_output = tf.nn.max_pool(input_4d, ksize=[1, height, width, 1], strides=[1, 1, 1, 1], padding='VALID')
# Drop extra dimensions
pool_output_2d = tf.squeeze(pool_output)
return pool_output_2d
my_maxpool_output = max_pool(my_activation_output, width=2, height=2)
```
1. 我們的全連接層與一維輸出非常相似。我們還應該注意到,此層的 2D 輸入被視為一個對象,因此我們希望每個條目都連接到每個輸出。為了實現這一點,我們需要完全展平二維矩陣,然后將其展開以進行矩陣乘法,如下所示:
```py
def fully_connected(input_layer, num_outputs):
# Flatten into 1d
flat_input = tf.reshape(input_layer, [-1])
# Create weights
weight_shape = tf.squeeze(tf.stack([tf.shape(flat_input), [num_outputs]]))
weight = tf.random_normal(weight_shape, stddev=0.1)
bias = tf.random_normal(shape=[num_outputs])
# Change into 2d
input_2d = tf.expand_dims(flat_input, 0)
# Perform fully connected operations
full_output = tf.add(tf.matmul(input_2d, weight), bias)
# Drop extra dimensions
full_output_2d = tf.squeeze(full_output)
return full_output_2d
my_full_output = fully_connected(my_maxpool_output, 5)
```
1. 現在我們需要初始化變量并使用以下代碼為我們的操作創建一個 feed 字典:
```py
init = tf.global_variables_initializer()
sess.run(init)
feed_dict = {x_input_2d: data_2d}
```
1. 每個層的輸出應如下所示:
```py
# Convolution Output
print('Input = [10 X 10] array')
print('2x2 Convolution, stride size = [2x2], results in the [5x5] array:')
print(sess.run(my_convolution_output, feed_dict=feed_dict))
# Activation Output
print('Input = the above [5x5] array')
print('ReLU element wise returns the [5x5] array:')
print(sess.run(my_activation_output, feed_dict=feed_dict))
# Max Pool Output
print('Input = the above [5x5] array')
print('MaxPool, stride size = [1x1], results in the [4x4] array:')
print(sess.run(my_maxpool_output, feed_dict=feed_dict))
# Fully Connected Output
print('Input = the above [4x4] array')
print('Fully connected layer on all four rows with five outputs:')
print(sess.run(my_full_output, feed_dict=feed_dict))
```
1. 上一步應該產生以下輸出:
```py
Input = [10 X 10] array
2x2 Convolution, stride size = [2x2], results in the [5x5] array:
[[ 0.37630892 -1.41018617 -2.58821273 -0.32302785 1.18970704]
[-4.33685207 1.97415686 1.0844903 -1.18965471 0.84643292]
[ 5.23706436 2.46556497 -0.95119286 1.17715418 4.1117816 ]
[ 5.86972761 1.2213701 1.59536231 2.66231227 2.28650784]
[-0.88964868 -2.75502229 4.3449688 2.67776585 -2.23714781]]
Input = the above [5x5] array
ReLU element wise returns the [5x5] array:
[[ 0.37630892 0\. 0\. 0\. 1.18970704]
[ 0\. 1.97415686 1.0844903 0\. 0.84643292]
[ 5.23706436 2.46556497 0\. 1.17715418 4.1117816 ]
[ 5.86972761 1.2213701 1.59536231 2.66231227 2.28650784]
[ 0\. 0\. 4.3449688 2.67776585 0\. ]]
Input = the above [5x5] array
MaxPool, stride size = [1x1], results in the [4x4] array:
[[ 1.97415686 1.97415686 1.0844903 1.18970704]
[ 5.23706436 2.46556497 1.17715418 4.1117816 ]
[ 5.86972761 2.46556497 2.66231227 4.1117816 ]
[ 5.86972761 4.3449688 4.3449688 2.67776585]]
Input = the above [4x4] array
Fully connected layer on all four rows with five outputs:
[-0.6154139 -1.96987963 -1.88811922 0.20010889 0.32519674]
```
## 工作原理
我們現在應該知道如何在 TensorFlow 中使用一維和二維數據中的卷積和 maxpool 層。無論輸入的形狀如何,我們最終都得到相同的大小輸出。這對于說明神經網絡層的靈活性很重要。本節還應該再次向我們強調形狀和大小在神經網絡操作中的重要性。
- 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