假设有4个2维的数据,数据的特征分别是(3,3),(4,3),(1,1),(2,1)。其中(3,3)和(4,3)这两个数据的标签为1,(1,1)和(2,1)这两个数据的标签为-1。
使用单层感知器来进行分类,如下:
import numpy as np #导入科学计算包
import matplotlib.pyplot as plt #导入画图包
'''定义输入,我们习惯上用一行代表一个数据
原始数据是4个二维数据,(3,3),(4,3)标签为1,(1,1),(2,1)标签为-1
这里我们把神经元的偏置值也设为一个节点,所以输入的数据为
(1,3,3) (1,4,3) (1,1,1) (1,2,1)
'''
X = np.array([[1,3,3],
[1,4,3],
[1,1,1],
[1,2,1]])
#定义标签,我们习惯上用一行代表一个数据的标签
T = np.array([[1],
[1],
[-1],
[-1]])
#初始化权值,权值取0-1的随机数,3行1列
#np.random.random可以生成0-1的随机数
W = np.random.random([3,1])
#设置学习率
lr=0.1
#神经网络的输出
Y= 0
#更新一次权值
def train():
#使用全局变量W
global W
#同时计算4个数据的预测值
#Y的形状为(4,1)-4行1列
Y = np.sign(np.dot(X,W)) #激活函数为sign,np.dot代表矩阵乘法
#用T-Y可以得到标签值与预测值之间的误差E,其形状为(4,1)
E = T - Y
#X.T表示X的转置矩阵,形状为(3,4)
#我们一共有4个数据,每个数据3个值,定义第i个数据的j个特征值为xij
#如第1个数据的第二个特征值为x12
#X.T.dot(T-Y)为一个3行1列的数据
#第一行等于:x00*e0+x10*e1+x20*e2+x30*e3,它会调整第一个神经元对应的权值
#第二行等于:x01*e0+x11*e1+x21*e2+x31*e3,它会调整第一个神经元对应的权值
#第三行等于:x02*e0+x12*e1+x22*e2+x32*e3,它会调整第一个神经元对应的权值
#X.shape表示X的形状,X.shape[0]得到X的行数,表示有多少个数据
#x.shape[1]得到列数,表示每个数据有多少个特征值
#这里的公式本质上和w=lr*(t-y)*x是一样的
delta_W = lr*(X.T.dot(E))/X.shape[0]
W = W + delta_W
#设置最大训练100次
for i in range(100):
#更新一次权值
train()
#打印当前的训练次数
print('epoch:',i+1)
#打印当前的权值
print('weights:',W)
#计算当前的输出
Y = np.sign(np.dot(X,W))
#.all()表示Y中的所有值跟T中的所有值都对应相等的时候结果才为真
if(Y==T).all():
print("Finished")
#跳出循环
break
#以下为画图部分
#正样本的x,y坐标
x1 = [3,4]
y1 = [3,3]
#负样本的x,y坐标
x2 = [1,2]
y2 = [1,1]
#计算分类边界线的斜率和截距
#神经网络的信号总和为
#当信号的总和大于0时,经过激活函数,模型的预测值会得到1
#当信号的总和小于0时,经过激活函数,模型的预测值会得到-1
#所以,当信号的总和w0*x0+w1*x1+w2*x2=0市,其为分类边界线表达式
#我们在画图的时候,把x1和x2分别看作平面坐标系中的x和y
#可以得到w0+w1*x+w2*y=0
#经过通分:y = -w0/w2-w1*x*/w2,因此可以得到
k = -W[1]/W[2]
d = -W[0]/W[2]
#设定两个点
xdata=(0,5) #因为x最小值为1,最大为4
#通过这两个点来确定一条直线,用红色的线画出分界线
plt.plot(xdata,xdata*k+d,'r')
#用蓝色的点画出正样本
plt.scatter(x1,y1,c ='b')
#用黄色的点画出负样本
plt.scatter(x2,y2,c='y')
#显示图案
plt.show()
训练到第9次的时候,神经网络的输出与标签一样,如图所示: