深度學(xué)習(xí)開篇-感知機(jī)(perceptron)原理和實(shí)現(xiàn)

近幾年科技領(lǐng)域很流行大數(shù)據(jù)、機(jī)器學(xué)習(xí)登馒、深度學(xué)習(xí)之類的字眼匙握,其實(shí),這些東西原理很早的時候就有了陈轿,只不過當(dāng)時不叫這些名詞圈纺,等我們慢慢學(xué)習(xí)就會發(fā)現(xiàn),這些玩意兒結(jié)合了高數(shù)麦射、概率統(tǒng)計(jì)學(xué)蛾娶、矩陣論、線性代數(shù)等潜秋,然后以代碼實(shí)現(xiàn)來解決實(shí)際問題蛔琅。深度學(xué)習(xí)可以認(rèn)為被包含在機(jī)器學(xué)習(xí)之中。至于目前他們的應(yīng)用和研究領(lǐng)域峻呛,包括圖像識別罗售、NLP(自然語言處理)等等,大家自行查閱钩述。廢話不多說寨躁,現(xiàn)在我從一個最簡單的模型向大家展示這類玩意兒怎么玩起來

1.感知機(jī)

為了了解什么是感知機(jī),我們需要先理解一下幾點(diǎn):

第一點(diǎn):感知機(jī)是二類分類的線性分類模型(為了新手理解牙勘,還是多說兩句朽缎,什么叫做二類分類,從程序的角度谜悟,感知機(jī)的輸入是某個事物话肖,而它的輸出只有兩種狀態(tài),從現(xiàn)實(shí)的角度葡幸,我們把具體的人這個事物輸入給感知機(jī)要她判別性別最筒,最后感知機(jī)只能輸出兩種結(jié)果:“男人”或“女人”,不會有第三種~~蔚叨,如果我們需要有第三種結(jié)果床蜘,則這個問題不能用感知機(jī)來解決(有其他辦法)辙培。至于什么叫做線性,接下來會講到)

第二點(diǎn):把某個事物輸入到感知機(jī)模型的理解邢锯。(太抽象了吧扬蕊,映射到程序是怎樣的啊)這種輸入其實(shí)有很多種形式丹擎,我舉個最簡單的例子幫助讀者理解尾抑。對于某個特定的人,比如我蒂培,身高2.0米再愈,體重150,帥氣程度100分(滿分100) 可愛程度0(滿分100)护戳,數(shù)據(jù)提取出來 (2.0 150 100 0) 其中的每一個標(biāo)識都稱之為一個特征點(diǎn)翎冲,然后我們就定義一個向量 a = (2.0,150,100,0)來表示“我”這個人,所以輸入就是向量a(特征向量)媳荒。(ps:這只是最基礎(chǔ)的一種形式抗悍,不局限于此)

第三點(diǎn):“學(xué)習(xí)”的簡單理解。機(jī)器學(xué)習(xí)钳枕、深度學(xué)習(xí)中都有學(xué)習(xí)二字缴渊,此二字代表什么意思?直觀理解么伯,就是我們從已知信息中學(xué)習(xí)其中的規(guī)律規(guī)則疟暖,從而預(yù)測未知。還是以上述例子闡述√锶幔現(xiàn)在我們碰到這樣的一個問題:我有1000條人的信息俐巴,現(xiàn)在我在路上看到一個背影,目測身高165,體重90硬爆、帥氣程度30欣舵,可愛程度80,想知道他(她)是男是女缀磕。這種情況就可以考慮采用感知機(jī)處理類似問題缘圈。(埋下鋪墊,實(shí)際中的應(yīng)用場景很有限)袜蚕。我們提取1000個人信息中的五個特征點(diǎn)(身高糟把、體重、帥氣程度牲剃、可愛程度遣疯,性別)轉(zhuǎn)化成1000個特征向量,1000個標(biāo)記向量(只有性別凿傅,男用+1表示缠犀,女用-1表示数苫,對應(yīng)于特征向量)作為感知機(jī)的輸入進(jìn)行訓(xùn)練,讓其學(xué)習(xí)其中的關(guān)聯(lián)辨液,得到一個訓(xùn)練后的模型虐急,當(dāng)輸入向量(1.65,90,30,80)后,感知機(jī)就可以根據(jù)訓(xùn)練好的模型預(yù)測出最后的結(jié)果(+1 或 -1)

