---
# System prepended metadata

title: CNN

---

CNN
==

# Why CNN

- 常用於影像辨識上
- 也可以用neuron network來做，每一個點視為一個classifier，往往我們會需要過多的參數
    - 假如現在有一個100x100的圖，我們input需要100x100x3(顏色)需要3萬維的vector，參數太多了
    - CNN 就是為了減少這情況，先濾掉一些不會用到的weight

## 3個property
1. 許多patterns往往只佔圖片的一小部分，所以不用看整張圖片
    - ![](https://i.imgur.com/w1Oazp1.png)
    - 像是後面這個鳥嘴偵測器只要偵測小範圍，就可以判斷他是不是鳥嘴
2. 常常**相同**的patterns會在不同的地方出現，如果因此做兩個detector是很重複的行為，所以只要讓detector讀某一組參數就好，減少參數的使用量。
3. **Subsampling** :把圖變小，不會影響他讀的判斷，還可以減少參數的使用

# CNN Flow
- ![](https://i.imgur.com/bGY3UBG.png)
    - 首先先經過很多convolution, max pooling的組合
    - concolution負責解決Property 1, 2
    - Max Pooling負責解決Subsampling(property 3)
    - 再flattern將他展平
    - 最後再丟入fully connected
    - output結果

## 1. CNN Convoloution

- CNN跟Fully connected network的關係
    - 這邊用的是6 * 6的黑白為例子，filter為3 * 3
    - ![](https://i.imgur.com/QZm4xJs.png)
        - 可以看到這邊他顏色都有標記好相對應的
        - 相當於做某hidden layer 的計算，且他不是取36個參數都看，只看filter的那9個，縮短了計算量
        - 可以吧他看成一個神經網路，就是有被filter對到的部分乘上weight，剩下的乘上0，得到neuron = 3
    - ![](https://i.imgur.com/Xf2aBPH.png)
        - 隨著stride不斷移動他會不斷生出下一個neuron
        - 在這邊他是使用filetr來移動所以他是**使用相同的weight**，而原本的neuron network會是不一樣的weight -> **shared weights**
        - 減少參數的使用！


### 黑白照片
- 他會有**很多**filter，這些filter（小於原本的pixel數），就是偵測小範圍的patterns，然後filter裡面每一個參數都是自己去學習的，不是人設定的
- 一開始先設定他從左上方開始，然後分別跟對上的pixels做內積，之後再向右移幾格(稱為**stride**)
    - ![](https://i.imgur.com/j152I43.png)
    - 所以我們把6 * 6的matrix壓成4 * 4的matrix(filter 3 * 3)
    - 再比較他**內積**的結果，就可以知道哪一個範圍他有吻合
    - 順便也滿足**property 2**的，用單一個detector可以判斷不同region的pattern
- 會有很多filter做這個操作，會形成多組**feature map**
    - **有多少filter就用有多少feature map**(在keras稱為channel)
    - ![](https://i.imgur.com/ccLtMQW.png)


### 彩色照片
- 彩色照片就是3個matrix疊再一起形成的立方體，現在我們的**filter也會是立方體**
    - ![](https://hackmd.io/_uploads/HydqRZ8E3.png)

    - ex: rgb照片 3 * 6 * 6, filter就會是3 * 3 * 3，就像黑白剛剛一樣對他做內積

## 2. Max Pooling
- 只取image中最大的那一項保留
    - ![](https://i.imgur.com/Zd4Ykb8.png)
    - ![](https://i.imgur.com/7rDeiMX.png)
- 所以一個圖(6 * 6)經過convolution(4 * 4)，在經過maxpooling(2 * 2)
    - ![](https://i.imgur.com/3E1RNJw.png)
    - 這操作可以repeat很多次，使圖片一直壓縮
- 這邊有一個要注意的是:
    - ![](https://i.imgur.com/8eidYp0.png)
    - 假如有 20 個filter，經過concolution, max pooling變成4 * 4他會有20個channel


## Flattern
- 就是很簡單的把他拉直丟進Fully Connected network
    - ![](https://i.imgur.com/OtHKPwh.png)

## CNN in Keras
- ![](https://i.imgur.com/kJlE4bW.png)
    - convolution(多少filter, filter x, filter y)
    - input_shape(有幾層, image x, image y)
        - 1:黑白照片, 3:RGB照片
    - maxpooling(x, y) -> 在x * y之中取最大的
- ![](https://i.imgur.com/dbaF3yE.png)
    - 上面黃色的9是代表他是3 * 3的filter然後input進去是只有一層，所以**每一個filter**是3 * 3 = **9 個參數**
    - 而下面橘色的225，因為同樣filter 3 * 3但是現在的input有25層，所以**每一個filter**是3 * 3 * 25 = **225個參數**
- ![](https://i.imgur.com/4Kzqd1S.png)
    - 這邊有他vector的變化，最後再做flattern就可以傳進去fully connected network

# What does CNN learn?
- ![](https://i.imgur.com/b2xyuoA.png)
    - 以第k層convolution為例，他的input已經不是原來的圖，而是第一層操作玩的結果，filter為11 * 11的參數matrix，用$a_{ij}^k$代表他裡面的數值，
    - 這邊$a^k$代表他feature map所有項的和(用來評斷好壞)，做為第k個filter **activate的幅度**(多接近input)
    - 也就是找$a^k$使k filter activate最大
    - 我們要找一個x使$a^k$使他最大
    - 然後我們要做gradient ascent(因為現在要找最大)來找到最好的$x^*$
    - 所以有點像是我們用已知的output($a^k$)來推input($x^*$)
- ![](https://hackmd.io/_uploads/Byq6JWSVh.png)
    - 所以這張每一格代表不一樣的filter他所在意的長相(紋路)(每一個filter只會判斷小範圍的長相)，他所推出來的$x^*$

- ![](https://i.imgur.com/Noq4xdp.png)
    - 跟上面的操作是一樣的，用output來推input的感覺
    - 不一樣的是上面是推出filter的$x^*$(是紋路)，neuron退出的$x^*$是整張圖
    - 還有一點我們取的$a_j$，他是經過flattern 他會把他壓會一個圖，而不是局部的圖

- ![](https://hackmd.io/_uploads/HJIu-WrVh.png)
    - 這邊取結果來推出他的image，會發現每一個都亂七八糟，但是把他亂七八糟的圖丟進CNN他會判斷出對的對應圖
    - ：**神經網路**跟人學到的東西是很不一樣的

- ![](https://hackmd.io/_uploads/BkXtz-rE2.png)
    - 對L1做**regularization**
    - **白色點代表有墨水的地方**，我們希望可以得到最小的sum($x_{ij}$)，使白色點越少越好(在不該出現白色的地方不要出現)
    - 右邊稍微有比較好
    - 問題：
        - L1 regularization是什麼
        - 怎麼微分sum($x_{ij}$)


## Deep Dream

- ![](https://i.imgur.com/d63iVYC.jpg)
    - 把照片丟到cnn之中
    - 取某一段hidden layer(是一個vector)
    - 把vector中的值調大(正變更大，負變更小)
    - 用此vector做gradient descent來找出對應的圖片
    - 用CNN誇大他看到的東西


## Deep style

- input 一張照片然後可以結合其他畫
    - ![](https://i.imgur.com/weMcNBe.jpg)
        - 將原本將原本圖片丟進CNN，得到它filter的output(這張圖裡面有什麼)稱為content
        - "吶喊"也丟進CNN，會得到style(filter跟filter之間的correlation)
        - 用用同一個CNN找相片，使他的filter的output像是content，filter correlation像是style的相片(用gradient descent找)

## Go

- Go是使用CNN(但是圍棋不一定只能用CNN，也可以用fully connected network)，但是CNN會perform好很多
- ![](https://i.imgur.com/UKgfN0P.png)
    - 在圍棋上是有很多CNN適合的性質，
    1. property 1 :他會有很多小region，可以只看5 * 5的範圍判斷現在的性質，而不是19 * 19
    2. property 2 :會有很多相同的patterns出現在不同地方，但是代表相同意義，用同一個detector處理
    3. property 3 :subsampling感覺很不合理之原因：
        - ![](https://i.imgur.com/O3yT3qz.png)
        - input 一個19 * 19 * 48(每個位置有48個value描述他，用來描述個種狀況)
        - 19 * 19 * 48 -> 1st hidden layer -> 23 * 23之image -> k filters 5 * 5, stride = 1 -> Relu -> 21 * 21 之image -> k 3 * 3隻filter, stride = 1 -> ... ->
        - 沒有用max pooling, 因為圍棋性質也不適合用max pooling

## Speech
- CNN 可以用在語音辨識

- ![](https://hackmd.io/_uploads/BJp1lQ8N3.png) 
    - 可以直接對頻圖做CNN，然後就可以得到他說什麼
    - 一般會對y軸的方向(Fequency)
    -  像是不同人說一樣的話，頻率會不一樣，但是在頻圖上的形狀應該差不多，只是會有位移而已，剛好滿足property 2


- CNN 可以用在文字辨識
- ![](https://i.imgur.com/5HuoaXM.png)

    - 每一個word都用一個vector來表示，兩個word意思越相近，他的vector就越相近。
    - 排在一起就變成sentence matrix(image)
    - CNN會走x軸(時間軸)的方向，filter大小就是藍色的部分，(y軸上是彼此獨立的資訊)

- 要設計好CNN 要知道目標的架構與性質



