1. 程式人生 > >SVM原理以及Tensorflow 實現SVM分類(附程式碼)

SVM原理以及Tensorflow 實現SVM分類(附程式碼)

1.1. SVM介紹

SVM(Support Vector Machines)——支援向量機是在所有知名的資料探勘演算法中最健壯,最準確的方法之一,它屬於二分類演算法,可以支援線性和非線性的分類。發展到今天,SVM已經可以支援多分類了,但在這一章裡,我們著重講支援向量機在二分類問題中的工作原理。
假設在一個二維線性可分的資料集中,圖一A所示,我們要找到一個超平面把兩組資料分開,這時,我們認為線性迴歸的直線或邏輯迴歸的直線也能夠做這個分類,這條直線可以是圖一B中的直線,也可以是圖一C中的直線,或者圖一D中的直線,但哪條直線才最好呢,也就是說哪條直線能夠達到最好的泛化能力呢?那就是一個能使兩類之間的空間大小最大的一個超平面。
這個超平面在二維平面上看到的就是一條直線,在三維空間中就是一個平面...,因此,我們把這個劃分資料的決策邊界統稱為超平面。離這個超平面最近的點就叫做支援向量,點到超平面的距離叫間隔。支援向量機就是要使超平面和支援向量之間的間隔儘可能的大,這樣超平面才可以將兩類樣本準確的分開,而保證間隔儘可能的大就是保證我們的分類器誤差儘可能的小,儘可能的健壯。
2017-09-07-13-58-24


圖一

1.2. 工作原理

1.2.1. 幾何間隔和函式間隔

在最大化支援向量到超平面距離前,我們首先要定義我們的超平面\(h({{x}})\)(稱為超平面的判別函式,也稱給定\({w}\)\({b}\)的泛函間隔),其中\({w}\)為權重向量,\({b}\)為偏移向量:
\[h({{x}})={w}^T{x}+{b}\]
樣本\({x}\)到最優超平面的幾何間隔為:
\[r=\frac{h({x})}{||{w}||}=\frac{{w}^T{x}+{b}}{||{w}||}\]
\(||{w}||\)是向量\({w}\)的內積,是個常數,即\(||{w}||=\sqrt{{w_{_0}}^2+{w_{_1}}^2+...+{w_{_n}}^2}\)

,而\(h({{x}})\)就是下面要介紹的函式間隔。

函式間隔
\[\widehat{r}=h({{x}})\]
函式間隔\(h({x})\)它是一個並不標準的間隔度量,是人為定義的,它不適合用來做最大化的間隔值,因為,一旦超平面固定以後,如果我們人為的放大或縮小\({w}\)\({b}\)值,那這個超平面也會無限的放大或縮小,這將對分類造成嚴重影響。而幾何間隔是函式間隔除以\(||{w}||\),當\({w}\)的值無限放大或縮小時,\(||{w}||\)也會放大或縮小,而整個\(r\)保持不變,它只隨著超平面的變動而變動,不受兩個引數的影響。因而,我們用幾何間隔來做最大化間隔度量。

1.2.2. 最大化間隔

在支援向量機中,我們把幾何間隔\({r}\)作為最大化間隔進行分析,並且採用-1和1作為類別標籤,什麼採用-1和+1,而不是0和1呢?這是由於-1和+1僅僅相差一個符號,方便數學上的處理。我們可以通過一個統一公式來表示間隔或者資料點到分隔超平面的距離,同時不必擔心資料到底是屬於-1還是+1類。
我們一步一步的進行分析,首先如下圖,在這個\(\mathbb{R}^2\)空間中,假設我們已經確定了一個超平面,這個超平面的函式關係式應該是\(h({{x}})={w}^T{x}+{b}=0\),這個式子表示我們圖中的那條虛線,很明顯,這個式子意思是說點x在超平面上,但我們要想使所有的點都儘可能的遠離這個超平面,我們只要保證離這個超平面最近的點遠離這個超平面,也就是說這些叫支援向量的點\(x^*\)需要儘可能的遠離它。

