前言
本文主要针对双月数据集实现二分类问题。
一、单层感知机
单层感知机目标是将被感知数据集划分为两类的分离超平面,并计算出该超平面。单层感知机是二分类的线性分类模型,输入是被感知数据集的特征向量,输出时数据集的类别{+1,-1}。感知器的模型可以简单表示为:
该函数称为单层感知机,其中w是网络的N维权重向量,b是网络的N维偏置向量, w.x是w和x的内积,w和b的N维向量取值要求在实数域。
本文是将感知机模型简化,将权值b合并到w里进行更新,简化了计算。
sign函数是感知机的早期激活函数,后面又演化出一系列的激活函数。激活函数一般采用非线性激活函数,以增强网络的表达能力。常见的激活函数有:sign, sigmoid,tanh,ReLU等。
二、双月数据集
根据圆的参数方程,设置圆的角度与双月宽度两个随机参数生成双月数据点集。
初始值为:
N = 1000 # 单个月亮数据集数据量
w = 2
r = 8
d = 1
iter = 50 # 迭代次数
learning_rate = 0.001 # 学习率
wn = np.array([1,0,0])
def moon(N,w,r,d):
'''
# :param w: 半月宽度
# :param r: x轴偏移量
# :param d: y轴偏移量
# :param N: 半月散点数量
:return: data (2*N*3) 月亮数据集
data_dn (2*N*1) 标签
'''
data = np.ones((2*N,4))
# 半月1的初始化
r1 = 10 # 半月1的半径,圆心
w1 = np.random.uniform(-w / 2, w / 2, size=N) # 半月1的宽度范围
theta1 = np.random.uniform(0, np.pi, size=N) # 半月1的角度范围
x1 = (r1 + w1) * np.cos(theta1) # 行向量
y1 = (r1 + w1) * np.sin(theta1)
label1 = [1 for i in range(1,N+1)] # label for Class 1
# 半月2的初始化
r2 = 10 # 半月1的半径,圆心
w2 = np.random.uniform(-w / 2, w / 2, size=N) # 半月1的宽度范围
theta2 = np.random.uniform(np.pi, 2 * np.pi, size=N) # 半月1的角度范围
x2 = (r2 + w2) * np.cos(theta2) + r
y2 = (r2 + w2) * np.sin(theta2) - d
label2 = [-1 for i in range(1,N+1)] # label for Class 2
data[:,1] = np.concatenate([x1, x2])
data[:,2] = np.concatenate([y1, y2])
data[:,3] = np.concatenate([label1, label2])
return data
三、程序
1.引入库
import numpy as np
import matplotlib.pyplot as plt
# from sklearn.cross_validation import train_test_split #用于分割数据。
from sklearn.model_selection import train_test_split
# ##################### 添加图片文字 ###########################################
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimSun'] # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
# ############################################################################
2.主函数
if __name__ == '__main__':
# 初始化参数
N = 1000 # 单个月亮数据集数据量
w = 2
r = 8
d = 1
iter = 50 # 迭代次数
learning_rate = 0.001 # 学习率
wn = np.array([1,0,0])
data = moon(N,w,r,d)
'''随机采用20%的数据用于测试,剩下的80%用于构建训练集合'''
data_train,data_test,dn_train,dn_test=train_test_split(data[:,1:3],data[:,3],test_size=0.20,random_state=None)
'''训练数据调整'''
train_data = np.ones((1600,3))
train_data[:,1:3] = data_train
train_dn = dn_train
'''迭代 训练 寻找最优解wn'''
loss,wn = train(train_data,train_dn,wn,iter,learning_rate)
print(wn) # 最优解wn
'''测试数据调整'''
test_data = np.ones((400,3))
test_data[:,1:3] = data_test
test_dn = dn_test
'''测试'''
err,acc = test(test_data,test_dn)
print('测试结果 错误率:','%.2f'%err)
print('测试结果 正确率:','%.2f'%acc)
'''决策平面 y+wx+b=0'''
x = np.array(range(-15,25))
y = -x*wn[1]/wn[2]-wn[0]/wn[2]
'''月亮数据集'''
plt.figure()
plt.title('月亮数据集', size=14)
plt.xlabel('x 轴', size=14)
plt.ylabel('y 轴', size=14)
plt.grid(ls=':', color='gray', alpha=0.5) # alpha是透明度
plt.scatter(data[0:N,1],data[0:N,2],c='b',s=20,marker='+')
plt.scatter(data[N:2*N,1],data[N:2*N,2],c='r',s=20,marker='+')
plt.plot(x,y,'k--')
plt.savefig('./月亮数据集.png')
'''损失函数'''
x = [i for i in range(len(loss))]
plt.figure()
plt.title('损失函数曲线图', size=14)
plt.xlabel('迭代次数', size=14)
plt.ylabel('均方误差', size=14)
# plt.grid(ls=':', color='gray', alpha=0.5) # alpha是透明度
plt.plot(x,loss,c='r',linewidth=2,linestyle='-',marker='o')
plt.savefig('./损失函数.png')
plt.show()
总结
从N=1000*2个点中随机选取80%的点作为训练集,20%的点作为测试集。迭代50次后,返回最优值wn,测试结果的错误率与正确率:
[ 0.656 -0.01167188 0.66452531]
测试结果 错误率: 0.00
测试结果 正确率: 1.00
画出决策平面与损失函数,如图:
完整程序
https://download.csdn.net/download/weixin_43816216/62520810