第四點(diǎn):我們從數(shù)學(xué)的角度深入推敲這個問題的實(shí)際轉(zhuǎn)化(其實(shí)也就是一個數(shù)學(xué)建模的過程)

可以理解如下

人 ? ? ? ? ? ? ? 特征向量 ? ? ? ? ? ? ? ? ? ? ? ?標(biāo)記 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?序號

我 ? ? ? ? ? (2.0,150,100,0) ? ? ? ? ? ? ?+1(男) ? ? ? ? ? 已知 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1

夏目 ? ? (1.78,135,80,20) ? ? ? ? +1 ( 男) ? ? ? ? ? 已知 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?2

魯路修 ?(1.80,140,99,1) ? ? ? ? ?+1(男) ? ? ? ? ?已知 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?3

魔女cc ?(1.63,88,10,99) ? ? ? ? ? -1 (女) ? ? ? ? 已知 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?4

.... ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?... ? ? ? ? ? ? ? ? ? ? ?... ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ...

路人 ? ? ?(1.65,90,20,90) ? ? ? ? ? ? ?(要求解的量) ??

那么滔迈,建模開始


第五點(diǎn):"學(xué)習(xí)"的數(shù)學(xué)表達(dá)式直觀理解(以下以感知機(jī)為例止吁,其實(shí)很多類型神經(jīng)網(wǎng)絡(luò)都類似)

通過上述建模,現(xiàn)在我們的問題變成了如何調(diào)整系數(shù)W(w0,w1,w2.... )和b亡鼠,(注意赏殃,此處的系數(shù)W是向量)敷待,使得模型f(X) = sign(W*X+b)具有更好的表達(dá)能力间涵。此處好的表達(dá)能力指的什么?還是舉上述列子榜揖,對于已知的1000個特征向量勾哩,輸入模型f計(jì)算后得到的結(jié)果盡可能和對應(yīng)標(biāo)簽一致(其實(shí)也就是一個擬合過程),然后我們再輸入表示剛才路人的特征向量举哟,經(jīng)過f計(jì)算的結(jié)果就是對于此路人的性別預(yù)測結(jié)果思劳。

