斯坦福深度學習課程筆記(一)
影象分類
1 資料驅動方法
人眼和計算機看到的圖片不同,計算機看到的圖片是由很多代表畫素點的數字表示的陣列,所以人眼和計算機的視覺識別存在著Semantic Gap(語義鴻溝)。
同時,讓計算機能夠有效地識別圖片中的物體之前,還存在很多挑戰:比如
- 一些畫素的簡單偏移或者變化,會使整張圖片有改變;
- 物體所在的環境,如光線,位置會有變化;
- 物體本身有不同的姿態;
- 可能有障礙物遮擋物體;
等等。
以前的硬編碼方式不適合用在物體識別,因為我們很難去為這件事情設定一個死的規則。
我們希望有一個方法,可以有效地識別物體,且對不同情境下的同一物體的識別具有魯棒性,對於不同物體的識別具有可拓展性。
這裡就引出了機器學習的資料驅動方法,該方法首先要收集很多圖片和對應標籤作為資料,然後訓練一個數據分類器,使用該分類器在新的影象集上進行評估。
接下來老師介紹了第一個分類器:Nearest Neighbor
- 該方法的train步驟只是單純地記錄下所有的圖片和標籤。
- 該方法的predict步驟對每個新的影象,找出train中和它最相似的影象,將它的影象標籤賦給新影象。
如何去判定影象的相似呢?這裡介紹曼哈頓距離。將兩個影象中每個畫素點的差異相加,就是兩個點的距離。
class NearestNeighbor:
def __init__(self):
pass
def train(self,X,y):
'''X is N*D where each row in a dimension, y is a one-dimension '''
#the nearesr neighrbor algorithm simply remember all training data
self.X_tr = X
self.y_tr = y
def test(self,X):
'''X is M*D where each row is an example we wish to predict label for'''
num_test = X.shape[0]
Ypred = np.zeros(num_test,dtype = self.y_tr.dtype)
for i in range(num_test):
distances = np.sum(np.abs(self.X_tr-X[i,:]),xis=1)
min_index = np.argmin(distances)
Ypred[i] = self.y_tr[min_index]
return Ypred
Nearest Neighbor訓練時的時間複雜度為,預測的時間複雜度為,這是不好的。因為我們構件模型的目的在於希望它能快速地預測,反而訓練的時間就算長一些也可以接受。
2 KNN演算法
上節描述的NN演算法是尋找與待預測影象最相近的點,但是實際上,最相近的點不一定與待測影象標籤一致;反而是從相鄰的K個點中進行投票,票選出來的標籤會更加魯棒和精確。這種加上投票的演算法叫做KNN。
除了上節提到的曼哈頓距離,還有一種度量向量間距離的方法,歐式距離。
這兩種距離的區別在於,L1距離隨著座標軸的旋轉各點到原點的距離會發生變化,L2則不會。如果輸入的特徵中,有些特徵是具有明顯含義的,使用L1效果可能會好一些。
像剛剛提到的K, distance的選擇,都是超引數(hyperparameters),所謂超引數,就是在訓練模型之前人為選擇的而非訓練得到的引數。超引數非常依賴問題情境,需要不斷地調參來使訓練效果最優。
劃分資料集的有效方法是將資料集分成三份:訓練集、驗證集和測試集。選擇在驗證集上效果最好的超引數,然後在測試集上測試。在訓練時應該不接觸測試集,直到最後測試模型效果的時候才應該去接觸測試集。
還有一種劃分資料集的方法叫做“K-折劃分法”,這種方法一般適用於小資料集,不常在深度學習中使用。它是將訓練集分成幾份,每次選擇一份作為驗證集進行訓練。
實際上,我們不會在圖片域使用KNN進行預測。因為KNN在預測時很慢,而且在畫素點之間的距離度量沒什麼實際意義。
還有一個原因,就是維度災難。
因為KNN並不會在訓練前假設一個分佈函式,所以它需要訓練集的標籤資料較為densely地分佈。但是,隨著維度的提升,獲取densely資料需要的資料量越來越多,這會引發維度災難。
3 線性分類
線性分類(linear classifier)可以說是神經網路中最基本、最簡單的一個元件。
線性分類方法是一種引數方法。
考慮CIFAR-10資料集,共有50,000張訓練影象,每張的維度是;10,000漲測試影象。
考慮一個引數模型,把影象,我們通常稱為作為輸入,就是模型的引數,將和以某種或複雜或簡單的方式組合起來,就得到了我們的引數模型,輸出類別。
將與相乘,是一種直觀和簡單的方法,線性分類器也是這麼做的。
將的圖片拉伸成的向量,輸出是的向量,所以的形狀就是一個的矩陣。這裡我們可以加一個偏執常數向量,表示給每一個類加偏置,比如訓練資料中貓的圖片遠遠多於狗的圖片,那麼貓的偏置值會大一些。
剛剛是從代數的角度解讀線性分類,我們還可以從視覺的角度解讀線性分類。訓練好模型得到後,由於的每一行代表一個類,我們可以將每個類的抽出來,形成模板圖片。通過觀察模板圖片我們可以大概推測出這個學了個什麼東西出來。
或者從幾何學的角度解讀線性分類。我們把每個影象都視為高維空間的一個點,那麼線性分類器就是在高維空間去找一些平面,來分割這些不同的類。
也存在著一些問題是線性分類無法解決的,比如說上圖class1的異或問題,有些情景沒辦法使用線性分割,這就需要我們採用其他的方法去做預測分類。