ps:在 TensorFlow Keras 中,構建 Sequential 模型的正確方式是將層作為列表傳遞,而不是作為一系列單獨的參數。
model=models.Sequential([layers,layers])
而不是model=models.Sequential(layers,layers)
文章目錄
- 卷積操作及其計算過程的詳細解釋
- 卷積的基本操作
- 1. 卷積核(Convolution Kernel)
- 卷積核如何提取特征
- 2. 卷積過程
- 卷積的數學表示
- 簡單例子
- 輸出尺寸的計算
- 3.卷積矩陣在深度訓練中的改變過程
- 卷積核的調整過程
- 1. 初始化
- 2. 前向傳播
- 3. 反向傳播和卷積核的更新
- 4. 迭代過程
- 卷積核的角色
- 并行卷積結構和深度可分離卷積的詳細數學解釋
- 并行卷積結構:Inception 模塊
- 概念
- 數學表示
- 簡單例子
- 輸出尺寸的計算
- 為什么不同的卷積大小產生相同的尺寸輸出
- 代碼
卷積操作及其計算過程的詳細解釋
卷積是深度學習中用于圖像和信號處理的一種基本數學操作。它通過應用卷積核(或過濾器)到輸入數據上,來提取重要特征。
卷積的基本操作
1. 卷積核(Convolution Kernel)
- 卷積核是一個小的矩陣(通常是2D),用于通過濾過輸入數據來提取特定特征。
卷積核如何提取特征
-
邊緣檢測:例如,卷積核 K = [ ? 1 0 1 ? 1 0 1 ? 1 0 1 ] K = \begin{bmatrix}-1 & 0 & 1 \\ -1 & 0 & 1 \\ -1 & 0 & 1\end{bmatrix} K= ??1?1?1?000?111? ? 被用于邊緣檢測。這個特定的卷積核可以突出水平方向的邊緣。它通過計算左側像素與右側像素的差異來工作,這種差異在邊緣處最大。
-
紋理和模式識別:不同的卷積核可以識別不同的紋理和模式。例如,對于識別特定方向的紋理,卷積核會有特定的方向性。
在實際應用中,通常不是手動設計這些卷積核,而是通過訓練過程讓神經網絡自行學習最優的卷積核,以適應特定的任務和數據。
2. 卷積過程
- 將卷積核放在輸入數據的左上角。
- 將卷積核的每個元素與其覆蓋的輸入數據元素相乘,然后將結果求和,得到輸出特征圖的一個元素。
- 將卷積核向右滑動一個步長(Stride),重復上述過程,直到覆蓋整個輸入數據。
卷積的數學表示
卷積操作可以表示為:
S ( i , j ) = ( I ? K ) ( i , j ) = ∑ m ∑ n I ( m , n ) K ( i ? m , j ? n ) S(i, j) = (I \ast K)(i, j) = \sum_m \sum_n I(m, n) K(i-m, j-n) S(i,j)=(I?K)(i,j)=m∑?n∑?I(m,n)K(i?m,j?n)
其中, I I I 是輸入圖像, K K K 是卷積核, S S S 是輸出特征圖, i i i 和 j j j 表示特征圖上的位置。
-
以一個 3 × 3 3 \times 3 3×3 的卷積核為例,應用于一個二維輸入數據(如圖像):
S ( i , j ) = ∑ m = 0 2 ∑ n = 0 2 I ( i + m , j + n ) K ( m , n ) S(i, j) = \sum_{m=0}^{2} \sum_{n=0}^{2} I(i+m, j+n) K(m, n) S(i,j)=m=0∑2?n=0∑2?I(i+m,j+n)K(m,n)
其中 I I I 是輸入數據, K K K 是卷積核, S S S 是輸出特征圖, i i i 和 j j j 是特征圖上的位置。
簡單例子
假設輸入數據是一個 4 × 4 4 \times 4 4×4 的矩陣,卷積核是一個 3 × 3 3 \times 3 3×3 的矩陣,如下所示:
輸入數據 I
:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
卷積核 K
:
-1 0 1
-1 0 1
-1 0 1
- 將卷積核放在輸入數據的左上角,計算卷積(不考慮步長和填充):
S(0, 0) = (1*-1 + 20 + 31) + (5*-1 + 60 + 71) + (9*-1 + 100 + 111)
= -1 + 0 + 3 - 5 + 0 + 7 - 9 + 0 + 11
= 7
- 將卷積核向右滑動一個步長,并重復計算。
輸出尺寸的計算
輸出尺寸取決于輸入尺寸、卷積核尺寸、步長和填充:
Output?Size = Input?Size ? Filter?Size + 2 × Padding Stride + 1 \text{Output Size} = \frac{\text{Input Size} - \text{Filter Size} + 2 \times \text{Padding}}{\text{Stride}} + 1 Output?Size=StrideInput?Size?Filter?Size+2×Padding?+1
在不使用填充且步長為1的情況下,上述例子中的輸出尺寸將是 2 × 2 2 \times 2 2×2。
3.卷積矩陣在深度訓練中的改變過程
在深度學習中,卷積矩陣(或稱為卷積核、過濾器)是通過訓練過程逐漸調整以優化特征提取的。這個調整過程是通過反向傳播算法和梯度下降方法實現的。
卷積核的調整過程
1. 初始化
- 初始化:開始訓練時,卷積核的權重通常被初始化為隨機小數值。
2. 前向傳播
- 提取特征:在訓練過程中,卷積核在前向傳播階段通過卷積操作提取輸入數據的特征。
前向傳播是數據通過神經網絡的過程,其中的每一步如下:- 數據輸入:原始數據輸入網絡。
- 卷積操作:數據通過卷積層,卷積核應用于數據。
- 激活函數:卷積的結果通過激活函數,如ReLU。
- 池化:可選步驟,應用池化(如最大池化)降低維度。
- 輸出生成:通過全連接層生成最終輸出。
3. 反向傳播和卷積核的更新
卷積核的更新發生在反向傳播過程中,該過程如下:
- 損失計算:計算預測輸出和實際輸出之間的差異(損失)。
-
損失函數衡量模型預測與實際標簽之間的差距。常用的損失函數包括均方誤差(MSE)和交叉熵損失。
-
假設有實際值 y y y 和預測值 y ^ \hat{y} y^?,MSE 計算公式為:
MSE = 1 n ∑ i = 1 n ( y i ? y ^ i ) 2 \text{MSE} = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 MSE=n1?i=1∑n?(yi??y^?i?)2
其中 n n n 是樣本數量。
- 梯度計算:通過反向傳播算法計算損失函數相對于卷積核權重的梯度。
-
對于每個權重 W W W,損失函數的梯度計算為:
? Loss ? W = ? Loss ? y ^ × ? y ^ ? W \frac{\partial \text{Loss}}{\partial W} = \frac{\partial \text{Loss}}{\partial \hat{y}} \times \frac{\partial \hat{y}}{\partial W} ?W?Loss?=?y^??Loss?×?W?y^??
- 權重更新:根據梯度和學習率更新卷積核的權重。更新公式為:
W new = W old ? η × ? Loss ? W W_{\text{new}} = W_{\text{old}} - \eta \times \frac{\partial \text{Loss}}{\partial W} Wnew?=Wold??η×?W?Loss?
其中 W W W 是卷積核權重, η \eta η 是學習率, ? Loss ? W \frac{\partial \text{Loss}}{\partial W} ?W?Loss? 是損失函數相對于 W W W 的梯度。
示例:單層神經網絡
-
假設有一個單層網絡,輸出 y ^ = W x + b \hat{y} = Wx + b y^?=Wx+b,損失函數是 MSE。
-
損失對 W W W 的梯度為:
? Loss ? W = 2 n ∑ ( y ? y ^ ) × ( ? x ) \frac{\partial \text{Loss}}{\partial W} = \frac{2}{n} \sum (y - \hat{y}) \times (-x) ?W?Loss?=n2?∑(y?y^?)×(?x)
-
在反向傳播中,這個梯度用于更新 W W W。
4. 迭代過程
- 重復迭代:這個過程在多個訓練周期(epoch)中重復進行,直到模型性能達到預定的標準或者停止改進。
卷積核的角色
- 在訓練過程中,卷積核逐漸學習到如何有效地提取輸入數據的關鍵特征,這些特征對于完成特定的深度學習任務(如圖像分類、物體檢測等)至關重要。
并行卷積結構和深度可分離卷積的詳細數學解釋
并行卷積結構:Inception 模塊
概念
- Inception 模塊是一種在同一網絡層上并行應用多種不同尺寸卷積核的結構。
- 它允許網絡在單一層級上捕獲多尺度特征。
數學表示
假設輸入特征圖為 X X X,Inception 模塊中的不同分支可以表示如下:
-
1 × 1 1 \times 1 1×1 卷積分支:
Y 1 = Conv 1 × 1 ( X ) Y_1 = \text{Conv}_{1 \times 1}(X) Y1?=Conv1×1?(X)
這里, Conv 1 × 1 \text{Conv}_{1 \times 1} Conv1×1? 表示 1 × 1 1 \times 1 1×1 卷積,用于捕獲局部特征。 -
3 × 3 3 \times 3 3×3 卷積分支:
Y 2 = Conv 3 × 3 ( X ) Y_2 = \text{Conv}_{3 \times 3}(X) Y2?=Conv3×3?(X)
3 × 3 3 \times 3 3×3 卷積能捕獲更廣泛的空間特征。 -
5 × 5 5 \times 5 5×5 卷積分支:
Y 3 = Conv 5 × 5 ( X ) Y_3 = \text{Conv}_{5 \times 5}(X) Y3?=Conv5×5?(X)
5 × 5 5 \times 5 5×5 卷積提供了更大范圍的感受野。
這些分支的輸出被沿深度方向合并,生成綜合特征映射 Y Y Y:
Y = [ Y 1 , Y 2 , Y 3 ] Y = [Y_1, Y_2, Y_3] Y=[Y1?,Y2?,Y3?]
簡單例子
考慮一個 224 × 224 × 3 224 \times 224 \times 3 224×224×3 的圖像作為輸入 X X X。Inception 模塊中的 1 × 1 1 \times 1 1×1 卷積可能產生 224 × 224 × 64 224 \times 224 \times 64 224×224×64 的輸出 Y 1 Y_1 Y1?, 3 × 3 3 \times 3 3×3 卷積產生相同尺寸的輸出 Y 2 Y_2 Y2?,而 5 × 5 5 \times 5 5×5 卷積也產生相同尺寸的輸出 Y 3 Y_3 Y3?。合并這些輸出,我們得到一個 224 × 224 × 192 224 \times 224 \times 192 224×224×192 的特征映射 Y Y Y。
輸出尺寸的計算
輸出特征圖的尺寸取決于幾個因素:
- 輸入尺寸:輸入圖像的尺寸。
- 卷積核尺寸:卷積核的大小。
- 步長(Stride):卷積核在輸入上滑動的步長。
- 填充(Padding):在輸入周圍添加的零的層數。
輸出尺寸的計算公式為:
Output?Size = Input?Size ? Filter?Size + 2 × Padding Stride + 1 \text{Output Size} = \frac{\text{Input Size} - \text{Filter Size} + 2 \times \text{Padding}}{\text{Stride}} + 1 Output?Size=StrideInput?Size?Filter?Size+2×Padding?+1
為什么不同的卷積大小產生相同的尺寸輸出
在前面的例子中, 1 × 1 1 \times 1 1×1, 3 × 3 3 \times 3 3×3 和 5 × 5 5 \times 5 5×5 的卷積產生了相同尺寸的輸出,這是因為:
-
步長和填充的調整:通過調整步長和填充,可以使不同大小的卷積核產生相同尺寸的輸出。通常,較大的卷積核會使用更多的填充來保持輸出尺寸不變。
-
保持特征圖空間分辨率:這種做法使得并行的卷積分支可以在深度方向上直接合并,因為它們具有相同的空間維度。
所以假設輸入尺寸為 224 × 224 224 \times 224 224×224,卷積核尺寸分別為 1 × 1 1 \times 1 1×1, 3 × 3 3 \times 3 3×3 和 5 × 5 5 \times 5 5×5,步長為 1,并且對于 3 × 3 3 \times 3 3×3 和 5 × 5 5 \times 5 5×5 卷積使用適當的填充(分別為 1 和 2)來保持輸出尺寸不變。根據上述公式,所有這些卷積操作將產生 224 × 224 224 \times 224 224×224 的輸出特征圖。
代碼
import tensorflow as tf
from tensorflow.keras.layers import Input, Conv2D, Concatenate
from tensorflow.keras.models import Model# 定義一個函數來創建并行卷積層
def parallel_convolution(input_tensor):# 1x1 卷積conv_1x1 = Conv2D(filters=64, kernel_size=(1, 1), padding='same', activation='relu')(input_tensor)# 3x3 卷積conv_3x3 = Conv2D(filters=64, kernel_size=(3, 3), padding='same', activation='relu')(input_tensor)# 5x5 卷積conv_5x5 = Conv2D(filters=64, kernel_size=(5, 5), padding='same', activation='relu')(input_tensor)# 合并不同尺寸卷積的結果output = Concatenate()([conv_1x1, conv_3x3, conv_5x5])return output# 輸入層
input_layer = Input(shape=(224, 224, 3))# 應用并行卷積層
output_layer = parallel_convolution(input_layer)# 創建模型
model = Model(inputs=input_layer, outputs=output_layer)# 查看模型概況
model.summary()