CS231n筆記|2 圖像分類流程

CS231n筆記|2 圖像分類流程

來自專欄 CS231n深度視覺筆記4 人贊了文章

2 圖像分類流程(Image Classification pipeline)

最鄰近、K-鄰近、L1距離、L2距離、線性分類器f-評分函數s

2.1 數據驅動

計算機視覺的核心任務就是圖像分類,圖像只是[0,255]之間的一個大的數字網格,我們的演算法應該對視覺變化、照明、形變、遮擋、背景混亂、類內變化等有魯棒性。圖像分類不像排序數字列表那樣,它沒有明顯的硬編碼演算法識別貓或其他類。

人們也嘗試了硬編碼的方法來識別不同的動物,如計算出圖像的邊緣,然後把邊、角等各種形狀分類好,寫一些規則來識別出貓,但這種方法容易出錯,並且要識別另外的物體時又要重新來一遍。

我們想要發開一種演算法可以識別出世界萬物,所以想到了數據驅動的方法,不再寫具體的分類規則來識別,而是在網上抓取大量貓等種類的圖片數據集,然後訓練機器來分類這些標記圖片,了解每個類的視覺外觀,機器會收集所有數據用某種方式總結,然後生成一個模型,總結識別出這些不同類的對象的核心知識要素,然後用這些模型來識別新的圖片,看是否識別準確,可以進行分類器的評估。

我們的API變成這樣,是有兩個函數,一個是訓練函數,用來接收圖片和標籤,然後輸出模型;另一個是預測函數,接收一個模型,對圖片種類進行預測。本課重點討論神經網路、CNN和深度學習等,數據驅動類演算法是比深度學習更廣義的一種理念。

Python教程: cs231n.github.io/python

NumPy參考手冊: docs.scipy.org/doc/nump

谷歌雲教程:cs231n.github.io/gce-tu

谷歌雲中提供的圖像支持以下框架:

* anaconda3,一個Python包經理。你可以認為它是一個更好的選擇pip

* NumPy,matplotlib,和其他普通的科學計算軟體包噸。

* tensorflow 1.7,CPU和GPU

* pytorch 0.3,CPU和GPU

* keras這與Tensorflow 1.7一起工作

* Caffe2,CPU。請注意,它是從原始的咖啡非常不同。

* NVIDIA運行時間:CUDA 9和CUDNN 7。它們只在創建雲GPU實例時工作。

* Python 3.6.4,這上面安裝了所有的庫。

2.2 鄰近演算法

1.最近鄰演算法

最近鄰演算法(Nearest Neighbor)通過尋找最近的一個點來分類,可以實現一個簡單的分類器,我們只需要記錄所有數據,在預測步驟,我們會拿一些新的圖片去在訓練數據中尋找與新圖片最相似的,然後基於此來給出一個標籤。

數據集CIFAR10會給出10個不同的類別,共有5萬張訓練數據圖大概平均分布在這10個類別中,還會有1萬張額外的測試圖片。我們將最近鄰演算法用在這些圖片,就能在訓練集中找到最接近的樣本,因為他們來自訓練集,我們就能知道最接近樣本的標籤。

2.L1距離

比較兩幅圖的方法,比如用L1距離(曼哈頓距離)取像素差絕對值之和,只對圖像的每個像素做對比,對應像素相減取絕對值,再將這些差值相加就是距離。

3.最近鄰分類器的Python代碼

import numpy as npclass NearestNeighbor(object):def __init__(self):pass##記憶訓練數據def train(self, X, y):""" X is N x D where each row is an example. Y is 1-dimension of size N """# the nearest neighbor classifier simply remembers all the training dataself.Xtr = Xself.ytr = ydef predict(self, X):""" X is N x D where each row is an example we wish to predict label for """num_test = X.shape[0]# lets make sure that the output type matches the input typeYpred = np.zeros(num_test, dtype = self.ytr.dtype)##對於每個測試圖像:查找最近的訓練圖像,預測最近圖像的標籤。# loop over all test rowsfor i in xrange(num_test):# find the nearest training image to the ith test image# using the L1 distance (sum of absolute value differences)distances = np.sum(np.abs(self.Xtr - X[i,:]), axis = 1)min_index = np.argmin(distances) # get the index with smallest distanceYpred[i] = self.ytr[min_index] # predict the label of the nearest examplereturn Ypred

