Python線性分類模型簡介

bound發表於2017-09-01

在過去幾週中,我們開始對機器學習有了更多的瞭解,也認識到機器學習在機器視覺、影像分類和深度學習領域的重要作用。

我們已經看到卷積神經網路,如LetNet,可以用於對MNIST資料集的手寫字跡進行分類。我們使用了k-NN演算法來識別一張圖片中是否含有貓或狗,並且我們也已經學習瞭如何調參來優化模型,進而提高分類精度。

然而,還有一個重要的機器學習的演算法我們尚未涉及:這個演算法非常容易構建,並能很自然地擴充套件到神經網路和卷積神經網路中。

是什麼演算法呢?

它是一個簡單的線性分類器,並且由於其演算法很直觀,被認為是更多高階的機器學習和深度學習演算法的基石。

繼續閱讀來加深你對線性分類器的認識,以及如何使用它們進行影像分類。


Python線性分類模型簡介

本教程的前半部分主要關注線性分類有關的基本原理和數學知識。總的來說,線性分類指的是那些真正從訓練資料中“學習”的有參分類演算法。

在這裡,我提供了一個真正的線性分類實現程式碼,以及一個用scikit-learn對一張圖片中的內容分類的例子。

4大引數化學習和線性分類的元件

我已經多次使用“引數化”,但它到底是什麼意思?

簡而言之:引數化是確定模型必要引數的過程。

在機器學習的任務中,引數化根據以下幾個方面來確定面對的問題:

  1. 資料:這是我們將要學習的輸入資料。這些資料包括了資料點(例如,特徵向量,顏色矩陣,原始畫素特徵等)和它們對應的標籤。
  2. 評分函式:一個函式接收輸入資料,然後將資料匹配到類標籤上。例如,我們輸入特徵向量後,評分函式就開始處理這些資料,呼叫某個函式f(比如我們的評分函式),最後返回預測的分類標籤。
  3. 損失函式:損失函式可以量化預測的類標籤與真實的類標籤之間的匹配程度。這兩個標籤集合之間的相似度越高,損失就越小(即分類精度越高)。我們的目標是最小化損失函式,相應就能提高分類精度。
  4. 權重矩陣:權重矩陣,通常標記為W,它是分類器實際優化的權重或引數。我們根據評分函式的輸出以及損失函式,調整並優化權重矩陣,提高分類精度。

注意:取決於你使用的模型的種類,引數可能會多的多。但是在最底層,你會經常遇到4個引數化學習的基本模組。

一旦確定了這4個關鍵元件,我們就可以使用優化方法來找到評分函式的一組引數W,使得損失函式達到最小值(同時提升對資料的分類準確度)

接下來,我們就將看到如何利用這些元件,搭建一個將輸入資料轉化為真實預測值的分類器。

線性分類器:從圖片到標籤

在這部分中,我們將更多的從數學角度研究引數模型到機器學習。

首先,我們需要資料。假設訓練資料集(圖片或者壓縮後的特徵向量)標記為Python線性分類模型簡介 ,每個圖或特徵向量都有對應的類標籤 y_{i}。我們用 i = 1 ldots N 和y_{i}= 1 ldots K表示有N個D維(特徵向量的長度)的資料點,劃分到K個唯一的類別中。

為了這些表示式更具體點,參考我們以前的教程:基於提取後的顏色矩陣,使用knn分類器識別圖片中的貓和狗。

這份資料集中,總共有N=25,000張圖片,每張圖片的特徵都是一個3D顏色直方圖,其中每個管道有8個桶。這樣產出的特徵向量有D=8 x 8 x 8 = 512個元素。最後,我們有k=2個類別標籤,一個是“狗”,另一個是“貓”。

f(x_{i}, W, b) = Wx_{i} + b

有了這些變數後,我們必須定義一個評分函式f,將特徵向量對映到類標籤的打分上。正如本篇部落格標題所說,我們將使用一個簡單的線性對映:

f(x_{i}, W, b) = Wx_{i} + b

我們假設每個 x_{i}都由一個形狀為[D x 1]的單列向量所表示。我們在本例中要再次使用顏色直方圖,不過如果我們使用的是原始畫素粒度,那可以直接把圖片中的畫素壓扁到一個單列向量中。

我們的權重矩陣W形狀為[K x D](類別標籤數乘以特徵向量的維數)

最後,偏置矩陣b,大小為[K x 1]。實質上,偏置矩陣可以讓我們的評分函式向著一個或另一個方向“提升”,而不會真正影響權重矩陣W,這點往往對學習的成功與否非常關鍵。

