AndrewNG Deep learning課程筆記 - CNN


參考,

An Intuitive Explanation of Convolutional Neural Networks

http://www.hackcv.com/index.php/archives/104/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

 

CNN基礎

CNN網絡主要用於compute vision

對於圖片輸入而言,是一種極高維度的數據,比如分辨率1000*1000*3的圖,可能會產生3 billion的參數,這不太可行

 

所以我要使用convolutional NN來解決這種問題,

首先看看什么是卷積操作,

如下圖,

原圖片6*6

中間3*3的矩陣,稱為filter或卷積核kernel,它表示你需要匹配的模式,這里detect edge,豎線

最右邊4*4的矩陣,就是進行卷積操作后的結果

為何這個filter可以找出豎線,直觀理解,filter找出左右存在色彩反差的區域或者找出由明轉向暗的區域,如下圖

 

實際中還有很多其他的filter,

但是其實在deep learning中,你不需要去手工設計或者選擇filter,因為他們是學習的參數,可以通過模型學習到

 

可以看出用卷積可以大大減少需要學習的參數,

 

為什么卷積網絡,可以用這么少的參數?

首先是參數共享

通過一個filter可以找出圖片上任何位置的特征,如豎線

這樣的好處是無論輸入圖片多大,參數size都是固定的,由filter本身決定

第二,稀疏鏈接

如果是全連接層,每個輸出的每個維度都和輸入的每個維度相關,所以需要很多的參數
而在卷積層,一個輸出的某個維度如下圖,是由輸入中的9個feature算出的,而其他特征無關

這樣需要的參數大大減少,同時也降低了過擬合

 

Padding

上面的卷積操作有兩個問題,

每次卷積操作都會縮小圖片的尺寸

會丟失邊緣區域的特征

所以為了解決這些問題,padding就是把圖片擴大一圈,用0填充

這樣就有兩種convolution操作,

valid就是no padding,結果大小的公式,n-f+1

same就是padding讓輸出結果大小不變,根據公式算,p=2的時候,就可以保證不變

這里描述filter一般都是odd,而不會是偶數,直觀上講,如果f是偶數,那么沒法對稱的padding,而且f是奇數是filter是有中心點的,這個很方便
所以filter一般都是3*3,5*5,7*7

 

strided convolution

對於convolution,除了調整filter size,padding,還可以調整stride的大小

可以每次滑動超過1步,那公式會變成如下,

cross-correlation VS convolution

在通信或數據中,convolution操作要先把filter,同時在橫軸和豎軸上進行翻轉,如圖,

這樣做的好處,是可以讓convolution操作滿足結合律 

但是在DL中,我們其實沒有做這種翻轉,這種操作其實應該叫做cross-correlation

但是大家都習慣和默認稱為convolution

 

convolutions on volumes

真實的圖片有RBG三層,所以是立體的,這樣如果進行convolution

輸入數據的層數,稱為depth或channel

當輸入數據有3個channel,那么filter對應也需要有3個channel

如圖,上面這個3*3*3的filter可以detect 紅色的豎線

下面這個,可以detect 任意顏色的豎線

在實際使用中,需要同時detect多個feature,所以有多個filter,如下圖

輸出數據的channel數,取決於filter的數目

 

one layer of a convolutional network

那把卷積操作放到網絡中的一層結構如下,

卷積再加上b,就完成了線性變換的部分,后面跟上非線性變換,就完成了一個神經單元

上圖中的各個參數的表示如下,

 

 給出一個完整的CNN的例子,

每層的結構,根據上面的公式很容易算出,卷積層只是做特征的提取和變換,最終輸出前,還是需要fully connected,然后用logistics或softmax輸出結果

 

CNN網絡一般有三種layer組成,convolution層,pooling層,fully connected層

 

pooling layers

池化層,利用采樣高效的降低維度和減少特征值

 

一般有最大和平均池化,這層是沒有參數的

 

neural network example

卷積神經網絡的結構比較復雜,而且超參數非常多,所以常用的方法是參考經典的網絡結構

先看個例子,用於手寫體數字識別,

如下圖,總結下這個網絡的結構,

能學到的規律,

首先,池化層沒有參數,而卷積層的參數並不多,參數主要集中在全連接層

然后,CNN的經典結構就是,cov-pool-cov-pool-fc-fc-fc-softmax,幾層cov和pool組合,加上幾組fc層

再者,activation size是慢慢減少的,如果降低的太快會影響模型的性能

 

Case Studies

參考,https://zhuanlan.zhihu.com/p/22094600 

比較直觀看出各個網絡的年代和性能差距

 

 

LeNet-5

該網絡由作者名字LeCun命名,5代表五層模型

該網絡,用於手寫數字識別,用於灰度圖片,所以圖片channel為1

網絡整體有60k的參數,比較小

用於當時沒有padding技術,所以隨着網絡depth增加,size是不斷變小,但是channel是不斷變大的

網絡結構被后續沿用,若干cov+pool + 若干fc + output 

從原始圖片1024個像素到最后一層FC的維度84,所以cnn關鍵就是抽象和提取特征

 

AlexNet

這個網絡也是用作者名字命名的

AlexNet和LeNet其實比較像,就是規模大了許多,參數從60k到60m

只所以可以訓練這么大的網絡,是因為AlexNet在工程實踐上利用的GPU

然后AlexNet,采用了Relu和dropout,最終把compute vision帶到一個新世界

 

VGG

VGG網絡是比AlexNet規模更大,更深的網絡模型,參數達到138M之多 

16表示有參數的layer有16層

VGG的特點是結構規整,工業化的思路,我們不去精巧的設計,依賴網絡的規模和數據規模來解決問題

首先他用的Conv和Pool模塊是固定的,

Conv是3*3,s=1,same

Pool是2*2,s=1

然后為了便於表示,在圖中省略了Conv的參數,Conv 64 *2,表示2層卷積層,每層有64個filter

再者,

由於這里用same conv,所以conv是不會改變圖片size的

全靠pooling層改變圖片size,並且也很有規律

多個Same Conv后,會接一個Pool,這樣picture的size減半,並且每個Pool后,加上的Conv層的channel都會double

所以還是符合size變小,channel變大的規律,只是更規整

 

Residual Networks(ResNets) 

殘差網絡的本質是要解決網絡太深后難以訓練的問題,由於梯度消失或梯度爆炸

可以看到之前的網絡也就十幾層,而殘差網絡都是上百層,甚至上千層

所以殘差網絡效果好,不是有什么秘訣,因為更深的網絡,更好的性能,這是理所當然的

只是之前的網絡模型,在實踐中無法訓練到那么深

殘差網絡,是由residual block組成的,

residual block至少兩層layer組成,

除了普通的main path,不同就是多了shotcut或skip connection

即,會把第一層的輸入a1,疊加到第二層的激活函數前

所以第二層的輸出,就從a2 = g(z2),變成a2 = g(z2 + a1)

 

我們把很多的residual block 堆疊(stack)在一起,就形成residual network,如下圖,

如圖,把plain network變成ResNet,只需要給每兩層加上shortcut,這樣就可以解決plain network當layer數過大性能明顯下降的問題

 

為什么殘差網絡可以幫助網絡增加深度?

NG的觀點是,因為residual block對網絡是無副作用的

如下圖,由於residual block的輸出是a2 = g(z2 + a1)

那么只要讓z2 = w2a1 + b2的參數,w2,b2趨於0(類似正則化),那么a2=g(a1),如果g是relu,那么g(a1)=a1,所以得到a2 = a1

而讓參數為0這是很容易學習的

所以說residual block最差的情況就是,原封不動的傳遞輸入,這樣當然無論迭代多深都沒有關系

但是,如果不是最差情況,能學到些東西,對網絡就可以產生正向的幫助 

這里residual block有個假設,就是z2 + a2,那么兩者的size需要一樣

如果不一樣了?那這里需要增加一個參數,Ws用於把a2的size轉成和z2一樣

 

下圖是個實際的例子,如何將一個plain的cnn,轉化為一個ResNet網絡

注意虛線的鏈接,表示經過pool,size變化后,需要進行size轉換

 

Inception網絡

inception各個版本對比

https://blog.csdn.net/xbinworld/article/details/61674836

inception的命名,是因為在盜夢空間,inception,中有一句台詞,“we need to go to deeper”

所以可以看出,inception network或GoogleNet的主要目的,也是讓網絡更深

 

首先看下1*1 convolution

1*1 convolution,其實就是單像素點,在各個channels上的線性組合

它的作用,

主要就是低成本的調節channel數,或depth;在不需要調整長寬的情況下,用3*3,5*5,比較耗費性能

再者,因為有relu輸出,附帶一層非線性效果

 

下面就看看啥是inception網絡,

普通的convolution網絡,你要選擇用什么樣的filter或是用pool層,選擇困難怎么辦?

Inception的思路就是,都用上,然后把結果stack在一起,讓模型去決定

注意這里要保證輸出的size一致,所以這里的pool是same pool,不會壓縮尺寸,這是很特殊的pool用法

這個思路最大的問題就是計算量太大,那么這時我們的1*1 convolution就用上了

 

比如上面的例子,直接對輸入做5*5 convolution,那么計算量120 million

用上1*1 convolution,先把depth降下來,再算5*5 convolution,這樣計算量只有12 million左右,小十倍

可以看到,兩個方法,輸入和輸出都是一樣的,但用上1*1 convolution降低channel后,計算量大大降低

中間這層稱為,bottleneck layer,使用恰當的情況下,降維優化並不會損失算法的performance

我個人的理解,由於1*1 convolution是各個channel的線性組合,加上適當數量的filter,並不會丟失太多的信息

 

Inception module

現在來看inception module就比較清楚了,

如圖就是一個inception module,其中1*1 convolution都是用來調節depth的

比如MaxPool后面的,就把depth調節到32,避免pool的結果在最終stack中占太大的空間 

而inception網絡,就是inception module的堆疊,中間還會加上些紅色的pool層來調節size

 

Object Detection

classification with localization

這個和普通圖片分類的區別,就是除了給出類別,還要給出在圖中的位置信息

看這個例子,除了要給出圖片是哪一類,1,2,3,4,car是2

還要給出car的位置,bx,by,bh,bw

這里假設圖片的坐標是,從(0,0)到(1,1)

這樣就有5個輸出,其他的和原來一樣,還是交給模型去訓練

 

 具體實現如下,

這里的輸出增加一個Pc,表示是否有object,0或1

bx到bw是代表object的位置

c1,c2,c3表示具體的類別

這里給出兩個例子,一個是車的,一個是單純背景無object的

注意,

loss function中,如果Pc=0,表示沒有object,那么后面的值就沒有意義,所以在算loss function的時候就不需要考慮,只需要算第一項的平方誤差

上面是比較簡單的位置的例子,還可以檢測面部特征或體態特征這樣的case,思路都是一樣的,關鍵是定義清楚位置特征作為輸出

當然關鍵是,你需要有相當的訓練集

 

sliding windows object detection

如果一個圖里面有多個對象怎么辦,這個就是object detection

傳統的方法就是,sliding windows object detection,很naive的方法

拿一個框去遍歷裁剪圖片,對每個裁剪下來的小圖,做分類,是否有object,是什么object

這個方法的問題很明顯,你如何定義裁剪尺寸,太大就沒有意義,太小計算量就會非常大

傳統的方法是用線性回歸來做分類,性能還能接受,但是用cnn性能就不行了

 

上面的圖,顯示如何通過cnn進行分類,14*14*3是裁剪的小圖片,通過conv層,pool層,然后FC層,最后softmax

為了優化,我們可以把整個分類的過程,都轉化成conv層

比如,第一層FC,5*5*16,全連接到400的節點