問:在訓練集中有n個例子,訓練和預測過程有多快?

答:Train O(1)時間恆定, predict O(N)慢,測試時將數據集的N個訓練樣本與我們的測試圖像進行比較,這樣是不好的,相反我們需要預測的分類器可以快速的運行,在數據中心慢慢的訓練是可以的,我們有需要測試的分類器運行在手機、瀏覽器低功耗設備上。所以最近鄰演算法有點落後了,而CNN和其他參數模型正好相反,訓練慢、測試快。

4.K-近鄰演算法

K-近鄰演算法(K-Nearest Neighbors,KNN)的對象分類方法是由其最近的k個點中哪個類型占多數決定的。K=1時就是最近鄰分類器,K的值較大時決策邊界會更加平滑,下圖中白色區域表示區域中沒有最近的其他點。

當思考計算機視覺時,有一種觀點是在平面上的高維點概念,另一個觀點是具體圖像的觀察,因為圖像的像素允許我們把這些圖像看做高維向量。

圖像分類時KNN效果並不好,但還可以選擇不同的距離度量,當使用KNN時確定一個相對近鄰數據距離值來比較圖像類型。不同的距離度量,會在你預測的空間里對底層的幾何或拓撲結構做出不同的假設。通過不同距離度量,KNN可以泛化到許多不同的數據類型,向量、圖像、文本分類等。

5. L2距離

L2距離(歐幾里得距離)取像素差平方之和的平方根,在L1方形或L2圓形上的點分別與原點是等距的,L1距離取決於你選擇的坐標系統,所以如果轉動坐標軸時將會改變點之間的L1距離,而對L2無影響。當輸入特徵向量,對於向量中一些特殊意義的值或許L1更適合。但若它只是某個空間中的通用向量,不知道他的含義,L2更自然一些。

觀察當K=1時的最近鄰在不同距離度量下的分類效果,變化很大,L1時決策邊界趨向於跟隨坐標軸,因為L1取決於我對坐標軸的選擇;而L2不會受到影響,它只是把邊界放置在最自然的地方。哪種好還要具體情況試試。

k近鄰分類演算法互動式演示,平面上的每個點都用k-最近鄰演算法給它分配的類著色。你可以通過點擊和拖動移動點的周圍。 vision.stanford.edu/tea

6.超參數的設置

超參數(Hyperparameters)的設置是依賴於具體問題的,像K和距離度量的選擇,他們不能直接從訓練數據中學到,需要前提為演算法做出選擇,嘗試哪個參數最合適。設置超參數的策略如下幾種:

(1)選擇對訓練集最高的準確率、表現最佳的超參數,這是糟糕的,因為他可能對訓練集中未出現過的數據分類效果很差(過擬合),不要儘可能擬合訓練集,而是要讓我們的方法在未知數據上表現更好。

(2)將數據拆分為訓練集和測試集,在訓練集上用不同的超參數來訓練演算法,然後將訓練好的分類器用在測試集上,再選擇一組在測試集上表現最好的超參數。這也是糟糕的,如果用這種不同超參數訓練不同演算法的策略,選擇的表現最好的超參數,很可能這隻適用於此測試集,無法代表未知數據如何。從機器學習角度來講測試集的目的是給出一種預估方法,即在未知數據上演算法表現將會如何。

(3)將數據分為訓練集、驗證集和測試集三組,在訓練集上用不同的超參數來訓練演算法,在驗證集上進行評估,選擇一組在驗證集上表現最好的超參數,最後將這個在驗證集上表現最佳的分類器拿出來在測試集上跑一跑,即可得出此演算法在未知數據的表現性能。為了防止造假或偏差,要將驗證集和測試集分開,在最後一刻再給出測試集。這是較常用的。

(4)交叉驗證,在小數據集中更常用一點,先分出測試集,將訓練集分成很多份,輪流將每一份當作驗證集,以此輪流訓練和驗證,找出哪組超參數最穩定。但這在深度學習中,因為數據量很大計算力消耗嚴重,並不常用。

下圖5折的交叉驗證方法隨K近鄰中K值變化的效果圖,當K=7時準確率最高:

