CS231n章節一:圖像分類

關於本項目的聲明請點CS231翻譯及筆記項目目錄,在此不再重述。
-------------------------------------------------——--------------------------------------------------------------------

Convolutional Neural Networks for Visual Recognition——視覺識別的卷積神經網絡方法

目錄

第一部分:神經網絡

1.1-圖像分類:數據驅動方法,k近鄰法,訓練集/數值/文本 分類
1.2-線性分類器:支持向量機,分類器???
1.3-最優化:隨機梯度下降法
1.4-反向傳播,直覺???
1.5-神經網絡1:建立架構
1.6-神經網絡2:建立數據和損失???
1.7-神經網絡3:學習和預測
1.8-將上述結合在一起:最簡版神經網絡學習實例

第二部分:卷積神經網絡

2.1-卷積神經網絡:架構,卷積&採樣層
2.2-可理解的和可視化的卷積神經網絡???
2.3-遷移學習和微調神經網絡
2.4-迴旋網技巧和訣竅:擠出最後幾個百分點???

第X部分:準備

x.1-Python Numpy包使用指南
x.2-IPython指南
x.3-結束

—————————————————————————————————————————
這是一門介紹性課程,旨在引導人們進入計算機視覺的圖像分類問題以及數據驅動方法中來。課程的課表如下:

  • 介紹圖像分類,數據驅動方法,線程???
  • 最近鄰分類-------------k-近鄰
  • 校驗集,交叉驗證,調超參
  • 最近鄰的利弊
  • 總結
  • 總結:knn實戰
  • 閱讀參考

圖像分類

動機:在本節中,我們將介紹圖像分類問題,即從一些固定的類別中爲輸入圖像分配一個標籤。這是計算機視覺領域的核心問題之一,儘管它很單一,但有着大量的實際應用。此外,正如我們在後面課程會看到的,一些表面上看來獨特的計算機視覺問題(比如目標識別,目標分割)都可以簡化爲圖像分類問題。

例子:例如,下圖是一個圖像分類模型,它將取一張圖像並將其可能性分給四個標籤,{貓,狗,帽子,杯子}。請記住,如圖所示,對於計算機來說,圖像是由一個大的三位數組組成的。在這個例子中,這幅貓的圖像有248像素寬,400像素高,而且含有三個通道的顏色:紅色,綠色和藍色(或者簡短的說成RGB)。因此,這幅圖由2484003,總共297,600個數字組成。每個數字都是一個在0(黑色)-255(白)之間的整數。我們的任務就是將這百萬的四分之一的數字歸爲一個標籤,例如“貓”。
在這裏插入圖片描述
圖像分類的工作就是爲給定圖像預測單一的標籤(或者標籤的分佈,如上圖所示來表明我們的置信度)。圖像是一個取值爲0-255的三維整數數組,大小爲寬x高x3。這個3代表紅綠藍三個顏色通道。
挑戰:儘管識別視覺概念(例如貓)的任務對於人類來說是微不足道的,但是從計算機視覺算法的角度來看確是一個值得考慮的挑戰。當我們在下面提出(一個不詳盡的)挑戰列表時,請記住圖像的原始表示是一個三維亮度值數組:

  • 視角變化:一個物體可以以很多不同的方向來面向相機
  • 大小變化:視類經常在大小上出現變化(在現實世界中的大小,不僅僅是圖像中的)
  • 變形:很多我們感興趣的對象並不是嚴格死板的身形,它們可以極大程度的扭曲。
  • 包藏:感興趣的對象可以被包藏。有時僅有一小部分的物體(甚至小到只有幾個像素)可以被看到。
  • 光照條件:光照對圖像在像素級別的影響是非常嚴重的。
  • 背景雜波:感興趣的對象可能融入它們的環境,使它們難以識別。
  • 類內部變異:感興趣的類可能非常廣泛,例如椅子。這類對象有很多不同的類型,每一種都有自己的外觀。
    一個好的圖像分類模型必須對這些變化的綜合影響保持穩定,同時要對類內的變化保持敏感。
    在這裏插入圖片描述
    數據驅動方法:我們該如何寫一個可以將圖像分爲不同類別的算法呢?與編寫一個排序算法不同,我們不明確知道如何寫一個用於識別圖像中貓的算法。因此,與其在代碼中將感興趣對象的特徵列舉出來,我們使用的方法不會像你帶着一個小孩一樣:我們會提供給計算機每個類別的很多例子,以這些例子爲基礎,瞭解每個類的外觀,進而開發算法。這種方法被稱爲數據驅動方法,因爲它依賴於一開始積累的標籤訓練數據集,下面就是這樣一個數據集的例子:
    在這裏插入圖片描述
    在這裏插入圖片描述
    (四種視覺類別的訓練集,在實踐中,我們可能有上千個類別,每個類別可能有成千上萬幅圖像)
    圖像分類流程:我們可以看到圖像分類就是將一幅圖像用像素數組表示併爲其分配一個標籤。我們完整的流程可以總結???如下:
  • 輸入:我們的輸入包含N個圖像,每個圖像都被標記爲K個類別之一。
  • 學習:我們的任務是用訓練集來學習每個類別的樣子???。我們稱這個步驟爲訓練分類器,或者學習一個模型。
  • 評估:最後,我們通過讓分類器預測一組從未見過的新圖像的標籤來評估分類器的性能。然後我們會比較這些圖像的真實標籤與分類器預測的標籤,顯然,我們希望大部分預測結果和真實結果(基礎事實)是匹配的。