我們也可以用400個5*5*16的filter,進行卷積,最終得到1*1*400,同樣的效果

這樣第二層FC,我們用400個1*1*16的filter來代替

最后softmax,用4個1*1*16的filter來代替

這稱為,convolutional implementation

這樣的好處,我們可以把遍歷裁剪圖片分類這個過程,通過一遍cnn計算搞定

比如,輸入圖片16*16*3,裁剪大小是14*14*3,如果遍歷輸入圖片會產生4個小圖片

這里我們不用對每個小圖片分別采用conv計算,如果這樣做會產生大量的重復計算

而只要整體的做一遍conv計算,如下圖,最終得到2*2*4的輸出,即一下輸出4個裁剪小圖片的結果,效率大大提高

但這個方法,我們仍然需要指定裁剪size,

但這樣只能判斷object是否在小圖片中,無法給出更精確的位置信息;並且很有可能object無法完整的被任何裁剪小圖包含

 

Yolo(you only look once)

Yolo的思路,既然上面單純的分類無法找到精確邊界,那我們加上classification and localization的部分

對每個圖片同時給出分類和邊界數據,

既然我們可以得到精確的邊界,所以就沒有必要用sliding window,直接用grid把圖片切分就可以

對於下面的例子,我們把圖片用3*3的grid划分,最終就得到3*3*8的結果

訓練這個模型,我們也要按照這個格式給出訓練集,比如上圖中,給出綠色框和黃色框的數據作為實例

由於這里也用convolutional implementation的方式,使得計算非常高效,

所以訓練集中,x表示輸入圖片,100*100*3,輸出就是3*3*8

 

ok,這里明顯的問題是

如果一個grid里面兩個objects,怎么辦?這個通過用小grid來降低概率,比如用19*19

反之,如果一個object比較大,占好幾個grid怎么辦?

我們只看,object的中心點,bx,by落在哪個grid,那么就認為object屬於這個grid,即Pc為1,其他的grid仍然認為沒有object 

所以bx,by一定落在grid內,所以bx,by都是小於1的(grid的邊界從0,0到1,1)

但是由於object是可能占多個格子的,所以bh,bw可能是大於1的

 

Intersection over union (IOU)

如何判斷算出的bounding是否精確?

很簡單,交並比

下圖,紅框是精確的bounding box,而紫色的算出的bounding box,想判斷紫色的bounding box是否足夠精確

 

Non-max suppression

用yolo算法的時候,

在准備訓練集的時候,我們可以把一個車根據中心點放到一個grid中

但是在predict的時候,會有不止一個grid認為車在自己的grid中如圖,並用Pc來表示概率

 

那么直接的想法,既然Pc表示概率,我們就選概率最大的,其他的都discard掉,就好了

如果圖片中只有一個object,這個方法是可以的

但是如果有多輛車,我怎么知道哪些grid的bounding box是描述的同一輛車?

這里就要用到交並比,如果兩個bounding box的IOU大於0.5,我們就認為是同一輛車

所以得到下面的方法,

首先discard掉所以Pc較小的grid

然后找到最大的Pc,然后刪掉所有和它的IOU大於0.5的grid,這樣一個object就保留了一個Pc最大的grid

如果還有grid剩下,說明有其他的object,再重復上面的過程一一找出

 

Anchor boxes

前面說了當用很小grid的時候,一個grid中有多個object的概率是很小的

但如果要在一個grid中detect兩個object應該怎么做?

直接的想法是,我用8位的輸出來detect一個object

那如果要detect兩個,就用16位輸出,分別表示兩個object

比如下圖,圖片中人和車都在一個grid中,所以我們就用前8位表示人,后8位表示車

這樣講人可以理解,機器不行

所以我們要用機器可以理解的概念來定義人和車,

這里就是用anchor box,anchor box可以人手工設計,也可以用k-means去統計,比如人的平均邊界,車的的平均邊界

如下圖,我們就用anchor box1代表人,anchor box2代表車

那么一個object到底是算哪個box?還是用交並比,和誰的交並比大就算誰

 

