機器學習第5章第2節 : LMS算法

LMS算法-邏輯或運算

思路

LMS算法全稱爲 least mean square 算法,中文名叫最小均方算法.在ANN領域,均方誤差是指樣本預測輸出值與實際輸出值只差的平方的期望值,記爲MSE.設observed爲樣本真值,predicted爲預測值,計算公式如下:
mse

LMS的算法策略是使均方誤差最小,該算法運行在一個線性神經元上,使用的是批量修正算法,其誤差信號爲:
err(n)

然後在誤差信號的基礎上計算梯度向量,公式如下:
vdelta

最後,生成權值調整方案,公式如下:
update_weight
在上面的公式中,η代表學習率,該值越小,LMS算法執行的越精確,但同時算法的收斂速度越慢.

代碼

# -*- coding: utf-8 -*-
"""
Created on Thu Dec  7 14:06:09 2017

@author: Oscar

LMS算法實現邏輯或運算
"""

import numpy as np

#學習速率
learn_speed = 0.1

#偏置
b = 1

#學習的數據
x = np.array([
        [1,1,1],
        [1,1,0],
        [1,0,1],
        [1,0,0]
        ])

#期望輸出,對應的是學習數據的真假
d = np.array([1,1,1,0])

#權值
weight = np.array([b,0,0])

#最小誤差信號值
min_error_signal = 0.005

#最大學習次數
max_try_count = 20

#感知函數
def sgn(v):
    if v > 0:
        return 1
    else:
        return 0

#拿到感知器的返回值
def get_sgn(current_weight,current_x):
    #當前權值矩陣轉置後與當前的學習的數據進行矩陣相乘,得到一個實數,然後調用sgn函數得到感知器的返回值
    return sgn(np.dot(current_weight.T,current_x))

#獲取誤差信號
def get_error_signal(current_weight,current_x,current_d):
    return current_d - get_sgn(current_weight,current_x)

#權值更新
def update_weight(old_weight,current_d,current_x,learn_speed):
    current_error_signal = get_error_signal(old_weight,current_x,current_d)
    return (old_weight + learn_speed * current_error_signal * current_x,current_error_signal)

#當前重複的次數
current_count = 0 
while True:
    error_signal = 0
    i = 0
    for xn in x:
        weight , current_error_signal = update_weight(weight,d[i],xn,learn_speed)
        i += 1
        #pow() 方法返回 xy(x的y次方) 的值。
        error_signal += pow(current_error_signal,2)
    error_signal /= float(i)
    current_count += 1

    print("第",current_count,"次調整後的權值爲:",weight,"  誤差信號值爲:",error_signal)
    #噹噹前的誤差信號值精度小於最小的誤差信號值精度的時候
    #或者當調整次數大於最大的調整次數的時候
    #跳出循環
    if error_signal < min_error_signal or current_count > max_try_count : break

#訓練完成,開始檢驗
for xn in x:
    print("當前數據:",xn,",當前分類:",xn[1],"與",xn[2],"進行邏輯或運算,被分類爲:",get_sgn(weight,xn))

運行結果

第 1 次調整後的權值爲: [ 0.9  0.   0. ]   誤差信號值爲: 0.25
第 2 次調整後的權值爲: [ 0.8  0.   0. ]   誤差信號值爲: 0.25
第 3 次調整後的權值爲: [ 0.7  0.   0. ]   誤差信號值爲: 0.25
第 4 次調整後的權值爲: [ 0.6  0.   0. ]   誤差信號值爲: 0.25
第 5 次調整後的權值爲: [ 0.5  0.   0. ]   誤差信號值爲: 0.25
第 6 次調整後的權值爲: [ 0.4  0.   0. ]   誤差信號值爲: 0.25
第 7 次調整後的權值爲: [ 0.3  0.   0. ]   誤差信號值爲: 0.25
第 8 次調整後的權值爲: [ 0.2  0.   0. ]   誤差信號值爲: 0.25
第 9 次調整後的權值爲: [ 0.1  0.   0. ]   誤差信號值爲: 0.25
第 10 次調整後的權值爲: [  1.38777878e-16   0.00000000e+00   0.00000000e+00]   誤差信號值爲: 0.25
第 11 次調整後的權值爲: [-0.1  0.   0. ]   誤差信號值爲: 0.25
第 12 次調整後的權值爲: [-0.1  0.1  0.1]   誤差信號值爲: 0.5
第 13 次調整後的權值爲: [-0.1  0.1  0.1]   誤差信號值爲: 0.0
當前數據: [1 1 1] ,當前分類: 1 與 1 進行邏輯或運算,被分類爲: 1
當前數據: [1 1 0] ,當前分類: 1 與 0 進行邏輯或運算,被分類爲: 1
當前數據: [1 0 1] ,當前分類: 0 與 1 進行邏輯或運算,被分類爲: 1
當前數據: [1 0 0] ,當前分類: 0 與 0 進行邏輯或運算,被分類爲: 0