7.KNN的問題

訓練集就是一堆貼上標籤的圖片,將圖片與訓練集的每個元素比較,然後將與訓練數據最接近點的標籤作為結果;演算法無法看到驗證集的標籤,他們標籤只用來檢查演算法的表現。

統計學假設這些數據都是相互獨立,服從同一分布,這樣數據上的所有點都來自同一概率分布。但是現實中不可能總是這樣,測試集代表性不佳,我們通常收集數據時使用相同的方法一次性收集一大批數據,後期將它打亂隨機劃分成訓練集和測試集,對於不同時期收集的數據應該一起隨機劃分。

KNN在圖像分類中並不常用,因為它在測試時運算時間很長;並且像L2距離或者L1距離這樣的衡量標準不太適合用在比較圖像上,這種向量化的距離函數不太適合衡量圖像間的相似性,如下各圖的差距很明顯,但L2距離確是相同的,不能有效的表示出圖片之間的差異。

KNN分類器還有一個問題就是維度災難,KNN分類器有點像用訓練數據把空間分成幾塊,如果希望分類器很好,我們需要訓練數據能密集地分布在空間中,否則最近鄰點的實際距離可能很遠,也就和待測樣本的相似性沒有那麼高。而想要密集的分布在空間中,需要指數倍地訓練數據,我們不可能拿到那麼多圖片去密布這樣高維空間里的像素。下圖中點表示訓練數據,點的顏色表示訓練數據的類別,在一維空間可能只需要四個點就可以把空間覆蓋;但在二維空間需要4倍的點,也就是16個訓練數據才能把空間覆蓋;三維或者更高維所需要的訓練數據呈指數倍增長。

8.小總結

本節藉助KNN介紹了圖像分類的基本思路,根據最近的訓練集圖片和相應的標籤,可以預測測試集中的數據的標籤分類。KNN在機器學習演算法里有比較好的性質,但在實際應用中不怎麼好使,在圖像中也不怎麼用。

2.3 線性分類

1.KNN和線性分類的區別

線性分類是個重要且簡單的學習演算法,它有助於建立起(泛化到)整個神經網路和卷積網路,這種線性分類器就像巨型網路的基礎模塊。神經網路有模塊化的性質,將不同種類的神經網路組件組合在一起,來構建大型卷積網路。例如實驗室做的項目,輸入一副圖像,輸出用於描述圖像的描述性句子,這種工作方式有隻關注圖像的卷積神經網路,和只關注語言的循環神經網路,並且可以把這兩個網路放在一起,將其一塊訓練得到更好的系統。

最近鄰演算法設置中沒有參數,通常會保留所有種類的訓練數據,並在測試時全部使用。 但在參數化方法中所有訓練數據的經驗知識都體現在參數矩陣W中,在測試的時候不再需要實際的訓練數據,只需要這些參數W,這使得模型更有效率,甚至可以運行在手機這種小設備上,每個類只使用一個圖像而不是擁有數千個訓練圖像(雖然我們將學習它,但它不一定必須是訓練集中的圖像),我們使用(負)內積作為距離而不是L1或L2距離。。

2.線性分類器的用法

線性分類器(評分函數)是參數化方法(參數分類)中最簡單的例子,這個參數模型有兩個不同的部分,輸入數據記為X,參數設置或權重記為W 。CIFAR10數據集有5萬張訓練圖像,每幅圖像是32x32像素,每幅圖3個顏色通道,1000張測試圖像。現在需要寫一些函數,它們包含了輸入數據X和參數W,這就會算出10個數字來描述CIFAR10中10個類別所對應的分數,如果貓的分數更大,表明輸入X是貓的可能性更大。

基於參數的評分函數:將原始圖像像素映射為分類評分值(例如:一個線性函數)。

在深度學習中整個描述都是關於函數F的結構,可以用不同的複雜的方式組合權重和數據來編寫函數形式,這些可以對應於不同的神經網路體系結構。比如最簡單的相乘f(x,W) = W*x就是一個線性分類器,輸入圖像x即32x32x3數字數組(展開是個3072*1長列向量),W是10*3072的矩陣,相乘得到10個類的評分 f 即10*1列向量,有時會給這10個類的分數加一個偏置項b,它是一個10*1元素的常數向量,它是僅針對一類的獨立的偏好值,不與訓練數據交互,如當數據集中貓的數量很多時,貓的偏差元素就會高一點。