這個方法用起來比較麻煩,detect兩個object就用16位輸出,如果要detect多個object就要更多位的輸出

而且還要指定和設計anchor box

然后如果grid中出現多於假設個數的object,就沒辦法處理

或者兩個object的anchor box類似,也很難處理

 

Region proposals

除了,Yolo,還有另外一個思路來加速sliding windows object detection

region-cnn,思路就是對於sliding windows object detection,我們要遍歷所有的裁剪圖片去做分類,但是某些裁剪圖片明顯是沒有任何東西的

所以,region-cnn會對圖片做分塊,segmentation,如最右圖,這樣只需要對不同的色塊做分類即可

那么執行分類的candidate變少,性能就提高了

 

Face Recognition

Recognition可以分解成verification的問題,如果解決了verification的問題,那么Recognition只是遍歷的問題

這里要注意的是,如果要在Recognition達到一定精度,verification的精度要提高幾個量級

因為如果verification的精度99%,但庫里面有100張圖片,所以每次誤差的疊加就會很高 

 

One-shot training

在很多場景下,你不會有很多關於某個人的圖片,可能只有一張圖片作為訓練集,當這個人再次出現時,你要能夠認出他

這個用傳統的cnn就無法解決,首先訓練集太少,無法得到有效的網絡

再者如果要識別的對象增加,比如新員工入職,你需要從新訓練網絡

所以采用的方法是,

 

Siamese network

具體的做法,就是通過cnn對圖片進行encoding,比如下圖,一張圖片會編碼成128位的向量(往往成為embedding)

那么訓練目標,就是相同人的圖片得到的embedding間的距離比較小,反之

 

Triplet loss

Triplet,顧名思義,一個訓練集中有3個圖片,anchor作為baseline,一個positive,和一個negative

很明顯,

我們的目的就是,讓d(A,P)小於d(A,N),d是距離

光小於不夠,要遠小於,所以加上margin超參數alpha

形式化,

A和P的選擇很簡單,

對於N的選擇,我們應該盡量選擇和A相近的N,這樣算法效率會更高,如果我們隨機選擇N,會讓上面的約束很容易達到,會大大降低訓練效率

 

除了triplet loss,也有其他的方法訓練,siamese network ,比如下面的方法,把兩個圖片的embedding,作為logistics回歸的輸入,變成一個分類問題去訓練

 

Neural sytle transfer

sytle transfer要做的如下圖,

給出一張content圖片C,一張style圖片S,要的效果就是生成G

所以優化目標,J(G),由兩部分組成,

J(C,G),表示G和C在content上的相似度

J(S,G),表示G和S在style上的相似度

下面就分別來定義這兩個目標函數,

content cost function

判斷內容是否相似比較直觀,和前面臉部識別一樣,我們只要把圖片encoding成embedding,然后比較相似度就好

實際做,

找一個pre-trained的ConNet,選一層l的輸出作為embedding,通常l不會太淺也不會太深,這樣可以比較好的代表圖片的內容

剩下的就是計算兩個embedding的相似度 

 

style cost function

關鍵是要找出,style是什么?

這里給出的定義是,對於某個layer,style是各個channel的相關系數

cnn中,某一層的各個channel是由不同的filter生成,filter可以理解代表某一種特征

直觀理解,如果兩個channel相關性高,說明其filters所代表的特征常常會同時出現,比如下圖,中豎線和橘色兩種特征

形式化定義,我們用style matrix,G[l],來表示圖片在第l層的風格,

G用來表示每個channel之間的關系,所以nc*nc大小的

k層channel和k‘層channel的相關系數,就是兩層對應的每個位置數據的乘積和,也稱為gram矩陣

直觀上簡化一下,如果數據只有0,1,如果兩層不相干,乘積和會為0,只有相關才會同時出現1,這樣相關系數才會大

那么上面就給出在l層上,S和G的style的cost function,其實就是計算S和G的style matrix的差異

最終J(S,G)會考慮所有layer上的風格矩陣的差異


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM