單層感知器 - 坐標點二分類問題


單層感知器是神經網絡的入門常識,基本的單層感知器可以解決線性分類問題。這里我們通過實例體驗感知器是如何運作的。本次實例參照教材《MATLAB神經網絡原理與實例精解》。

單層感知器的基本結構

單層感知器基本結構

如圖,單層感知器可以有多個輸入,它們通過與權值相乘,再相加(即加權求和)后,經過一定的偏置,再由激活函數處理,最后輸出得到預測結果。這里面存在兩種變化:線性變化與非線性變化。其中,加權求和屬於線性變化,激活函數做的是非線性變化。通過上述兩種變化 ,可以把輸入的數據空間扭曲,使得只需要一個超平面就可以將其分開(線性可分),從而達到分類的目的。

單層感知器的工作原理

單層感知器工作原理

與其他的優化算法一樣,感知器做的工作就是不斷的調整權值,使得輸入的數據空間扭曲到適當的程度,然后再利用超平面一刀切開,達到二分類的效果。所有的算法都會有一個迭代終止指標,對於單層感知器來說,當輸出的預測值與期望值之間的誤差達到一定的精度要求,或者迭代次數超過一定的次數時(計算機也不可以無限的運行下去),算法結束。

單層感知器解決坐標的二分類問題

我們給出6個點的坐標,並給每個點的坐標設置分類,標簽為0(第一類)和1(第二類)。利用單層感知器,找到一個超平面(就是一根直線)將兩類坐標分開(即兩類坐標分別處在直線的兩邊)。

六坐標二分類問題

代碼實現

Python代碼

import numpy as np
import matplotlib.pyplot as plt

# 參數初始化
n = 0.2  # 學習率
w = np.array([0, 0, 0])  # 權值
p = np.array([[-9,  1, -12, -4,  0, 5],
              [15, -8,   4,  5, 11, 9]])   # 坐標
d = np.array([0, 1, 0, 0, 0, 1])  # 坐標分類標簽
P = np.vstack((np.ones((1, 6)), p))  # 輸入矩陣
MAX = 20    # 最大迭代次數
ee = []    # 誤差
i = 0  # 記錄迭代次數


# 定義激活函數
def hardlim(a):
    for i in range(len(a)):
        if a[i] >= 0:
            a[i] = 1
        else:
            a[i] = 0
    return a


# 定義平均絕對誤差
def mae(a):
    return sum(abs(a))/len(a)


while 1:
    v = np.matmul(w, P)
    y = hardlim(v)  # 實際輸出
    # 更新
    e = (d - y)
    ee.append(mae(e))
    if ee[i] < 0.001:
        print('we have got it:')
        print(w)
        break
    w = w + n*np.matmul(d-y,P.T)
    i = i + 1
    if i >= MAX:
        print('MAX times loop')
        print(w)
        print(ee[i])
        break

# 畫圖
plt.figure()
plt.rcParams['font.sans-serif'] = ['Simhei']
plt.rcParams['axes.unicode_minus'] = False
plt.subplot(211)
plt.xlim(-13, 6)
plt.ylim(-10, 16)
plt.plot([-9, -12, -4, 0], [15, 4, 5, 11], 'o', label='第一類')
plt.plot([1, 5], [-8, 9], '*', label='第二類')
plt.legend(loc='lower right')
plt.title('6個坐標點的二分類')
x = np.arange(-13, 6, 0.2)
y = x * (-w[1]/w[2]) - w[0]/w[2]
plt.plot(x, y)

plt.subplot(212)
x = np.arange(0,len(ee))
plt.plot(x, ee, 'o-')
plt.title('mae的值(迭代次數:%.0f)'%len(ee))
plt.subplots_adjust(wspace =0, hspace =0.5)
plt.show()

輸出畫面

Python輸出畫面

Matlab代碼

% perception_hand.m
%% 清理
clear,clc
close all

%%
n=0.2;                  % 學習率
w=[0,0,0]; 
P=[ -9,  1, -12, -4,   0, 5;...
   15,  -8,   4,  5,  11, 9];
d=[0,1,0,0,0,1];        % 期望輸出

P=[ones(1,6);P];
MAX=20;                 % 最大迭代次數為20次
%% 訓練
i=0;
while 1
    v=w*P; 
    y=hardlim(v);       % 實際輸出
    %更新
    e=(d-y);
    ee(i+1)=mae(e);
    if (ee(i+1)<0.001)   % 判斷
        disp('we have got it:');
        disp(w);
        break;
    end
    % 更新權值和偏置
    w=w+n*(d-y)*P';
    
    if (i>=MAX)         % 達到最大迭代次數,退出
        disp('MAX times loop');
        disp(w);
        disp(ee(i+1));
       break; 
    end
    i= i+1;
end


%% 顯示
figure;
subplot(2,1,1);         % 顯示待分類的點和分類結果
plot([-9 ,  -12  -4    0],[15, 4   5   11],'o');
hold on;
plot([1,5],[-8,9],'*');
axis([-13,6,-10,16]);
legend('第一類','第二類');
title('6個坐標點的二分類');
x=-13:.2:6;
y=x*(-w(2)/w(3))-w(1)/w(3);
plot(x,y);
hold off;

subplot(2,1,2);         % 顯示mae值的變化
x=0:i;
plot(x,ee,'o-');
s=sprintf('mae的值(迭代次數:%d)', i+1);
title(s);

輸出畫面

Matlab輸出畫面


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM