感知机-梯度下降
前言
近期跟隨課程進度,學習簡單地深度學習部分算法,我將以筆記和感悟的形式記錄這一段學習過程,有不當之處歡迎各位批評指正。
簡介
形象感知
接觸過了一點學習算法之后,大致上可以分為兩類。一類是依賴概率模型,一類依賴判別模型,本次學習的感知機屬于非常簡單的判別模型。它可以用于線性關系的二分類問題,比如我們制作一個分類器,該分類器用于將人的身材進行簡單分類,最終分類的類型只有胖或者瘦兩種結果。該分類器依賴于兩個參數進行分類,身高和體重。那么在一定粗略的程度上,我們大致認為,越高越輕則人越瘦。那么我們可以用這樣一個式子表示 y = a * 身高 + b * 體重 + c ,若y >0,則判斷此人為瘦。我們希望人越高,越輕,則 y 越可能大于0,那么此模型應該是合理的。那么我們怎樣找到合適的參數a,b,c呢?對于上述這個例子,當然存在很大的主觀性,但是對于很多分類問題,事實上是很客觀的,我們需要找到一組合適的參數讓這個分類器更加準確和穩定。那么我們怎樣找到一組合理的參數呢?不要著急,我們先弄明白背后的模型推導,這些問題就會一步步得到解決。
公式解釋
其實看明白上一個例子,應該就不難理解了。我們不妨將信號X取的小一點,我們取二維向量x[ x0,x1 ]^T作為特征向量,類比身高體重兩個參數 w[w0,w1]作為權重系數,類似于a,b兩個參數,為了引入sign(x)這個函數方便表示,我們添加一項 b,稱為偏置,不難理解選取合適的偏置,我們可以得到一個以0為標準的結果。
模型
假設輸入空間(特征向量)是X,輸出空間為Y。輸出Y表示實例的類別,則由輸入空間到輸出空間的表達形式為:
其中sign是一個符號函數
推導
關于找到合適的參數,我們首先想到的是采用試參法,在所舉例子中或許我們不難得到一組較為合理的參數,但是大多數時候我們是很難通過人工試湊得到合理參數的,尤其是特征空間很大時。所以我們將采用梯度下降法找到合理參數。下面是數學推導,事實上并不麻煩,如果覺得這一部分過于繁瑣,那么也可以直接選擇跳過,只要你堅信,這一過程是正確的。
首先,我們需要構建一個Lossfunction 來評價一套參數的好壞,比如我們期望損失函數越小,這套參數的表線更優秀。
承接上個標題 模型 中的例子,我們試圖在平面直角坐標系中給幾個點分類,當然首先我們已經知道這幾個點的類別,我們的工作是找出一套合適的參數讓這個分類更科學。
就像紫色部分覆蓋的兩個點是我們默認的一類,綠色點是另一類。深紫色的線即為我們所需要找出的那一套合理的參數了。
那么我們選取什么作為損失函數呢?
我們可以直觀的了解,其實存在無數條直線可以將這三個點正確的劃分為兩類,也即我們可也找到無數套參數。不難想到,在算法進行之初,我們未必能一次就找到合適的參數,我們可以用誤分類點的數目來作為損失函數,誤分類點個數越來越少時,表示參數越來越合理,但不妙的是我們無法用函數或者模型的形式給出錯誤分類的個數,因為它不具有規律性。
在這里,提供一種思路,我們采用當前錯誤分類點數到所找到的直線(也即參數)的距離來表示損失函數,自然當錯誤分類數達到0時,損失函數也就最小了。下面這個公式完全可以類比高中數學平面幾何知識 點到直線的距離。
那么下一個問題來了,哪些點是被我們當前錯誤分類的呢?
yi是我們實現劃分好的類別,可以理解為我們對一個人事先做好的胖瘦的評價。而 w * x + b是當前參數得到的結果,我們不關心數值,我們關心其符號,不難發現只要是被誤判的點,都符合上邊的式子。
那么誤分類點的距離就是
進一步簡化,我們將分母部分去掉,得到下式。
再往下,我們需要用到梯度下降法進行參數的更新了,首先我們需要對參數求偏導數。
選擇一個誤分類點(xi, yi),L(w,b)=-yi(w·xi+b),▽wL(w,b)=-yixi,▽bL(w,b)=-yi,對w和b進行更新:
實現
算法敘述
1.導入訓練數據,初始化參數 w[w0 w1],b
2.從訓練數據集中摘取數據,判斷其是否是錯誤分類的點
3.如果被錯誤分類,則更新w[w0 w1] 和b,如果沒有被錯誤分類,跳過,進行4
4.轉到2,直到不存在被錯誤分類的點。
代碼實現(python)
話不多說,上代碼
training_data = [[(3, 6), 1], [(4, 2), 1], [(2, 1), -1]]w = [0, 0] b = 0# 判斷是否是錯誤分類的點 def YN(data):global w,bresult = 0for i in range(len(data[0])):result += data[0][i] * w[i] # res = x0 * w0 + x1 + w1result = ( result + b ) * data[1] # res = yi * ( x0 * w0 + x1 + w1 +b ) return result# 梯度下降法 def update(data): global w,bw[0] = w[0] + 1 * data[1] * data[0][0] # w0 = w0 + n * yi * x0w[1] = w[1] + 1 * data[1] * data[0][1] # w1 = w1 + n * yi * x1b = b + 1 * data[1] # b = b + n * yi # 檢查每個點是否被正確分類 def check():flag = Falsefor data in training_data: if YN(data) <= 0: # 非正的即為錯誤分類的數據flag = Trueupdate(data)if not flag:print ('w:' + str(w) + ' b:'+ str(b))flag = Falsefor i in range(10):check()輸出結果
用圖形計算器作圖得到
可見,該分類器已經找到了一套合適的參數。
總結
- 上一篇: 51单片机 简易光电循迹小车
- 下一篇: 三星Quantum 4现身Geekben