例如下圖線性分類器將圖像像素值拉伸為列向量4*1,權重矩陣W是3*4,一行代表一類,有3個類型,每個類型4個像素,還有3元素偏差向量,最後算出該圖像評為三類的得分。哪類得分越高就更可能是哪類?(疑問)

3.線性分類器的理解

(1)理解1-模板匹配

線性分類可以理解為每個種類的學習模板,對左下角圖裡的每個像素以及10個分類里的每一項,矩陣W里都有一些對應的項,說明哪個像素對哪個分類有多少影響。權重W里每一行都對應一個類的模板(原型),然後通過使用內積(或點積)將每個模板與圖像進行比較來獲得圖像的每個類的得分逐個找到「最適合」的那個類。如果要解開這些行的值,那麼每一行又分別對應一些權重,每個圖像像素值和對應那個類別的一些權重將這行分解回圖像的大小,就可以可視化看到每個類的模板。

如果根據模板匹配的觀點考慮線性分類器,實際上可以取那個權重矩陣的行向量將它還原回圖像,就是將這些模板可視化成圖像,下圖就是權重矩陣的10個行向量還原為10個類的可視化結果。

線性分類器每個類別只能學習一個模板,如果這個類別出現了某種類型的變體,他將求取所有不同變體的不同外觀的平均值,並且只能用一個單獨的模板來識別每一個。如在horse分類器中,像是有兩個頭,就是因為它只允許學習每個類別的一個模板。神經網路和更複雜的模型能夠得到更好的準確率,因為它對每個類別只能學習一個單獨的模板沒有限制。神經網路將能夠在其隱藏層中開發中間神經元,可以檢測特定的汽車類型(例如,面向左側的綠色汽車,面向前方的藍色汽車等),下一層的神經元可以將這些組合在一起通過各個汽車探測器的加權總和得到更準確的汽車得分。

(2)理解2-高維空間

線性分類器另一個觀點是回歸到圖像作為點和高維空間的概念,將每張圖片類比為高維空間中單個點(例如CIFAR-10中的每個圖像是3072維空間中32x32×3像素的點),線性分類器在這些線性決策邊界上嘗試畫一個線性分類面來劃分一個類別和剩餘其他類別。

將每個類別的得分定義為所有圖像像素的加權和,因此每個類別得分是該空間上的線性函數。我們無法想像3072維空間,但如果我們想像將所有這些維度壓縮到只有兩個維度,那麼我們可以嘗試可視化分類器可能正在做什麼:

左上角是用來訓練的飛機樣例,通過訓練過程線性分類器會嘗試繪製這條藍色直線來把飛機類別和其他劃分開,訓練過程剛開始時這些線條是極速變化的。其中每個圖像是單個點,並且可視化三個分類器。使用汽車分類器的示例(紅色),紅線上顯示空間中所有汽車類得分為零的點。紅色箭頭顯示增加的方向,因此紅線右側的所有點都具有正(和線性增加)分數,並且左邊的所有點都具有負(並且線性減小)分數。

4.分類失效的數據集

要構造一個使線性分類器失效的數據集並不難,如左邊有兩類數據集,沒有辦法繪製一條單獨的直線來劃分藍色和紅色,這種奇數和偶數而非像素點的劃分問題是線性分類器通過傳統方法難以解決的。另外一種問題是多分類問題,如右邊藍色都出現在三個象限,很難在兩個類別之間繪製一條單獨的線性邊界,所以當有多模態數據時,有一個類別出現在不同領域空間中,線性分類器就很難分開。

5.小總結

本節討論了線性分類器思想和對應的函數形式,怎麼正確選擇權重的策略和演算法會在下節講,這會引出損失函數(量化「好」w的含義)、最優化(從隨機w開始,找一個w來最小化損失)甚、卷積(調整f的函數形式)方面的問題。

2.4 作業1

cs231n.github.io/assign

AI慕課學院視頻講解: mooc.ai/search?


推薦閱讀:

TAG:計算機視覺 | 深度學習DeepLearning | 斯坦福大學StanfordUniversity |