那么,現(xiàn)在問題變成了如何調(diào)整系數(shù)W和b妨猩,使得f(X)學(xué)習(xí)到的表達(dá)能力最好潜叛。這里扯起來又可以寫幾篇文章,我們以后一步步展開壶硅,目前我只做陳述威兜,有興趣的同學(xué)可以查看我的csdn博客(代價函數(shù) )。目前咱們暫且要記住庐椒,如何調(diào)整系數(shù)W和b椒舵,使得f(X)學(xué)習(xí)到的表達(dá)能力最好問題,可以轉(zhuǎn)換為調(diào)整模型參數(shù)W约谈,b笔宿,使得代價函數(shù)最小。代價函數(shù)有許多定義形式棱诱,此處我們依照李航《統(tǒng)計(jì)學(xué)習(xí)方法》P26 P27(大家有興趣的可以看看泼橘,其中有cost代價函數(shù)的推導(dǎo)過程。此處我直接給出

其中M表示誤分類點(diǎn)的集合 迈勋,xi表示第i個樣本(第i個已知信息的特征向量)炬灭,yi對應(yīng)+1/-1

第六點(diǎn):“學(xué)習(xí)算法”

怎樣使得代價函數(shù)最小(其實(shí)變成了一個純高數(shù)問題)粪躬,對于L(W,b)担败,xi和yi已知昔穴,W和b是變量,L是一個多元方程提前,求W和b吗货,使得L為最小值,采用梯度下降算法(ps:高數(shù)中有一個梯度的概念狈网,大家需要回顧宙搬,可以參考機(jī)器學(xué)習(xí)-梯度下降法實(shí)現(xiàn)線性回歸

最后的步驟如下:


上述訓(xùn)練集中xi可以是多維的,即訓(xùn)練集T = {(x11,x12,x13,x14,...,x1n,y1),(x21,x22,x23,x24,...,x2n,y2,...,(xN1,xN2,xN3,xN4,...,xNn,yN))


讀者要特別注意的幾點(diǎn):上述文字只是幫助初學(xué)者更容易上手理解拓哺,沒有涉及推導(dǎo)過程勇垛,《統(tǒng)計(jì)學(xué)習(xí)方法》李航著 ?第一二章一定要看看,學(xué)會手工推算士鸥,損失函數(shù)闲孤、梯度下降都要分別查閱文獻(xiàn)和推導(dǎo)

讀到這估計(jì)很多人已經(jīng)迷糊了,但最大的問題在于烤礁,為什么建模的時候使用多元線性方程讼积,難道多元自變量和結(jié)果之間的關(guān)系一定是線性的嗎?(如果讀到這都沒想過這個問題脚仔,那~~)當(dāng)然不一定勤众,怎么可能,而且絕大部分不是線性可分的鲤脏,所以们颜,大家要記住,單個感知機(jī)的表達(dá)能力很弱猎醇。此處可以聯(lián)想一下窥突,如果在二維坐標(biāo)中有很多離散的紅藍(lán)點(diǎn),我們有多少概率可以用一條線就將其劃分開姑食,在三維坐標(biāo)中又有多少概率可以用平面將其劃分開波岛,依次類推到n維。既然單個感知機(jī)的能力這么挫音半,我為什么要開篇講它则拷? 因?yàn)閱蝹€感知機(jī)可以看成組成神經(jīng)網(wǎng)絡(luò)的神經(jīng)元的一部分,以后詳解曹鸠。

2.代碼實(shí)例

扯了半天不寫代碼和咸魚又有什么區(qū)別

代碼下載(整個項(xiàng)目打包了煌茬,安裝vs2013 ,直接雙擊.sln即可調(diào)試查看)

感知機(jī)簡單實(shí)現(xiàn)c++

如果我們用上述代碼學(xué)習(xí)訓(xùn)練無法線性可分的數(shù)據(jù)集彻桃,就會導(dǎo)致W坛善,b無法收斂,陷入死循環(huán),若一定要用感知機(jī)訓(xùn)練眠屎,就只能手工設(shè)置循環(huán)次數(shù)剔交,但這種方式最后會導(dǎo)致訓(xùn)練效果不好,預(yù)測的正確率就會大幅降低改衩。以后會更新更好的神經(jīng)網(wǎng)絡(luò)模型來解決這個問題

以統(tǒng)計(jì)學(xué)習(xí)方法P29頁題目為例


#include<iostream>

#include<vector>

#include<string>

#include<fstream>

using namespace std;

typedef vectorfeatureVct;

typedef int label;

class Perceptron;

void printRes(Perceptron pp);

class Perceptron

{private:

vectorFtSet; //特征向量數(shù)據(jù)集vectorlabelSet; //二分類label數(shù)據(jù)集 +1或-1

double LearnRate; //學(xué)習(xí)率

featureVct w; //感知機(jī)模型參數(shù)

double bias; //偏置項(xiàng)

int dimension; //特征向量維度

int count;

public:

Perceptron(int dimension,featureVct w,double bias = 0.0,double learnRate = 1);

int GetCount() const;? //獲取迭代次數(shù)

const featureVct& GetW() const ; ? ? //獲取模型參數(shù)

void SetW(const featureVct& w); ? //設(shè)置模型參數(shù)

double GetBias() const; //獲取偏置項(xiàng)

void SetBias(double bias); //設(shè)置騙置項(xiàng)

bool ReadSource(const string& filePath); //讀取數(shù)據(jù)源

void Train(); //訓(xùn)練模型岖常,得到感知機(jī)模型

public:

double VectorDotProduct(const featureVct& f1, const featureVct& f2);? //向量點(diǎn)積運(yùn)算)

featureVct VectorScalarMulti(double num, const featureVct f); //向量數(shù)乘運(yùn)算

featureVct VectorAdd(const featureVct& f1, const featureVct& f2);? //向量加法運(yùn)算

};

const featureVct& Perceptron::GetW() const

{

return w;

}

void Perceptron::SetW(const featureVct& w)

{

this->w = w;

}

double Perceptron::GetBias() const

{

return bias;

}

void Perceptron::SetBias(double bias)

{

this->bias = bias;

}

/*文件格式:每行表示一個樣本點(diǎn),特征值之間用空格隔開葫督,最后一列存儲類別信息1或-1*/

bool Perceptron::ReadSource(const string& filePath)

{

ifstream file(filePath);

if (!file)

return false;

while (!file.eof())

{

featureVct dataTmp;

double tmp;

for (int i = 0; i < dimension; ++i)

{

file >> tmp;

dataTmp.push_back(tmp);

}

FtSet.push_back(dataTmp);

label labelData;

file >> labelData;

labelSet.push_back(labelData);

}

return true;

}

void Perceptron::Train()

{

//感知機(jī)訓(xùn)練過程

int flag = true;

while (flag)

{

for (int i = 0; i < FtSet.size(); i++)

{

flag = false;

if (labelSet[i] * (VectorDotProduct(w,FtSet[i]) + bias) <= 0)

{

//此處的打印只是為了更直觀的給大家展示學(xué)習(xí)過程竭鞍,工程中最后不要直接在類中打印信息

printRes(*this);

flag = true;

w = VectorAdd(w, VectorScalarMulti(labelSet[i]*LearnRate,FtSet[i]));

bias += LearnRate * labelSet[i];

++count;

break;

}

}

//此處的打印只是為了更直觀的給大家展示學(xué)習(xí)過程,工程中最后不要直接在類中打印信息

if(!flag)? printRes(*this);

}

}

Perceptron::Perceptron(int dimension, featureVct w, double bias, double learnRate)

{

this->dimension = dimension;

this->bias = bias;

this->LearnRate = learnRate;

this->w = w;

count = 0;

}

double Perceptron::VectorDotProduct(const featureVct& f1, const featureVct& f2)

{

double sum = 0.0;

for (int i = 0; i != f1.size(); ++i)

{

sum += f1[i] * f2[i];

}

return sum;

}

featureVct Perceptron::VectorScalarMulti(double num, const featureVct f)

{

featureVct tmp;

for (int i = 0; i != f.size(); ++i)

{

tmp.push_back(num*f[i]);

}

return tmp;

}

featureVct Perceptron::VectorAdd(const featureVct& f1, const featureVct& f2)

{

featureVct tmp(0);

for (int i = 0; i != f1.size(); ++i)

{

tmp.push_back(f1[i] + f2[i]);

}

return tmp;

}

int Perceptron::GetCount() const

{

return count;

}

void printRes(Perceptron pp)

{

cout << "迭代次數(shù):" << pp.GetCount() << endl;

cout << "w:";

featureVct tmp = pp.GetW();

for (int i = 0; i < tmp.size() - 1; ++i)

{

cout << tmp[i] << " ";

}

cout << tmp[tmp.size() - 1] << endl;

cout << "bias:";

cout << pp.GetBias() << endl;

cout << "---------------------------" << endl;

}

int main()

{

featureVct w;

w.push_back(0.0); //設(shè)置w初始化參數(shù)

w.push_back(0.0);

Perceptron pp(2, w);? //創(chuàng)建特征向量為2維的感知機(jī)對象

if (!pp.ReadSource("sun.txt"))

{

cout << "讀取文件失敗";

exit(-1);

}

pp.Train();? //訓(xùn)練得到感知機(jī)模型

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末橄镜,一起剝皮案震驚了整個濱河市偎快,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌洽胶,老刑警劉巖晒夹,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異妖异,居然都是意外死亡惋戏,警方通過查閱死者的電腦和手機(jī)领追,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門他膳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人绒窑,你說我怎么就攤上這事棕孙。” “怎么了些膨?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵蟀俊,是天一觀的道長。 經(jīng)常有香客問我订雾,道長肢预,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任洼哎,我火速辦了婚禮烫映,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘噩峦。我一直安慰自己锭沟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布识补。 她就那樣靜靜地躺著族淮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上祝辣,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天贴妻,我揣著相機(jī)與錄音,去河邊找鬼蝙斜。 笑死揍瑟,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的乍炉。 我是一名探鬼主播绢片,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼岛琼!你這毒婦竟也來了底循?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤槐瑞,失蹤者是張志新(化名)和其女友劉穎熙涤,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體困檩,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡祠挫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了悼沿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片等舔。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖糟趾,靈堂內(nèi)的尸體忽然破棺而出慌植,到底是詐尸還是另有隱情,我是刑警寧澤义郑,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布蝶柿,位于F島的核電站,受9級特大地震影響非驮,放射性物質(zhì)發(fā)生泄漏交汤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一劫笙、第九天 我趴在偏房一處隱蔽的房頂上張望芙扎。 院中可真熱鬧,春花似錦邀摆、人聲如沸纵顾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽施逾。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間汉额,已是汗流浹背曹仗。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蠕搜,地道東北人怎茫。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像妓灌,于是被迫代替她去往敵國和親轨蛤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348