神經(jīng)網(wǎng)絡(luò)之感知器

感知器的定義

下面是一個(gè)感知器:

Paste_Image.png

可以看到,一個(gè)感知器有如下組成部分:

  • 輸入權(quán)值 一個(gè)感知器可以接收多個(gè)輸入,每個(gè)輸入上有一個(gè)權(quán)值,此外還有一個(gè)偏置項(xiàng),就是上圖中的。
  • 激活函數(shù) 感知器的激活函數(shù)可以有很多選擇,比如我們可以選擇下面這個(gè)階躍函數(shù)來作為激活函數(shù):
Paste_Image.png
  • 輸出 感知器的輸出由下面這個(gè)公式來計(jì)算
Paste_Image.png

事實(shí)上,感知器不僅僅能實(shí)現(xiàn)簡(jiǎn)單的布爾運(yùn)算。它可以擬合任何的線性函數(shù),任何線性分類或線性回歸問題都可以用感知器來解決。

感知器訓(xùn)練法則

A)初始化權(quán)向量w=(w0,w1,…,wn),將權(quán)向量的每個(gè)值賦一個(gè)隨機(jī)值。
B)對(duì)于每個(gè)訓(xùn)練樣例,首先計(jì)算其預(yù)測(cè)輸出:

Paste_Image.png

C)當(dāng)預(yù)測(cè)值不等于真實(shí)值時(shí)則利用如下公式修改權(quán)向量:



各符號(hào)含義:
代表學(xué)習(xí)速率,t代表樣例的目標(biāo)輸出,o代表感知器輸出。
D)重復(fù)B)和C),直到訓(xùn)練集中沒有被錯(cuò)分的樣例。
算法分析:

若某個(gè)樣例被錯(cuò)分了,假如目標(biāo)輸出t為-1,結(jié)果感知器o輸出為1,此時(shí)為了讓感知器輸出-1,需要將wx減小以輸出-1,而在x的值不變的情況下只能減小w的值,這時(shí)通過在原來w后面添加(t-o)x=即可減小w的值(t-o<0, x>0)。
  通過逐步調(diào)整w的值,最終感知器將會(huì)收斂到能夠?qū)⑺杏?xùn)練集正確分類的程度,但前提條件是訓(xùn)練集線性可分。若訓(xùn)練集線性不可分,則上述過程不會(huì)收斂,將無限循環(huán)下去。

感知器的代碼實(shí)現(xiàn)
class Perception(object):
    def _int_(self,input_num,activator):
        '''
        初始化感知器
        '''
        self.activator = activator;
        #權(quán)重向量初始化為0
        self.weights = [0.0 for _ in range(input_num]
        #偏置項(xiàng)初始化為0
        self.bias = 0.0
    
    def _str_(self):
        #打印學(xué)習(xí)到的權(quán)重、偏置項(xiàng)
        return 'weight\t:%s\nbias\t:%f\n' %(self.weight,self.bias)
    
    def prefict(self,input_vec):
        #輸入向量,輸出感知器計(jì)算結(jié)果
        # 把input_vec[x1,x2,x3...]和weights[w1,w2,w3,...]打包在一起
        # 變成[(x1,w1),(x2,w2),(x3,w3),...]
        # 然后利用map函數(shù)計(jì)算[x1*w1, x2*w2, x3*w3]
        # 最后利用reduce求和
        return self.activator(
            reduce(lambda: a,b:a+b,map(lambda x,w:x*w,zip(input_vec,self.weights)),0.0)+self.bias) 
            # 這里reduce中的0.0就是reduce計(jì)算結(jié)果的初始值,其他是在0基礎(chǔ)上累加的
    def train(self,input_vec,labels,interation,rate):
        #輸入訓(xùn)練數(shù)據(jù):一組向量,與每個(gè)向量對(duì)應(yīng)的label,以及訓(xùn)練輪數(shù)
        for i in range(iteration):
            self._one_interation(input_vec,labels,rate)
    def _one_interation(self,input_vec,labels,rate):
        #一次迭代把所有訓(xùn)練數(shù)據(jù)過一遍
        # 把輸入和輸出打包在一起,成為樣本的列表[(input_vec, label), ...]
        # 而每個(gè)訓(xùn)練樣本是(input_vec, label)
        samples = zip(input_vec,labels)
        #對(duì)每個(gè)樣本按照感知器規(guī)則更新權(quán)重
        for (input_vec,label) in samles:
            #計(jì)算感知器當(dāng)前權(quán)重下的輸出
            out = self.predict(input_vec)
            #更新權(quán)重
            self._update_weights(input_vec,output,label,rate)
    def _update_wights(self,input_vec,output,label,rate):
        #按照感知器規(guī)則更新權(quán)重
        # 把input_vec[x1,x2,x3,...]和weights[w1,w2,w3,...]打包在一起
        # 變成[(x1,w1),(x2,w2),(x3,w3),...]
        # 然后利用感知器規(guī)則更新權(quán)重
        delta = label - output
        self.wights = map(
            lambda:(x,w):w+rate*delta*x,
            zip(input_vec,self.weights))
        #更新bias
        self.bias+=rate*delta
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容