LMS算法-二值分類

思路

應用LMS算法實現比邏輯或更復雜的算法,比如:在輸入矩陣中,如果x向量的整除結果爲6,則表示一類,輸出爲1;如果整除結果爲3,則表示另一類,輸出爲-1.

代碼

# -*- coding: utf-8 -*-
"""
Created on Thu Dec  7 15:17:13 2017

@author: Oscar
使用LMS算法實現在輸入矩陣中,如果x向量的整除結果爲6,則表示一類,輸出爲1;
                          如果整除結果爲3,則表示另一類,輸出爲-1.
"""

import numpy as np

#學習速率
learn_speed = 0.1

#偏置
b = 1

#學習的數據
x = np.array([
        [1,1,6],    #1
        [1,2,12],   #1
        [1,3,9],    #-1
        [1,8,24]    #-1
        ])

#測試數據
test_data1 = np.array([1,9,27]) #-1
test_data2 = np.array([1,11,66])#1

#期望輸出,對應的是學習數據的真假
d = np.array([1,1,-1,-1])

#權值
weight = np.array([b,0,0])

#最小誤差信號值
min_error_signal = 0.005

#最大學習次數
max_try_count = 20

#感知函數
def sgn(v):
    if v > 0:
        return 1
    else:
        return -1

#拿到感知器的返回值
def get_sgn(current_weight,current_x):
    #當前權值矩陣轉置後與當前的學習的數據進行矩陣相乘,得到一個實數,然後調用sgn函數得到感知器的返回值
    return sgn(np.dot(current_weight.T,current_x))

#獲取誤差信號值
def get_error_signal(current_weight,current_x,current_d):
    return current_d - get_sgn(current_weight,current_x)

#權值更新
def update_weight(old_weight,current_d,current_x,learn_speed):
    current_error_signal = get_error_signal(old_weight,current_x,current_d)
    return (old_weight + learn_speed * current_error_signal * current_x,current_error_signal)

#當前重複的次數
current_count = 0 
while True:
    error_signal = 0
    i = 0
    for xn in x:
        weight , current_error_signal = update_weight(weight,d[i],xn,learn_speed)
        i += 1
        #pow() 方法返回 xy(x的y次方) 的值。
        error_signal += pow(current_error_signal,2)
    error_signal /= float(i)
    current_count += 1

    print("第",current_count,"次調整後的權值爲:",weight,"  誤差信號值爲:",error_signal)
    #噹噹前的誤差信號值精度小於最小的誤差信號值精度的時候
    #或者當調整次數大於最大的調整次數的時候
    #跳出循環
    if abs(error_signal) < min_error_signal or current_count > max_try_count : break

#訓練完成,開始檢驗
for xn in x:
    print("當前數據:",xn,",當前分類:",xn[1],"與",xn[2],"進行分類,被分類爲:",get_sgn(weight,xn))

#開始測試
print("測試數據爲:",test_data1,",被分類爲:",get_sgn(weight,test_data1))
print("測試數據爲:",test_data2,",被分類爲:",get_sgn(weight,test_data2))

運行結果

1 次調整後的權值爲: [ 0.8 -0.6 -1.8]   誤差信號值爲: 1.02 次調整後的權值爲: [  1.00000000e+00  -6.00000000e-01   4.44089210e-16]   誤差信號值爲: 3.03 次調整後的權值爲: [ 0.8 -2.4 -4.2]   誤差信號值爲: 3.04 次調整後的權值爲: [ 1.2 -1.8 -0.6]   誤差信號值爲: 2.05 次調整後的權值爲: [ 1.2 -2.2 -1.2]   誤差信號值爲: 2.06 次調整後的權值爲: [ 1.4 -2.2  0.6]   誤差信號值爲: 3.07 次調整後的權值爲: [ 1.2 -2.8 -1.2]   誤差信號值爲: 1.08 次調整後的權值爲: [ 1.4 -2.8  0.6]   誤差信號值爲: 3.09 次調整後的權值爲: [ 1.4 -2.8  0.6]   誤差信號值爲: 0.0
當前數據: [1 1 6] ,當前分類: 16 進行分類,被分類爲: 1
當前數據: [ 1  2 12] ,當前分類: 212 進行分類,被分類爲: 1
當前數據: [1 3 9] ,當前分類: 39 進行分類,被分類爲: -1
當前數據: [ 1  8 24] ,當前分類: 824 進行分類,被分類爲: -1
測試數據爲: [ 1  9 27] ,被分類爲: -1
測試數據爲: [ 1 11 66] ,被分類爲: 1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章