---
tags: 深度學習筆記
---
# CNN原理

* 輸入層
輸入資料(Data)的特徵值 (Features)
* 隱藏層
隱藏層在做運算,由神經元(Neuron)組成,透過**前向傳播(Forward propagation)** 計算出我們的**Output值。**
* 輸出層
透過輸入特徵,經過隱藏層的運算所得到的預測值,我們藉由**縮小預測值與實際標註值**(Label),**更新**我們隱藏層的**參數**,最終**訓練**出一組**權重(weights)**。
---
## CNN (Convolutional Neural Network)
#### 權值共享
一般的FC架構,輸入一張**28*28*1的灰階照片(784個特徵)**,隱藏層使用100個神經元,那麼需要多少個參數?
:
**100*784 (weights)+100 (bias)= 78500個參數
在一般的圖像內有**許多的特徵是相同的**,如特定的輪廓或線條,那我們就可以讓相同幾個神經元組成的**卷積核**去學這個特徵,透過滑動窗口(filters、kernel)對整張圖片進行卷積,進而達到節省參數的效果
#### 保留位置資訊
CNN還有一大特色就是能保留圖像的位置資訊
圖片中的像素 (Pixels)與其鄰近的像素會有一定的關聯度
如果使用FC的結構來訓練圖像資訊的話,要先通過一個展開(Flatten)的步驟,把高維的資訊拉成一條直線,如此一來就會大量失去特徵之間的空間資訊,效果不佳。 *(大部分FC變成最後一層*
## 卷積(Convolution)的基本概念
> 透過卷積核(Kernels)滑動對圖像做訊息提取,並藉由步長(Strides)與填充 (Padding)控制圖像的長寬
卷積核
卷積核(Kernel)又稱為Filters、Features Detectors
1. 可以藉由選擇Kernel的**張數**控制 Feature maps (圖像經由Kernel卷積後的結果,也就是下圖中粉紅色的部分)的**深度**
1. 藉由調整Kernel**大小**決定Kernels的特徵接受域 (Receptive field)。

### Kernel的起始值與運算
上圖中黃色區塊就是一個3*3的Kernel,其中的值就是我們**預訓練的權重**,通常用常態分佈隨機產生,再經由訓練更新。

**Kernel的張數**
控制張數主要就是控制學習的參數量,沒有一定幾張就是對的,常見是16、32或64
如果16就能達到很好的效果,就不需要浪費額外的參數去增加學習和計算量
**Kernel大小**
現在普遍流行的方式是選用**不同大小**的Kernel對圖像做卷積後,再把**輸出的Feature maps合併或平均**。
常見的Kernel大小有1*1, 3*3, 5*5, 7*7。
然而也有人提出,兩層3*3的Kernel 卷積與一層的5*5Kernel 卷積擁有相近的Receptive field,並且使用較少的參數量,因此不妨去嘗試看看不同組合的效果。
**步長**
步長(Strides)為控制圖像長寬尺寸的方式之一,下圖中的Kernel步長分別為1、2,可以觀察到輸出的Feature map大小也不同,雖然通**常長寬上的步長會設為相等**,但我們也可以透過不同的**長寬步長**控制Feature map不同維度尺度的變化。

**填充 (Padding)**
[1]填充 (Padding)是透過在圖像周圍補值為0的像素,其與[2]Strides及[3]Kernel 尺寸**決定輸出Feature map的大小**。
下圖為3*3的Kernel, Stride為 『1』,Padding也為 『1』,可以發現輸出的Feature map與輸入的圖像擁有一樣的尺寸。

通常Padding 又可以分為兩類,分別為: (這部分尚未了解,待查)
* Same Padding
『Same Padding』在Stride為1時,會讓輸出Feature map與輸入圖像**維持一樣的尺寸**,可參考下方程式碼。而當Stride大於1時,輸出Feature map寬、高等於輸入影像寬、高/Stride(小數值無條件進位)。
* Valid Padding
『Valid Padding』不會特別去補邊,因此會讓輸出的Feature map尺寸下降,而當遇到卷積無法完整卷積的狀況則會直接捨棄多出來的像素。
```python=
import tensorflow as tf
import numpy as np
input_image = tf.constant([[1., 2., 3., 4.],
[4., 5., 6., 4.],
[3., 4., 5., 4.],
[3., 4., 5., 4.]])
input_image = tf.reshape(input_image, [1, 4, 4, 1])
output_valid=tf.layers.conv2d(inputs=input_image,filters=1,kernel_size=(3,3),strides=(1, 1), padding='valid')
output_same=tf.layers.conv2d(inputs=input_image,filters=1,kernel_size=(3,3),strides=(1, 1), padding='same')
output_valid.get_shape() == [1, 2, 2, 1]
output_same.get_shape() == [1, 4, 4, 1]
```
公式化輸出尺寸:
* SAME Padding

* Valid Padding

### 輸出Feature map尺寸
卷積過後Feature map尺寸可藉由下方公式計算,其中 input=輸入圖像、p=Padding、f=Filters size、s=Strides。
如果我們使用3*3 filter size, Padding =1, Stride=1,經過計算後會發現Output=Input。
<font size="6">Output = (Input+2p-f)/s+1 </font>
## CNN圖像辨識

展示一個簡單的CNN圖像辨識模型架構,主要可以拆解為:
---
[卷積層→激勵函數(activation function)→Batch Normalization]= <a style="color:red;" > **卷積組合** </a>
<font size="8"> 輸入圖像→[卷積組合→最大池化(Max Pooling)]*n→攤平(Flatten)→全連接層(Fully Connected layers)→分類 </font>
---
### 輸入圖像
一般來說CNN的輸入圖像為四維的Tensor
Tensorflow:[Batch_size,Height,Width,Channels]
Pytorch:[Batch_size,Channels,Height,Width]
**Batch_size**是你的一個Batch放了幾張照片,可以不用先設定,**height、width**就是輸入圖像的長寬尺寸,**channels**指輸入圖像的深度,一般RGB彩色圖像為3,灰階圖為1。
### 卷積組合
卷積層如同上面所敘述的,通常還會經過**激勵函數(增加非線性性**)與**Batch Normalization**(加速收斂並同時達到一定的regularization效果)。
### 最大池化
常見Pooling 為 Average Pooling 與 Max Pooling
其中又以Max Pooling 最常見,其原理是透過window對應Feature map並提取其最大值。
**Max Pooling主要用於提取重要特徵、加速收斂並縮小Feature map尺寸。** 通常都會使用2*2的window,並且設置Stride為2,如此一來output size就會變為原本的1/2。
不過近期也有諸多學者提出,Max Pooling會導致大量特徵消失,因此逐漸採用其他方式代替Max Pooling來降低Feature map尺度。

### 攤平
攤平(Flatten)這個步驟主要是要**銜接CNN層與全連接層**,主要是因為FC層需要**一維的輸入**,常見其他方式還有Global average pooling。
### 全連接層
全連接層(FC)主要在做**最後的特徵提取**,並且利用最後一層FC當作分類器。
### 分類
要怎麼使用FC最後一層作為分類器?
假如要分的類別有10類,那FC最後一層就會接10個神經元,並且經過Softmax function。
下圖為Softmax原理,數值經過softmax function後,其加總值會變為1,因此我們可以把**各項的輸出值當作機率**,而目標就是要**縮小預測機率值與實際Label值**。
以下圖為例,預測輸出為[0.7,0.2,0.1],Label可能為[1,0,0],因此要讓0.7去接近1 *(這就是訓練的目的)*,實際做法是用Cross Entropy計算。
Cross Entropy 常用在分類器的Loss Function上面,相較於Mean Square Error(MSE)更能凸顯機率分佈之間的差異。
<font face="Times New Roman"> **Softmax** </font>

由於我們是多類的問題,所以使用Categorical Cross Entropy。
<font face="Times New Roman"> Cross Entropy </font>

Dice loss
$(2x^Ty+e)/(x^Tx+y^Ty+e)$
---
Reference
https://cinnamonaitaiwan.medium.com/%E6%B7%B1%E5%BA%A6%E5%AD%B8%E7%BF%92-cnn%E5%8E%9F%E7%90%86-keras%E5%AF%A6%E7%8F%BE-432fd9ea4935
---