2017-09-08-10-26-04

我們把其中一個支援向量\(x^*\)到最優超平面的距離定義為:
\[r^*={\frac{h({x}^*)}{||{w}||}}= \left\{\begin{matrix} {\frac{1}{||{w}||}} & if:y^*=h({x}^*)=+1 \\ & \\ {-\frac{1}{||{w}||}} & if:y^*=h({x}^*)=-1 \end{matrix}\right.\]

這是我們通過把函式間隔\(h({x})\)固定為1而得來的。我們可以把這個式子想象成還存在兩個平面,這兩個平面分別是\({w}^T{x}_{_s}+{b}=1\)\({w}^T{x}_{_s}+{b}=-1\),對應上圖中的兩根實線。這些支援向量\({x}_{_s}\)就在這兩個平面上,這兩個平面離最優超平面的距離越大,我們的間隔也就越大。對於其他的點\({x}_{_i}\)如果滿足\({w}^T{x}_{_i}+{b}>1\),則被分為1類,如果滿足滿足\({w}^T{x}_{_i}+{b}<-1\),則被分為-1類。即有約束條件:
\[\left\{\begin{matrix} {{w}^T{x_{_i}}+{b}}\geqslant 1 & y_{_i}=+1 \\ & \\ {{w}^T{x{_i}}+{b}} \leqslant -1& y_{_i}=-1 \end{matrix}\right.\]

支援向量到超平面的距離知道後,那麼分離的間隔\(\rho\)很明顯就為:
\[\rho=2r^*=\frac{2}{||{w}||} \]
這下我們就要通過找到最優的\({w}\)\({b}\)來最大化\(\rho\)了,感覺又像回到了邏輯迴歸或線性迴歸的例子。但是這裡,我們最大化\(\rho\)值需要有條件限制,即:
\[\begin{cases} & \max \limits_{{w},{b}} {\frac{2}{||{w}||}} \\ & \\ & {y_{_i}}({w}^T{x_{_i}}+{b}) \geqslant 1, \ (i=1,..,n) \end{cases}\]
\({y_{_i}}({w}^T{x_{_i}}+{b})\)的意思是通過判斷\({y_{_i}}\)\({w}^T{x_{_i}}+{b}\)是否同號來確定分類結果。
接著,為了計算方便,我們把上式最大化\(\rho\)換成:
\[\begin{cases} & \min \limits_{{w},{b}} {\frac{1}{2}}||{w}||^2 \\ & \\ & {y_{_i}}({w}^T{x_{_i}}+{b}) \geqslant 1, \ (i=1,..,n) \end{cases}\]

這種式子通常我們用拉格朗日乘數法來求解,即:
\[L({x})=f({x})+\sum\alpha g({x})\]
\(f({x})\)是我們需要最小化的目標函式,\(g({x})\)是不等式約束條件,即前面的\({y_{_i}}({w}^T{x_{_i}}+{b}) \geqslant 1\)\(\alpha\)是對應的約束係數,也叫拉格朗日乘子。為了使得拉格朗日函式得到最優化解,我們需要加入能使該函式有最優化解法的KKT條件,或者叫最優化條件、充要條件。即假設存在一點\({x}^*\)

1.2.2.0.0.1. \(L({x}^*)\)\({x}^*\)求導為0
1.2.2.0.0.2. \(\alpha_{_i} g_{_i}({x}^*)=0\),對於所有的\(i=1,.....,n\)

這樣構建我們的拉格朗日函式為:
\[L({w},{b},\alpha)=\frac{1}{2}{w}^T{w}-\sum_{i=1}^{n}\alpha_{_i}[y_{_i}({w}^T{x_{_i}}+{b})-1]\]
以上的KKT條件\(\alpha_{_i}[y_{_i}({w}^T{x_{_i}}+{b})-1]=0\)表示,只有距離最優超平面的支援向量\((x_i,y_i)\)對應的\(\alpha\)非零,其他所有點集的\(\alpha\)等於零。綜上所述,引入拉格朗日乘子以後,我們的目標變為:
\[\min_{{w},{b}}\max_{\alpha\geqslant 0 }L({w},{b},\alpha)\]
即先求得\(\alpha\)的極大值,再求\({w}\)\({b}\)的極小值。可以把該問題轉為為等價的凸優化和對偶問題來求解,對於凸優化和對偶問題可以參考《凸優化》這本書,因為該理論可以整整用一本書來介紹了,筆者在這裡也只能點到為止了。通過對偶,我們的目標可以又變成:
\[\max_{\alpha\geqslant 0}\min_{{w},{b}}L({w},{b},\alpha)\]
即先求得\({w}\)\({b}\)的極小值,在求\(\alpha\)的極大值。用\(L({w},{b},\alpha)\)\({w}\)\({b}\)分別求偏導,並令其等於0:
\[\begin{cases} & \frac{\partial L({w},{b},\alpha )}{\partial {w}} =0\\ & \ \\ & \frac{\partial L({w},{b},\alpha )}{\partial {b}}=0 \end{cases}\]
得:
\[\begin{cases} & {w}=\sum_{i=1}^{n}\alpha{_i}y_{_i}x_{_i} \\ & \ \\ & \sum_{i=1}^{n}\alpha{_i}y_{_i}=0 \end{cases}\]
把該式代入原來的的拉格朗日式子可得(推導過程省略):
\[W(\alpha)=\sum_{i=1}^{n}\alpha{_i}-\frac{1}{2}\sum_{i=1}^{n}\sum_{j=1}^{n}\alpha{_i}\alpha{_j}y_{_i}y_{_j}{x_{_i}}^Tx_{_j} \]
\[ \sum_{i=1}^{n}\alpha{_i}y_{_i}=0 \ , \alpha_{_i}\geqslant 0 (i=1,...,n)\]
\(W(\alpha)\)函式消去了向量\({w}\)和向量\({b}\),僅剩\(\alpha\)這個未知引數,只要我們能夠最大化\(W(\alpha)\),就能求出對應的\(\alpha\),進而求得\({w}\)\({b}\)。對於如何求解\(\alpha\),SMO演算法給出了完美的解決方案,下一節我們詳細講述。這裡我們假設通過SMO演算法確定了最優\(\alpha^*\),則
\[{w}^*=\sum_{i=1}^{n}\alpha{_i}^*y_{_i}x_{_i}\]
最後使用一個正的支援向量\({x}_{_s}\),就可以計算出\({b}\)
\[{b}^*=1-{{w}^*}^T {x}_{_s}\]

1.3. 軟間隔

在4.2節中我們推導瞭如何計算\({w}\)\({b}\)\({\alpha}\),但別忘了以上所有的推導都是線上性可分的條件下進行的,但是現實世界的許多問題並不都是線性可分的,尤其存在許多複雜的非線性可分的情形。如果樣本不能被完全線性分開,那麼情況就是:間隔為負,原問題的可行域為空,對偶問題的目標函式無限,這講導致相應的最優化問題不可解。
要解決這些不可分問題,一般有兩種方法。第一種是放寬過於嚴格的間隔,構造軟間隔。另一種是運用核函式把這些資料對映到另一個維度空間去解決非線性問題。在本節中,我們首先介紹軟間隔優化。
假設兩個類有幾個資料點混在一起,這些點對最優超平面形成了噪聲干擾,軟間隔就是要擴充套件一下我們的目標函式和KKT條件,允許少量這樣的噪聲存在。具體地說,就要引入鬆馳變數\(\xi_{_i}\)來量化分類器的違規行為:
\[\begin{cases} & \min \limits_{{w},{b}} {\frac{1}{2}}||{w}||^2 +C\sum_{i=1}^{n} {\xi_{_i}} & \\ & \\ & {y_{_i}}({w}^T{x_{_i}}+{b}) \geqslant 1-\xi_{_i} & ,\xi_{_i}\geqslant0, & (i=1,..,n) \end{cases}\]
引數C用來平衡機器的複雜度和不可分資料點的數量,它可被視為一個由使用者依據經驗或分析選定的“正則化”引數。鬆馳變數\(\xi_{_i}\)的一個直接的幾何解釋是一個錯分例項到超平面的距離,這個距離度量的是錯分例項相對於理想的可分模式的偏差程度。對上式的化解,可得:
\[W(\alpha)=\sum_{i=1}^{n}\alpha{_i}-\frac{1}{2}\sum_{i=1}^{n}\sum_{j=1}^{n}\alpha{_i}\alpha{_j}y_{_i}y_{_j}{x_{_i}}^Tx_{_j} \]

\[\sum_{i=1}^{n}\alpha{_i}y_{_i}=0, 0\leqslant \alpha_{_i}\leqslant C (i=1,...,n)\]
可以看到,鬆馳變數\(\xi_{_i}\)沒有出現在\(W(\alpha)\)中,線性可分與不可分的差異體現在約束\(\alpha_{_i}\geqslant 0\)被替換成了約束\(0\leqslant \alpha_{_i}\leqslant C\)。但是,這兩種情況下求解\({w}\)\({b}\)是非常相似的,對於支援向量的定義也都是一致的。
在不可分情況下,對應的KKT條件為:
\[\alpha_{_i}[y_{_i}({w}^T{x_{_i}}+{b})-1+\xi_{_i}]=0, (i=1,...,n)\]

1.4. SMO演算法

1996年, John Platt釋出了一個稱為SMO的強大演算法,用於訓練SVM。 SMO表示序列最小優化(Sequential Minimal Optimization)。 Platt的SMO演算法是將大優化問題分解為多個小優化問題來求解,這些小優化問題往往很容易求解,並且對它們進行順序求解的結果與將它們作為整體來求解的結果是完全一致的。
SMO演算法的目標是求出一系列\(\alpha\),一旦求出了這些\(\alpha\),就很容易計算出權重向量\({w}\)\({b}\),並得到分隔超平面。
SMO演算法的工作原理是:每次迴圈中選擇兩個\(\alpha\)進行優化處理。一旦找到一對合適的\(\alpha\),那麼就增大其中一個同時減小另一個。這裡所謂的“合適”就是指兩個\(\alpha\)必須要符合一定的條件,條件之一就是這兩個\(\alpha\)必須要在間隔邊界之外,而其第二個條件則是這兩個\(\alpha\)還沒有進行過區間化處理或者不在邊界上。
對SMO具體的分析如下,在4.3節中我們已經得出了

\[W(\alpha)=\sum_{i=1}^{n}\alpha{_i}-\frac{1}{2}\sum_{i=1}^{n}\sum_{j=1}^{n}\alpha{_i}\alpha{_j}y_{_i}y_{_j}{x_{_i}}^Tx_{_j} \]

\[\sum_{i=1}^{n}\alpha{_i}y_{_i}=0, 0\leqslant \alpha_{_i}\leqslant C (i=1,...,n)\]

其中\((x_i,y_i)\)已知,C可以預先設定,也是已知數,現在就是要最大化\(W(\alpha)\),求得引數\({\alpha}=[\alpha_{_1},\alpha_{_2},...,\alpha_{_n}]\)。SMO演算法是一次選擇兩個\(\alpha\)進行優化,那我們就選擇\(\alpha_{_1}\)\(\alpha_{_2}\),然後把其他引數\([\alpha_{_3},\alpha_{_4},...,\alpha_{_n}]\)固定,這樣\(\alpha_{_1}\)\(\alpha_{_2}\)表示為下面的式子,其中\(\zeta\)是實數值:
\[\alpha_{_1}y_{_1}+\alpha_{_2}y_{_2}=-\sum_{i=3}^{n}\alpha_{_i}y_{_i}=\zeta\]
然後用\(\alpha_{_2}\)來表示\(\alpha_{_1}\)
\[\alpha_{_1}=(\zeta-\alpha_{_2}y_{_2})y_{_1}\]
把上式帶入\(W({\alpha})\)中:
\[W(\alpha)=W(\alpha_{_1},\alpha_{_2},...,\alpha_{_n})=W((\zeta-\alpha_{_2}y_{_2})y_{_1},\alpha_{_2},...,\alpha_{_n})\]
省略一系列化解過程後,最後會化解成我們熟悉的一元二次方程,a,b,c均是實數值:
\[W(\alpha_{_2})=a\alpha_{_2}^2+b\alpha_{_2}+c\]
最後對\(\alpha_{_2}\)求導,解得\(\alpha_{_2}\)的具體值,我們暫時把這個實數值叫\(\alpha_{_2}^*\)。而這個\(\alpha_{_2}^*\)需要滿足一個條件\(L\leqslant \alpha_{_2}^*\leqslant H\),其中\(L\)\(H\)是什麼呢?如下圖所示:

2017-09-13-16-56-00
(圖片來自網路)

根據之前的條件\(0\leqslant \alpha_{_i}\leqslant C\)和等式\(\alpha_{_1}y_{_1}+\alpha_{_2}y_{_2}=\zeta\)\(\alpha_{_1}\)\(\alpha_{_2}\)要在矩形區域內,並且在直線上。當\(y_{_1}\)\(y_{_2}\)異號時:
\[\begin{cases} L=max(0,\alpha_{_2}-\alpha_{_1}) \\ &\\ H=min(C,C+\alpha_{_2}-\alpha_{_1}) \end{cases}\]
\(y_{_1}\)\(y_{_2}\)同號時:
\[\begin{cases} L=max(0,\alpha_{_2}+\alpha_{_1}-C) \\ &\\ H=min(C,\alpha_{_2}+\alpha_{_1}) \end{cases}\]
最後,滿足條件的\(\alpha_{_2}\)應該由下面的式子得到,\(\alpha_{_2}^{**}\)才為最終的值:
\[\alpha_{_2}^{**} =\begin{cases} H &, \alpha_{_2}^*> H \\ \\ \alpha_{_2}^*& , L\leq \alpha_{_2}^*\leq H \\ \\ L & ,\alpha_{_2}^*<L \end{cases}\]
求得\(\alpha_{_2}^{**}\)後我們就可以求得\(\alpha_{_1}^{**}\)了。然後我們重複地按照最優化\((\alpha_{_1},\alpha_{_2})\)的方式繼續選擇\((\alpha_{_3},\alpha_{_4})\)\((\alpha_{_5},\alpha_{_6})\)....\((\alpha_{_{n-1}},\alpha_{_n})\)進行優化求解,這樣\({\alpha}=[\alpha_{_1},\alpha_{_2},...,\alpha_{_n}]\)求解出來後,整個線性劃分問題就迎刃而解。

1.5. 核函式

對於以上幾節講的SVC演算法,我們都線上性可分或存在一些噪聲點的情況下進行的二分類,但是如果我們存在兩組資料,它們的散點圖如下圖所示,你可以看出這完全是一個非線性不可分的問題,我們無法使用之前講的SVC演算法在這個二維空間中找到一個超平面把這些資料點準確的分開。

2017-09-13-18-11-01

解決這個劃分問題我們需要引入一個核函式,核函式能夠恰當的計算給定資料的內積,將資料從輸入空間的非線性轉變到特徵空間,特徵空間具有更高甚至無限的維度,從而使得資料在該空間中被轉換成線性可分的。如下圖所示,我們把二維平面的一組資料,通過核函式對映到了一個三維空間中,這樣,我們的超平面就面成了一個平面(在二維空間中是一條直線),這個平面就可以準確的把資料劃分開了。

2017-09-13-18-22-21

核函式有Sigmoid核、線性核、多項式核和高斯核等,其中高斯核和多項式核比較常用,兩種核函式均可以把低維資料對映到高維資料。高斯核的公式如下,\(\sigma\)是達到率,即函式值跌落到0的速度引數:
\[K({x_1},{x_2})=exp(\frac{-||{x_1}-{x_2}||^2}{2\sigma^2 })\]
多項式核函式的公式如下,\(R\)為實數,\(d\)為低維空間的維數:
\[K({x_1},{x_2})=(\left \langle {x_1}, {x_2}\right \rangle +R)^d\]
應用於我們的上個例子,我們先定義,用\(\phi : {x}\to H\)表示從輸入空間\({x}\subset \mathbb{R}^n\)到特徵空間H的一個非線性變換。假設在特徵空間中的問題是線性可分的,那麼對應的最優超平面為:
\[{w}^{\phi T}\phi({x})+{b}=0\]

通過拉格朗日函式我們推匯出:
\[{w}^{\phi *}=\sum_{i=1}^{n}\alpha{_i}^*y_{_i}\phi({x_{_i}})\]
帶入上式得特徵空間的最優超平面為:
\[\sum_{i=1}^{n}\alpha{_i}^*y_{_i}\phi^T({x_{_i}})\phi({x})+{b}=0\]
這裡的\(\phi^T({x_{_i}})\phi({x})\)表示內積,用核函式代替內積則為:
\[\sum_{i=1}^{n}\alpha{_i}^*y_{_i}K({x_{_i}},{x})+{b}=0\]
這說明,我們的核函式均是內積函式,通過在低維空間對輸入向量求內積來對映到高維空間,從而解決在高維空間中資料線性可分的問題,至於具體的推導過程,這裡就不再進行了,感興趣的可以自己再推導一次,加深理解。
為什麼核函式可以把低維資料對映成高維資料呢,我們以多項式核來解釋一下。
假設有兩個輸入樣本,它們均為二維行向量\({x_1}=[x_1,x_2]\)\({x_2}=[x_3,x_4]\),他們的內積為:
\[\left \langle {x_1},{x_2} \right \rangle={x_1}{x_2}^T=\begin{bmatrix} x_1 &x_2 \end{bmatrix}\begin{bmatrix} x_3\\x_4 \end{bmatrix}=x_1x_3+x_2x_4\]
用多項式核函式進行對映,令\(R=0\)\(d=2\)
\[ K({x_1},{x_2})=(\left \langle {x_1},{x_2} \right \rangle)^2 =(x_1x_3+x_2x_4 )^2={x_1}^2{x_3}^2+2x_1x_2x_3x_4+{x_2}^2{x_4}^2=\phi({x_1}) \phi({x_2})\]
按照線性代數中的標準定義,\(\phi({x_1})\)\(\phi({x_2})\)為對映後的三維行向量和三維列向量,即:

\[\phi({x_1})=\begin{bmatrix} {x_1}^2 & \sqrt{2}{x_1}{x_2} & {x_2}^2 \end{bmatrix}\]
\[\phi({x_2})=\begin{bmatrix} {x_3}^2\\ \\ \sqrt{2}{x_3}{x_4}\\ \\ {x_4}^2 \end{bmatrix}\]
它們的內積用向量的方式表示則更直觀:
\[\phi({x_1})\phi({x_2})=\begin{bmatrix} {x_1}^2 & \sqrt{2}{x_1}{x_2} & {x_2}^2 \end{bmatrix}\begin{bmatrix} {x_3}^2\\ \\ \sqrt{2}{x_3}{x_4}\\ \\ {x_4}^2 \end{bmatrix}={x_1}^2{x_3}^2+2x_1x_2x_3x_4+{x_2}^2{x_4}^2\]
這樣我們就把二維資料對映成了三維資料,對於高斯核的對映,會用到泰勒級數展開式,讀者可以自行推導一下。
對於核函式我們就暫時介紹到這裡。下一節我們開始運用tensorflow來進行實戰,由於沒有找到線性不可分的資料集,我們的例子中就沒有用到核函式來建模,因為我們只找到了一個線性可分的資料集,所以下一節我們僅運用tensorflow來進行線性二分類的分類器構建。

1.6. 例項

我們在網上下載了一組鳶尾花資料集,這組資料集有100個樣本點,我們用SVM來預測這些鳶尾花資料集中哪些是山鳶尾花,哪些是非山鳶尾花。

  • 首先需要載入資料集,載入資料集需要用到sklearn、scipy、mkl庫,sklearn直接在Pycharm中安裝即可,而另外兩個庫需要在網上下載安裝,下載地址:http://www.lfd.uci.edu/~gohlke/pythonlibs/
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from sklearn import datasets

sess = tf.Session()

# 載入資料
# iris.data = [(Sepal Length, Sepal Width, Petal Length, Petal Width)]
iris = datasets.load_iris()
x_vals = np.array([[x[0], x[3]] for x in iris.data])
y_vals = np.array([1 if y == 0 else -1 for y in iris.target])
  • 分離測試集與訓練集

# 分離訓練和測試集
train_indices = np.random.choice(len(x_vals),
                                 round(len(x_vals)*0.8),
                                 replace=False)
test_indices = np.array(list(set(range(len(x_vals))) - set(train_indices)))
x_vals_train = x_vals[train_indices]
x_vals_test = x_vals[test_indices]
y_vals_train = y_vals[train_indices]
y_vals_test = y_vals[test_indices]
  • 定義模型和loss函式

batch_size = 100

# 初始化feedin
x_data = tf.placeholder(shape=[None, 2], dtype=tf.float32)
y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)

# 建立變數
A = tf.Variable(tf.random_normal(shape=[2, 1]))
b = tf.Variable(tf.random_normal(shape=[1, 1]))

# 定義線性模型
model_output = tf.subtract(tf.matmul(x_data, A), b)

# Declare vector L2 'norm' function squared
l2_norm = tf.reduce_sum(tf.square(A))

# Loss = max(0, 1-pred*actual) + alpha * L2_norm(A)^2
alpha = tf.constant([0.01])
classification_term = tf.reduce_mean(tf.maximum(0., tf.subtract(1., tf.multiply(model_output, y_target))))
loss = tf.add(classification_term, tf.multiply(alpha, l2_norm))
  • 開始訓練資料
my_opt = tf.train.GradientDescentOptimizer(0.01)
train_step = my_opt.minimize(loss)

init = tf.global_variables_initializer()
sess.run(init)

# Training loop
loss_vec = []
train_accuracy = []
test_accuracy = []
for i in range(20000):
    rand_index = np.random.choice(len(x_vals_train), size=batch_size)
    rand_x = x_vals_train[rand_index]
    rand_y = np.transpose([y_vals_train[rand_index]])
    sess.run(train_step, feed_dict={x_data: rand_x, y_target: rand_y})
  • 繪製圖像
[[a1], [a2]] = sess.run(A)
[[b]] = sess.run(b)
slope = -a2/a1
y_intercept = b/a1
best_fit = []

x1_vals = [d[1] for d in x_vals]

for i in x1_vals:
    best_fit.append(slope*i+y_intercept)


# Separate I. setosa
setosa_x = [d[1] for i, d in enumerate(x_vals) if y_vals[i] == 1]
setosa_y = [d[0] for i, d in enumerate(x_vals) if y_vals[i] == 1]
not_setosa_x = [d[1] for i, d in enumerate(x_vals) if y_vals[i] == -1]
not_setosa_y = [d[0] for i, d in enumerate(x_vals) if y_vals[i] == -1]

plt.plot(setosa_x, setosa_y, 'o', label='I. setosa')
plt.plot(not_setosa_x, not_setosa_y, 'x', label='Non-setosa')
plt.plot(x1_vals, best_fit, 'r-', label='Linear Separator', linewidth=3)
plt.ylim([0, 10])
plt.legend(loc='lower right')
plt.title('Sepal Length vs Pedal Width')
plt.xlabel('Pedal Width')
plt.ylabel('Sepal Length')
plt.show()

訓練後的結果
2017-09-14-16-44-38

轉載註明出處http://www.cnblogs.com/vipyoumay/p/7560061.html