CS231n課程筆記翻譯:圖像分類筆記(上)

譯者注:本文智能單元首發,譯自斯坦福CS231n課程筆記image classification notes,由課程教師Andrej Karpathy授權進行翻譯。本篇教程由杜客翻譯完成。ShiqingFan對譯文進行了仔細校對,提出了大量修改建議,態度嚴謹,幫助甚多。鞏子嘉對幾處術語使用和翻譯優化也提出了很好的建議。張欣等亦有幫助。

原文如下

這是一篇介紹性教程,面向非計算機視覺領域的同學。教程將向同學們介紹圖像分類問題和數據驅動方法。下面是內容列表

  • 圖像分類、數據驅動方法和流程

  • Nearest Neighbor分類器
    • k-Nearest Neighbor 譯者註:上篇翻譯截止處

  • 驗證集、交叉驗證集和超參數調參

  • Nearest Neighbor的優劣

  • 小結

  • 小結:應用kNN實踐

  • 拓展閱讀

圖像分類

目標:這一節我們將介紹圖像分類問題。所謂圖像分類問題,就是已有固定的分類標籤集合,然後對於輸入的圖像,從分類標籤集合中找出一個分類標籤,最後把分類標籤分配給該輸入圖像。雖然看起來挺簡單的,但這可是計算機視覺領域的核心問題之一,並且有著各種各樣的實際應用。在後面的課程中,我們可以看到計算機視覺領域中很多看似不同的問題(比如物體檢測和分割),都可以被歸結為圖像分類問題。

例子:以下圖為例,圖像分類模型讀取該圖片,並生成該圖片屬於集合 {cat, dog, hat, mug}中各個標籤的概率。需要注意的是,對於計算機來說,圖像是一個由數字組成的巨大的3維數組。在這個例子中,貓的圖像大小是寬248像素,高400像素,有3個顏色通道,分別是紅、綠和藍(簡稱RGB)。如此,該圖像就包含了248X400X3=297600個數字,每個數字都是在範圍0-255之間的整型,其中0表示全黑,255表示全白。我們的任務就是把這些上百萬的數字變成一個簡單的標籤,比如「貓」。

—————————————————————————————————————————

圖像分類的任務,就是對於一個給定的圖像,預測它屬於的那個分類標籤(或者給出屬於一系列不同標籤的可能性)。圖像是3維數組,數組元素是取值範圍從0到255的整數。數組的尺寸是寬度x高度x3,其中這個3代表的是紅、綠和藍3個顏色通道。

—————————————————————————————————————————

