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 要知道目標的架構與性質