回到Kaggle的貓和狗例子中, 每個都表示為512維顏色直方圖,因此的形狀是[512 x 1]。權重矩陣W的形狀為[2 x 512],而偏置矩陣b為[2 x 1]

下面展示的是線性分類的評分函式f

Figure 1: Illustrating the dot product of weight matrix W and feature vector x, followed by addition of bias term. (Inspired by Karpathy's example in the CS231n course).

在上圖的左側是原始輸入圖片,我們將從中提取特徵。在本例中,我們計算的是一個512維的顏色直方圖,也可以用其他一些特徵表示方式(包括原始畫素密度),但是對於這個例子,我們就只用顏色分佈,即直方圖來表示xi。

然後我們有了權重矩陣W,有2行(每個類標籤一行)和512列(每一列都是特徵向量中的條目)

將W和xi點乘後,再加上大小為[2 x 1]的偏置矩陣bi。

最後就得到了右邊的兩個值:貓和狗標籤各自的分數。

看著上面的公式,你可以確信輸入xi和yi都是固定的,沒法修改。我們當然可以通過不同的特徵提取技術來得到不同的xi,但是一旦特徵抽取後,這些值就不會再改變了。

實際上,我們唯一能控制的引數就是權重矩陣W以及偏置向量b。因此,我們的目標是利用評分函式和損失函式去優化權重和偏置向量,來提升分類的準確度。

如何優化權重矩陣則取決於我們的損失函式,但通常會涉及梯度下降的某種形式。我們會在以後的部落格中重溫優化和損失函式的概念,不過現在只要簡單理解為給定了一個評分函式後,我們還需要定義一個損失函式,來告訴我們對於輸入資料的預測有多“好”。

引數學習和線性分類的優點

利用引數學習有兩個主要的優點,正如我上面詳述的方法:

  1. 一旦我們訓練完了模型,就可以丟掉輸入資料而只保留權重矩陣W和偏置向量b。這大大減少了模型的大小,因為我們只需要儲存兩個向量集合(而非整個訓練集)。
  2. 對新的測試資料分類很快。為了執行分類,我們要做的只是點乘W和xi,然後再加上偏置b。這樣做遠比將每個測試點和整個訓練集比較(比如像knn演算法那樣)快的多。

既然我們理解了線性分類的原理,就一起看下如何在python,opencv和scikit-learn中實現。

使用python,opencv和scikit-learn對圖片線性分類

就像在之前的例子Kaggle 貓vs狗資料集和knn演算法中,我們將從資料集中提取顏色直方圖,不過和前面例子不同的是,我們將用一個線性分類器,而非knn。

準確地說,我們將使用線性支援向量機(SVM),即在n維空間中的資料之間構造一個最大間隔分離超平面。這個分離超平面的目標是將類別為i的所有(或者在給定的容忍度下,儘可能多)的樣本分到超平面的一邊,而所有類別非i的樣本分到另一邊。

關於支援向量機的具體描述已經超出本部落格的範圍。(不過在PyImageSearch Gurus course有詳細描述)

同時,只需知道我們的線性SVM使用了和本部落格“線性分類器:從圖片到標籤”部分中相似的評分函式,然後使用損失函式,用於確定最大分離超平面來對資料點分類(同樣,我們將在以後的部落格中講述損失函式)。

我們從開啟一個新檔案開始,命名為linear_classifier.py,然後插入以下程式碼:

從第2行至11行匯入了必須的python包。我們要使用scikit-learn庫,因此如果你還沒安裝的話,跟著這些步驟,確保將其安裝到你機器上。

我們還將使用我的imutils包,用於方便處理影像的一系列函式。如果你還沒有安裝imutils,那就讓pip安裝。

現在我們定義extract_color_histogram 函式,用於提取和量化輸入圖片的內容:

這個函式接收一個輸入image ,將其轉化為HSV顏色空間,然後利用為每個通道提供的bins,計算3D顏色直方圖。

利用cv2.calcHist函式計算出顏色直方圖後,將其歸一化後返回給呼叫函式。

有關extract_color_histogram方法更詳細的描述,參閱這篇部落格

接著,我們從命令列解析引數,並初始化幾個變數:

33行到36行解析命令列引數。我們這裡只需要一個簡單的開關,dataset是kaggle 貓vs狗資料集的路徑。

然後我們將25000張圖片儲存的磁碟位置賦值給imagePaths,跟著初始化一個data矩陣,儲存提取後的特徵向量和類別labels。

說到提取特徵,我們接著這樣做:

打賞支援我翻譯更多好文章,謝謝!

打賞譯者

打賞支援我翻譯更多好文章,謝謝!

Python線性分類模型簡介

相關文章