摘要:發(fā)布于年月日,年月日更新作者使用感知器的機(jī)器學(xué)習(xí)簡(jiǎn)介每個(gè)熟悉技術(shù)的人都聽說過機(jī)器學(xué)習(xí)。什么是感知器感知器是機(jī)器學(xué)習(xí)和神經(jīng)網(wǎng)絡(luò)的基礎(chǔ)。第一個(gè)參數(shù)用于控制感知器學(xué)習(xí)的速度。請(qǐng)注意,我們?cè)谶@里使用變量,它決定了感知器學(xué)習(xí)的速度。
發(fā)布于2016年11月29日,2017年1月19日更新, 作者: Matthew Corrigan
使用感知器的Python機(jī)器學(xué)習(xí)簡(jiǎn)介每個(gè)熟悉技術(shù)的人都聽說過機(jī)器學(xué)習(xí)。但都認(rèn)為必得高智商的數(shù)學(xué)大師才能搞, 咋也得懂微積分才整機(jī)器學(xué)習(xí)吧。其實(shí)沒那么難,本文將指導(dǎo)您在沒有任何高級(jí)數(shù)學(xué)理論的情況下, 在Python中創(chuàng)建感知器,總計(jì)也不到60行代碼。
什么是感知器?感知器是機(jī)器學(xué)習(xí)和神經(jīng)網(wǎng)絡(luò)的基礎(chǔ)。你為程序喂一堆輸入數(shù)據(jù),想個(gè)法兒把這些輸入數(shù)據(jù)變成輸出數(shù)據(jù)。通過為每個(gè)輸入數(shù)據(jù)分配權(quán)重來實(shí)現(xiàn)。每個(gè)輸入乘以該權(quán)重,并加在一起。最后,我們需要將該總和轉(zhuǎn)換為二個(gè)值之一:1或-1。在訓(xùn)練感知器時(shí),我們會(huì)評(píng)估程序生成的輸出,并根據(jù)輸入和應(yīng)該輸出的內(nèi)容調(diào)整權(quán)重。實(shí)際上,感知器可以幫助我們對(duì)數(shù)據(jù)進(jìn)行分類。如果這個(gè)解釋讓你感到困惑,請(qǐng)不要擔(dān)心,當(dāng)我們開始編碼時(shí)你就會(huì)明白了。
編碼感知器類我們應(yīng)該從創(chuàng)建一個(gè)感知器類開始。在初始化函數(shù)中,我們想要初始化我們的權(quán)重,每個(gè)權(quán)重是從-1到1之間的隨機(jī)數(shù)。為了生成隨機(jī)數(shù),我們將使用random.random(),它返回0到1之間的數(shù)字。
??import random ?? ??class Perceptron: ?? ????def __init __(self, learn_speed, num_weights): ???? ??????self.speed = learn_speed ???? ??????self.weights = [] ??????for x in range(0, num_weights): ????????self.weights.append(random.random()* 2-1)
????????
第一個(gè)參數(shù)learn_speed用于控制感知器學(xué)習(xí)的速度。值越低,學(xué)習(xí)的時(shí)間越長,但每個(gè)數(shù)據(jù)對(duì)總體權(quán)重的值改變就越小。如果此參數(shù)太高,我們的程序?qū)⒑芸旄淖兤錂?quán)重,使其不準(zhǔn)確。另一方面,如果learn_speed太低,則因?yàn)榫葐栴}永遠(yuǎn)也無法完成感知器的訓(xùn)練。該參數(shù)的值約為0.01-0.05時(shí)比較合適。
第二個(gè)參數(shù)num_weights控制感知器將具有多少個(gè)權(quán)重值。我們的感知器也將具有與權(quán)重相同的輸入數(shù)量,因?yàn)槊總€(gè)輸入都有自己對(duì)應(yīng)的權(quán)重值。
接下來,我們需要在類中創(chuàng)建一個(gè)函數(shù)來接收輸入,并將它們轉(zhuǎn)換為輸出。我們通過將每個(gè)輸入乘以其相應(yīng)的權(quán)重,將所有這些加在一起,然后檢查總和是否大于0來完成此操作。在您的perceptron類中,在__init__函數(shù)之后添加此代碼:
??def feed_forward(self, inputs): ??????sum = 0 ??????#權(quán)重乘以輸入并求和 ??????for x in range(0, len(self.weights)): ????????sum + = self.weights[x] * inputs[x] ??????#返回"激活"總和 ??????return self.activate(sum) ?????? ????def activate(self, num): ??????#將大于0之和轉(zhuǎn)為1,低于0轉(zhuǎn)為-1 ??????if num> 0: ????????return 1 ??????return -1
上面的代碼是我們感知器的基礎(chǔ)。如果您能夠很好地理解這些代碼,那么您對(duì)機(jī)器學(xué)習(xí)的基礎(chǔ)知識(shí)已有了一個(gè)飛躍。讓我們一塊一塊地剖析這段代碼。
第一個(gè)函數(shù)feed_forward用于將輸入轉(zhuǎn)換為輸出。術(shù)語前饋通常用于神經(jīng)網(wǎng)絡(luò),以描述將輸入轉(zhuǎn)換為輸出的過程。該方法基于每個(gè)對(duì)應(yīng)的權(quán)重對(duì)每個(gè)輸入進(jìn)行加權(quán)并求和,然后使用activate函數(shù)返回1或-1。
activate函數(shù)用于將數(shù)字轉(zhuǎn)換為1或-1。這是因?yàn)楫?dāng)我們使用感知器時(shí),我們想要對(duì)數(shù)據(jù)進(jìn)行分類。我們將它分為兩??組,其中一組用1表示,另一組用-1表示。
你可能想知道,“如果權(quán)重是隨機(jī)的,那有什么用?” 這就是我們?cè)谑褂弥氨仨氂?xùn)練感知器的原因。在我們的訓(xùn)練函數(shù)中,我們希望根據(jù)提供的輸入進(jìn)行猜測(cè),然后看看我們的猜測(cè)與我們想要的輸出相比如何。感知器類的訓(xùn)練函數(shù)如下所示。
??def train(self,inputs,desired_output): ??????guess = self.feed_forward(inputs) ??????error = desired_output - guess ?????? ??????for x in range(0, len(self.weights)): ????????self.weights[x] + = error * inputs[x] * self.speed
????????
前幾行中的大多數(shù)都應(yīng)該有意義。我們的函數(shù)接受輸入,以及當(dāng)我們通過程序運(yùn)行輸入時(shí)應(yīng)該發(fā)生的輸出。我們使用feed_forward函數(shù)猜測(cè)輸入,然后根據(jù)我們應(yīng)該輸出的內(nèi)容計(jì)算出錯(cuò)誤。請(qǐng)注意,如果我們正確預(yù)測(cè),則錯(cuò)誤將等于0,并且函數(shù)的最后一行根本不會(huì)改變我們的權(quán)重。
這個(gè)功能的最后兩行是多汁的部分 - 他們把學(xué)習(xí)放在機(jī)器學(xué)習(xí)中。我們遍歷每個(gè)重量并根據(jù)我們有多少錯(cuò)誤來調(diào)整它。請(qǐng)注意,我們?cè)谶@里使用self.speed變量,它決定了感知器學(xué)習(xí)的速度。通過在一堆輸入及其輸出上運(yùn)行此訓(xùn)練函數(shù),我們最終可以教我們的感知器獲得正確的輸出。
訓(xùn)練感知器如果我們不實(shí)際訓(xùn)練它們,我們的感知器就沒用了。我們將通過編寫快速Trainer類來完成此操作。在這個(gè)例子中,我們將訓(xùn)練我們的感知器, 使其能分辨一個(gè)點(diǎn)是在一條線之上還是在一條線之下。我們的線由方程 y = 0.5x + 10表示。一旦您知道如何訓(xùn)練感知器來識(shí)別線,您可以將x和y表示為不同的屬性,在線的上方或下方作為這些屬性的運(yùn)算結(jié)果。
例如,如果您有關(guān)于哈佛大學(xué)申請(qǐng)人的GPA和ACT分?jǐn)?shù)的數(shù)據(jù)集,以及他們是否被接受,您可以訓(xùn)練感知器在圖表上找到x = GPA分?jǐn)?shù)和y = ACT分?jǐn)?shù)的線。在線以上將是被接受的學(xué)生,并且在線以下將是被拒絕的學(xué)生。然后,您可以使用此感知器來預(yù)測(cè)學(xué)生是否會(huì)根據(jù)他們的GPA和ACT分?jǐn)?shù)被哈佛大學(xué)錄取。
在這個(gè)例子中,我們將繼續(xù)去識(shí)別一條線。為此,我們將創(chuàng)建一個(gè)Trainer類,用于訓(xùn)練感知器的點(diǎn)數(shù),以及它們是否在線上。以下是我們的Trainer類的代碼:
class Trainer: def __init__(self): self.perceptron = Perceptron(0.01, 3) def f(self, x): return 0.5*x + 10 # line: f(x) = 0.5x + 10 def train(self): for x in range(0, 1000000): x_coord = random.random()*500-250 y_coord = random.random()*500-250 line_y = self.f(x_coord) if y_coord > line_y: # 在線上方 answer = 1 self.perceptron.train([x_coord, y_coord, 1], answer) else: # 在線下??面 answer = -1 self.perceptron.train([x_coord, y_coord, 1], answer) return self.perceptron # 返回我們訓(xùn)練有素的感知器????
??????
正如您所看到的,Trainer類的初始化程序創(chuàng)建了一個(gè)具有三個(gè)輸入且學(xué)習(xí)速度為0.01的感知器。前兩個(gè)輸入是x和y,但最后一個(gè)輸入是什么?這是神經(jīng)網(wǎng)絡(luò)和機(jī)器學(xué)習(xí)的另一個(gè)核心概念。最后一個(gè)輸入將始終設(shè)置為1. 與其對(duì)應(yīng)的權(quán)重將決定它對(duì)我們的線的影響。例如,如果你回顧我們的等式:y = 0.5x + 10,我們需要某種方式來表示y軸截距10. 我們通過創(chuàng)建第三個(gè)輸入來實(shí)現(xiàn)這一點(diǎn),該輸入需要根據(jù)感知器的權(quán)重增加或減少。將其視為一個(gè)閾值,幫助感知器理解線需要向上調(diào)整10個(gè)單位。
在我們的f函數(shù)中,我們接受一個(gè)x坐標(biāo)并返回一個(gè)y坐標(biāo)。根據(jù)x坐標(biāo)在線上找到點(diǎn),這將在下一個(gè)函數(shù)中派上用場(chǎng)。
Trainer類的這個(gè)訓(xùn)練函數(shù)是所有魔法發(fā)生的地方,我們實(shí)際上是訓(xùn)練我們的感知器。我們開始循環(huán)100萬次。還記得我們的感知器學(xué)習(xí)速度嗎?我們訓(xùn)練感知器的次數(shù)越多(在這種情況下,100萬次),即使學(xué)習(xí)速度很低,它也會(huì)越準(zhǔn)確。
在循環(huán)的每次迭代中,我們創(chuàng)建一個(gè)點(diǎn),確定它是否在線的上方或下方,然后將這些輸入饋送到感知器的訓(xùn)練函數(shù)中。首先,在-250和250之間隨機(jī)生成x和y坐標(biāo)。接下來,我們找到y(tǒng)坐標(biāo)在該x行的線上的位置,以查看我們的點(diǎn)是否在線上方。例如,如果我們?cè)冢?,3)處選擇一個(gè)點(diǎn),那么我們應(yīng)該獲得x值為3的線上的點(diǎn)的y坐標(biāo)。我們使用f函數(shù)執(zhí)行此操作。如果我們的隨機(jī)y坐標(biāo)值高于線上對(duì)應(yīng)的y坐標(biāo)值,我們知道隨機(jī)坐標(biāo)在線上方。
這就是我們?cè)趇f ... else語句中所做的。如果點(diǎn)在線上方,我們?cè)O(shè)置預(yù)期輸出,存儲(chǔ)在answer中為1.如果點(diǎn)低于該線,則我們的預(yù)期輸出為-1。然后根據(jù)x,y坐標(biāo)和我們的預(yù)期輸出訓(xùn)練我們的感知器。整個(gè)循環(huán)完成后,返回新訓(xùn)練的感知器對(duì)象。
運(yùn)行程序為了運(yùn)行程序,我們創(chuàng)建一個(gè)training對(duì)象,并調(diào)用它的.train()方法。
trainer = Trainer() p = trainer.train()
現(xiàn)在是榮耀的時(shí)刻;我們運(yùn)行該程序。讓我們選擇兩點(diǎn),( - 7,9)和(3,1)。第一個(gè)點(diǎn)在線上方,所以它應(yīng)該返回1,第二個(gè)點(diǎn)在線下面,所以它應(yīng)該返回-1。讓我們看看我們?nèi)绾芜\(yùn)行我們的感知器:
print "(-7, 9): " + p.feed_forward([-7,9,1]) print "(3, 1): " + p.feed_forward([3,1,1])
如果我們運(yùn)行它會(huì)輸出:
(-7, 9): 1
(3, 1): -1
成功! 我們的程序檢測(cè)到每個(gè)點(diǎn)是在線之上還是之下。 您可以嘗試更多的點(diǎn)來自己測(cè)試程序是否正常運(yùn)行。
小結(jié)本文旨在幫助您了解機(jī)器學(xué)習(xí)的一些基礎(chǔ)知識(shí); 具體而言,神經(jīng)網(wǎng)絡(luò)。 如果您想深入研究這個(gè)主題,請(qǐng)查看以下鏈接:
神經(jīng)網(wǎng)絡(luò)簡(jiǎn)介
斯坦福大學(xué)的免費(fèi)機(jī)器學(xué)習(xí)課程
納米級(jí)機(jī)器學(xué)習(xí)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/42525.html
摘要:沒有過年,年后在年后的年打敗了圍棋高手李世石,這下人工智能引起了全世界的關(guān)注。隨后的十多年,人工智能轉(zhuǎn)入第一次低潮,而也在他生日時(shí),因海事喪生,遺憾未能見到神經(jīng)網(wǎng)絡(luò)后期的復(fù)興。算力的進(jìn)步再次加速了人工智能的快速發(fā)展。 showImg(https://segmentfault.com/img/remote/1460000019409315); 小西:小迪小迪,我發(fā)現(xiàn)人工智能發(fā)展史上很多事...
摘要:二十世紀(jì)八十年代是機(jī)器學(xué)習(xí)成為一個(gè)獨(dú)立的學(xué)科領(lǐng)域各種機(jī)器學(xué)習(xí)技術(shù)百花初綻的時(shí)期。這時(shí)候,人們把機(jī)器學(xué)習(xí)劃分為機(jī)械學(xué)習(xí),示教學(xué)習(xí),類比學(xué)習(xí),歸納學(xué)習(xí)。三機(jī)器學(xué)習(xí)的分類機(jī)器學(xué)習(xí)中,有個(gè)定理叫沒有免費(fèi)午餐定理,簡(jiǎn)稱定理。 一、人工智能與機(jī)器學(xué)習(xí) 說到人工智能,就不得不提圖靈測(cè)試。圖靈測(cè)試是阿蘭圖靈在1950年提出的一個(gè)關(guān)于機(jī)器是否能夠思考的著名實(shí)驗(yàn),測(cè)試某機(jī)器是否能表現(xiàn)出與人等價(jià)或無法區(qū)分的...
閱讀 2796·2019-08-30 15:53
閱讀 2932·2019-08-29 16:20
閱讀 1135·2019-08-29 15:10
閱讀 1092·2019-08-26 10:58
閱讀 2252·2019-08-26 10:49
閱讀 695·2019-08-26 10:21
閱讀 774·2019-08-23 18:30
閱讀 1694·2019-08-23 15:58