最近鄰分類器

作爲我們的第一個方法,我們將介紹???一個名叫最近鄰分類器的算法。這個分類器和卷積神經網絡無關且在實踐中很少用到,但它可以讓我們瞭解圖像分類的基本方法。
示例圖像分類數據集:CIFAR-10。一個流行的玩具圖像分類數據集是CIFAR-10數據集。這個數據集包含六萬張32像素寬和高的小圖像。每幅圖像都被標記爲10個類別之一(例如“飛機”,“汽車”。“鳥”等)。這六萬張圖像有五萬張被分作訓練集和一萬張被分爲測試集。在下面的圖片中,你可以看到來自10個類的各10張隨機示例圖片:
在這裏插入圖片描述
假設我們現在給 CIFAR-10 訓練集五萬張圖像(每個類別有五千張),並希望給剩餘的一萬張進行歸類。最近鄰分類器將會把測試圖像與訓練集的每一張圖像進行對比,並將最近的訓練集圖像的標籤作爲預測結果。在上面圖片的右側你可以看到10幅示例圖像的測試結果。注意,只有3幅圖像檢索到了同一類型的圖像,其他7幅卻並非如此。例如,在第8行中,訓練集中最接近馬頭圖像的是一幅紅色汽車,這大概是因爲其深黑色的背景。因此,這幅馬的圖像就被誤分爲汽車類了。
你可能注意到我們沒有詳細說明如何比較兩幅圖像,在本例中僅僅是兩個32323大小的方塊兒。最簡單的方法是逐像素的比較並將所以的差異相加。換句話說,給定兩個圖像並將它們看作向量I1 , I2,比較兩者的合理選擇就是L1距離???:
在這裏插入圖片描述
這裏的和考慮了所以的像素,下面是可視化的過程:
在這裏插入圖片描述
一個使用像素間差異來比較兩幅圖像的L1距離的例子(例子中爲單通道)。兩幅圖像的元素值相減,然後將所以的差異相加的一數值。如果兩幅圖像完全一樣,那得到的結果就是零,但是如果兩幅圖像差異特別大,那結果也會非常大。
在這裏插入圖片描述
讓我們看看如何用代碼實現分類器。首先,我們下載CIFAR-10數據集並分爲4部分:訓練數據集/標籤,和測試數據集/標籤。在下面代碼中,Xtr(大小爲50,0003232*3)包含了訓練集中的所有圖像,還有一個相應的一維數組Ytr(長度爲50,000)包含了訓練集的標籤(標籤爲0-9):

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

現在我們將所以的圖像拉伸成行,下面讓我們看看如何訓練和評估一個分類器吧。

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

注意,以預測部分的正確率爲評估標準是非常普遍的。???這裏,我們構建的所有分類器有一個共同的API:他們都有一個獲取訓練數據和標籤的函數train(X,y),在分類器內部???,應該建立某種根據數據來預測標籤的模型。然後後面是**predict(X)**函數,功能是獲取新數據並預測其標籤。當然,我們忽略了最本質的東西——分類器本身。下面是一個基於L1距離的最近鄰分類器的簡單實現,它滿足上述模板:

import numpy as np
class NearestNeighbor:
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
# the nearest neighbor classifier simply remembers all the training da
self.Xtr = X
self.ytr = y
def predict(self, X):
""" X is N x D where each row is an example we wish to predict label f
num_test = X.shape[0]
# lets make sure that the output type matches the input type
Ypred = np.zeros(num_test, dtype = self.ytr.dtype)
# loop over all test rows
for i in xrange(num_test):
# find the nearest training image to the i'th 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 dista
Ypred[i] = self.ytr[min_index] # predict the label of the nearest ex
return Ypred

如果你運行這段代碼,你會發現這個分類器對於CIFAR-10的正確率僅達到38.6%。這比瞎猜(當有10個類別時猜中的概率只有10%)要好些,但遠不及人類性能???(估計在94%左右)或者先進的卷積神經網絡來實現匹配人臉的95%的精確度(見CIFAR-10上最近的Kaggle競賽的排行榜)。
距離度量的選擇:向量之間的距離計算有很多方式。另一常見的可選的爲L2距離,它的幾何解釋是計算兩個向量之間的歐式距離,距離計算爲:
在這裏插入圖片描述
換句話說,我們將想以前那樣計算像素級的差異,但是這次我們將所有元素開方,相加,並計算平方根,在numpy中,只需要替換上面的一行代碼。計算距離的這行代碼:

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

注意我在上面包含了np包。但是實際最近鄰算法應用中我們可以忽略開平方根運算因爲平方根是單調函數。也就是說它縮放了距離的絕對大小但保留了距離的順序,所以有沒有開平方根的最近鄰算法是一樣的。如果你用這個距離對 CIFAR-10數據集來運行這個最近鄰分類器,你將獲得35.4%的準確率(略低於我們的L1距離結果)。
L1 vs L2:比較兩種距離的差異是非常有趣的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章