困難和挑戰:對於人來說,識別出一個像「貓」一樣視覺概念是簡單至極的,然而從計算機視覺演算法的角度來看就值得深思了。我們在下面列舉了計算機視覺演算法在圖像識別方面遇到的一些困難,要記住圖像是以3維數組來表示的,數組中的元素是亮度值。

  • 視角變化(Viewpoint variation:同一個物體,攝像機可以從多個角度來展現。
  • 大小變化(Scale variation:物體可視的大小通常是會變化的(不僅是在圖片中,在真實世界中大小也是變化的)。
  • 形變(Deformation:很多東西的形狀並非一成不變,會有很大變化。
  • 遮擋(Occlusion:目標物體可能被擋住。有時候只有物體的一小部分(可以小到幾個像素)是可見的。
  • 光照條件(Illumination conditions:在像素層面上,光照的影響非常大。
  • 背景干擾(Background clutter:物體可能混入背景之中,使之難以被辨認。
  • 類內差異(Intra-class variation:一類物體的個體之間的外形差異很大,比如椅子。這一類物體有許多不同的對象,每個都有自己的外形。

面對以上所有變化及其組合,好的圖像分類模型能夠在維持分類結論穩定的同時,保持對類間差異足夠敏感。

—————————————————————————————————————————

—————————————————————————————————————————

數據驅動方法:如何寫一個圖像分類的演算法呢?這和寫個排序演算法可是大不一樣。怎麼寫一個從圖像中認出貓的演算法?搞不清楚。因此,與其在代碼中直接寫明各類物體到底看起來是什麼樣的,倒不如說我們採取的方法和教小孩兒看圖識物類似:給計算機很多數據,然後實現學習演算法,讓計算機學習到每個類的外形。這種方法,就是數據驅動方法。既然該方法的第一步就是收集已經做好分類標註的圖片來作為訓練集,那麼下面就看看資料庫到底長什麼樣:

—————————————————————————————————————————

一個有4個視覺分類的訓練集。在實際中,我們可能有上千的分類,每個分類都有成千上萬的圖像。

—————————————————————————————————————————

圖像分類流程。在課程視頻中已經學習過,圖像分類就是輸入一個元素為像素值的數組,然後給它分配一個分類標籤。完整流程如下:

  • 輸入:輸入是包含N個圖像的集合,每個圖像的標籤是K種分類標籤中的一種。這個集合稱為訓練集。
  • 學習:這一步的任務是使用訓練集來學習每個類到底長什麼樣。一般該步驟叫做訓練分類器或者學習一個模型
  • 評價:讓分類器來預測它未曾見過的圖像的分類標籤,並以此來評價分類器的質量。我們會把分類器預測的標籤和圖像真正的分類標籤對比。毫無疑問,分類器預測的分類標籤和圖像真正的分類標籤如果一致,那就是好事,這樣的情況越多越好。

Nearest Neighbor分類器

作為課程介紹的第一個方法,我們來實現一個Nearest Neighbor分類器。雖然這個分類器和卷積神經網路沒有任何關係,實際中也極少使用,但通過實現它,可以讓讀者對於解決圖像分類問題的方法有個基本的認識。

圖像分類數據集:CIFAR-10。一個非常流行的圖像分類數據集是CIFAR-10。這個數據集包含了60000張32X32的小圖像。每張圖像都有10種分類標籤中的一種。這60000張圖像被分為包含50000張圖像的訓練集和包含10000張圖像的測試集。在下圖中你可以看見10個類的10張隨機圖片。

—————————————————————————————————————————

左邊:從CIFAR-10資料庫來的樣本圖像。右邊:第一列是測試圖像,然後第一列的每個測試圖像右邊是使用Nearest Neighbor演算法,根據像素差異,從訓練集中選出的10張最類似的圖片。

—————————————————————————————————————————

假設現在我們有CIFAR-10的50000張圖片(每種分類5000張)作為訓練集,我們希望將餘下的10000作為測試集並給他們打上標籤。Nearest Neighbor演算法將會拿著測試圖片和訓練集中每一張圖片去比較,然後將它認為最相似的那個訓練集圖片的標籤賦給這張測試圖片。上面右邊的圖片就展示了這樣的結果。請注意上面10個分類中,只有3個是準確的。比如第8行中,馬頭被分類為一個紅色的跑車,原因在於紅色跑車的黑色背景非常強烈,所以這匹馬就被錯誤分類為跑車了。

那麼具體如何比較兩張圖片呢?在本例中,就是比較32x32x3的像素塊。最簡單的方法就是逐個像素比較,最後將差異值全部加起來。換句話說,就是將兩張圖片先轉化為兩個向量I_1I_2,然後計算他們的L1距離:

displaystyle d_1(I_1,I_2)=sum_p|I^p_1-I^p_2|

這裡的求和是針對所有的像素。下面是整個比較流程的圖例:

—————————————————————————————————————————

以圖片中的一個顏色通道為例來進行說明。兩張圖片使用L1距離來進行比較。逐個像素求差值,然後將所有差值加起來得到一個數值。如果兩張圖片一模一樣,那麼L1距離為0,但是如果兩張圖片很是不同,那L1值將會非常大。

—————————————————————————————————————————

下面,讓我們看看如何用代碼來實現這個分類器。首先,我們將CIFAR-10的數據載入到內存中,並分成4個數組:訓練數據和標籤,測試數據和標籤。在下面的代碼中,Xtr(大小是50000x32x32x3)存有訓練集中所有的圖像,Ytr是對應的長度為50000的1維數組,存有圖像對應的分類標籤(從0到9):

Xtr, Ytr, Xte, Yte = load_CIFAR10(data/cifar10/) # a magic function we providen# flatten out all images to be one-dimensionalnXtr_rows = Xtr.reshape(Xtr.shape[0], 32 * 32 * 3) # Xtr_rows becomes 50000 x 3072nXte_rows = Xte.reshape(Xte.shape[0], 32 * 32 * 3) # Xte_rows becomes 10000 x 3072n

現在我們得到所有的圖像數據,並且把他們拉長成為行向量了。接下來展示如何訓練並評價一個分類器:

nn = NearestNeighbor() # create a Nearest Neighbor classifier classnnn.train(Xtr_rows, Ytr) # train the classifier on the training images and labelsnYte_predict = nn.predict(Xte_rows) # predict labels on the test imagesn# and now print the classification accuracy, which is the average numbern# of examples that are correctly predicted (i.e. label matches)nprint accuracy: %f % ( np.mean(Yte_predict == Yte) )n

作為評價標準,我們常常使用準確率,它描述了我們預測正確的得分。請注意以後我們實現的所有分類器都需要有這個API:train(X, y)函數。該函數使用訓練集的數據和標籤來進行訓練。從其內部來看,類應該實現一些關於標籤和標籤如何被預測的模型。這裡還有個predict(X)函數,它的作用是預測輸入的新數據的分類標籤。現在還沒介紹分類器的實現,下面就是使用L1距離的Nearest Neighbor分類器的實現套路:

import numpy as npnnclass NearestNeighbor(object):n def __init__(self):n passnn def train(self, X, y):n """ X is N x D where each row is an example. Y is 1-dimension of size N """n # the nearest neighbor classifier simply remembers all the training datan self.Xtr = Xn self.ytr = ynn def predict(self, X):n """ X is N x D where each row is an example we wish to predict label for """n num_test = X.shape[0]n # lets make sure that the output type matches the input typen Ypred = np.zeros(num_test, dtype = self.ytr.dtype)nn # loop over all test rowsn for i in xrange(num_test):n # find the nearest training image to the ith test imagen # using the L1 distance (sum of absolute value differences)n distances = np.sum(np.abs(self.Xtr - X[i,:]), axis = 1)n min_index = np.argmin(distances) # get the index with smallest distancen Ypred[i] = self.ytr[min_index] # predict the label of the nearest examplenn return Ypredn

如果你用這段代碼跑CIFAR-10,你會發現準確率能達到38.6%。這比隨機猜測的10%要好,但是比人類識別的水平(據研究推測是94%)和卷積神經網路能達到的95%還是差多了。點擊查看基於CIFAR-10數據的Kaggle演算法競賽排行榜。

距離選擇:計算向量間的距離有很多種方法,另一個常用的方法是L2距離,從幾何學的角度,可以理解為它在計算兩個向量間的歐式距離。L2距離的公式如下:

displaystyle d_2(I_1,I_2)=sqrt{ sum_p(I^p_1-I^p_2)^2}

換句話說,我們依舊是在計算像素間的差值,只是先求其平方,然後把這些平方全部加起來,最後對這個和開方。在Numpy中,我們只需要替換上面代碼中的1行代碼就行:

distances = np.sqrt(np.sum(np.square(self.Xtr - X[i,:]), axis = 1))n

注意在這裡使用了np.sqrt,但是在實際中可能不用。因為求平方根函數是一個單調函數,它對不同距離的絕對值求平方根雖然改變了數值大小,但依然保持了不同距離大小的順序。所以用不用它,都能夠對像素差異的大小進行正確比較。如果你在CIFAR-10上面跑這個模型,正確率是35.4%,比剛才低了一點。

L1和L2比較。比較這兩個度量方式是挺有意思的。在面對兩個向量之間的差異時,L2比L1更加不能容忍這些差異。也就是說,相對於1個巨大的差異,L2距離更傾向於接受多個中等程度的差異。L1和L2都是在p-norm常用的特殊形式。

k-Nearest Neighbor分類器

你可能注意到了,為什麼只用最相似的1張圖片的標籤來作為測試圖像的標籤呢?這不是很奇怪嗎!是的,使用k-Nearest Neighbor分類器就能做得更好。它的思想很簡單:與其只找最相近的那1個圖片的標籤,我們找最相似的k個圖片的標籤,然後讓他們針對測試圖片進行投票,最後把票數最高的標籤作為對測試圖片的預測。所以當k=1的時候,k-Nearest Neighbor分類器就是Nearest Neighbor分類器。從直觀感受上就可以看到,更高的k值可以讓分類的效果更平滑,使得分類器對於異常值更有抵抗力。

—————————————————————————————————————————

上面示例展示了Nearest Neighbor分類器和5-Nearest Neighbor分類器的區別。例子使用了2維的點來表示,分成3類(紅、藍和綠)。不同顏色區域代表的是使用L2距離的分類器的決策邊界。白色的區域是分類模糊的例子(即圖像與兩個以上的分類標籤綁定)。需要注意的是,在NN分類器中,異常的數據點(比如:在藍色區域中的綠點)製造出一個不正確預測的孤島。5-NN分類器將這些不規則都平滑了,使得它針對測試數據的泛化(generalization能力更好(例子中未展示)。注意,5-NN中也存在一些灰色區域,這些區域是因為近鄰標籤的最高票數相同導致的(比如:2個鄰居是紅色,2個鄰居是藍色,還有1個是綠色)。

—————————————————————————————————————————

在實際中,大多使用k-NN分類器。但是k值如何確定呢?接下來就討論這個問題。

圖像分類筆記(上)完。

點擊查看圖像分類筆記(下)。

譯者反饋

  1. 因CS231n的單篇課程筆記長度長,完整閱讀需較長時間。知友張欣等建議對其進行適當分拆。故本次翻譯將圖像分類筆記拆分為上下篇,每篇閱讀量控制在1萬字左右,降低閱讀成本。效果如何,請知友們點評;
  2. 知乎專欄的公式編輯器可以使用LaTeX語法,贊。但公式居中需手動空格,有無更優雅的方式?請知友們評論指教;
  3. 翻譯中的任何不足之處,請知友們在評論中批評指正,我們會及時討論並作出反饋;
  4. 本翻譯是無償行為,知乎專欄首發。允許轉載,請全文保留並註明出處。

推薦閱讀:

車輛3D檢測:Deep MANTA論文閱讀筆記
AI為人民服務:視覺缺陷檢測
1.11【OpenCV圖像處理】形態學操作
視覺演算法研發工程師/嵌入式AI全棧(實習/全棧)(20K-40K/月)
Neural Artistic Style

TAG:机器学习 | 计算机视觉 | 斯坦福大学StanfordUniversity |