感知机是一种二类分类的线性分类器,属于判别模型(另一种是生成模型)。简单地说,就是通过输入特征,利用超平面,将目标分为两类。感知机是神经网络和支持向量机的基础。现实过程如下:
1.感知器模型结构
此例模型的输入量有三个x1、x2和偏置量bias=1.0,W1、W2、W3为输入量的权重系数,f(x)为激活函数,用于判断样本类型,实际上是一个三值化的输入函数,如图所示。我们希望所有样本为1的类别,输出值为1,样本为-1的类别,输出值为-1.
2.感知器的算法
(1)初始权重值,如w=[0.75,0.6,0.5],本例中为随机生成。
(2)根据权重公式f(x)=x1*W1+x2*W2+bias*W3计算出输出值,如果输出值不符合预期,则对权重系数进行调整。
(3)权重参数调整:△Wi=λ(d-f(x))*xi
即将预期结果d与激活函数输出结果做差,得到误差值,由于误差是由于输入引起的,因此将输入xi与误差值的乘积做为误差调整量。为了避免因一次调整量过大,加入λ做为调整量的因子,也被称为学习率,一般是一个0.1左右的小数值,不宜取值太大。则新的权重值为:
W=Wi+△Wi
(4)重复(2)-(3)步骤,将训练所有样本。
(5)检验训练结果
3.Python感知器的实现
1 '''利用高斯白噪声生成基于某个直线附近的若干个点 2 y=wb+b 3 weight 直线权重 4 bias 直线偏置 5 size 点的个数 6 ''' 7 import numpy as np 8 9 10 def random_point_nearby_line(weight, bias, size=10): 11 x_point = np.linspace(-1, 1, size)[:, np.newaxis] 12 noise = np.random.normal(0, 0.5, x_point.shape) 13 y_point = weight * x_point + bias + noise 14 15 input_arr = np.hstack((x_point, y_point)) 16 return input_arr 17 18 19 # 直线的真正参数 20 real_weight = 1 21 real_bias = 3 22 size = 100 23 24 # 输入数据标签 25 # 生成输入的数据 26 input_point = random_point_nearby_line(real_weight, real_bias, size) 27 label = np.sign(input_point[:, 1] - (input_point[:, 0] * real_weight + real_bias)).reshape((size, 1)) 28 29 # 分割数据,15个为测试样本,其余为训练样本 30 from sklearn.model_selection import train_test_split 31 testSize = 15 32 x_train, x_test, y_train, y_test = train_test_split(input_point, label, test_size=testSize) 33 34 trainSize = size - testSize 35 36 37 # 初始化W,b 38 Weight = np.random.rand(2, 1) # 随机生成一个-1到1的数据 39 Weight = [0.75, 0.6, -0.6] # 随机生成一个-1到1的数据 40 Bias = 1 # 初始化为0 41 42 43 def trainByStochasticGradient(input, output, x_test, y_test, test_size, input_num, train_num=1000, learning_rate=1): 44 global Weight, Bias 45 x = input 46 y = output 47 for rounds in range(train_num): 48 for i in range(input_num): 49 x1, x2 = x[i] 50 prediction = np.sign(Weight[0] * x1 + Weight[1] * x2 + Bias * Weight[2]) 51 if y[i] * prediction <= 0: 52 Weight[0] = Weight[0] + learning_rate * (y[i] - prediction) * x1 53 Weight[1] = Weight[1] + learning_rate * (y[i] - prediction) * x2 54 # Bias = Bias + learning_rate * (y[i] -prediction)* 55 Weight[2] = Weight[2] + learning_rate * (y[i] - prediction) * Bias 56 57 if rounds % 10 == 0: 58 # learning_rate *= 0.9 59 accuracy = compute_accuracy(x_test, y_test, test_size, Weight, Bias) 60 print("迭代次数{},测试精度{}".format(rounds, accuracy)) 61 62 # 测试样本 63 64 65 def compute_accuracy(x_test, y_test, test_size, weight, bias): 66 x1, x2 = np.reshape(x_test[:, 0], (test_size, 1)), np.reshape(x_test[:, 1], (test_size, 1)) 67 prediction = np.sign(y_test * (x1 * weight[0] + x2 * weight[1] + bias * Weight[2])) 68 count = 0 69 70 for i in range(prediction.size): 71 if prediction[i] > 0: 72 count = count + 1 73 return (count + 0.0) / test_size 74 75 76 trainByStochasticGradient(x_train, y_train, x_test, y_test, testSize, 85, train_num=400, learning_rate=0.6) 77 78 # 绘制样本及超平面 79 import matplotlib.pyplot as plt 80 fig = plt.figure("感知机(二分类器)") 81 82 # fig.title = "感知机(二分类器)" 83 ax = fig.add_subplot(1, 1, 1) 84 for i in range(y_train.size): 85 if y_train[i] == 1: 86 ax.scatter(x_train[i, 0], x_train[i, 1], color='r') 87 else: 88 ax.scatter(x_train[i, 0], x_train[i, 1], color='b') 89 # 绘制超平面 90 x = [-1, 1] 91 y = [(-Weight[2] * Bias + Weight[0]) / Weight[1], (-Weight[2] * Bias - Weight[0]) / Weight[1]] 92 ax.plot(x, y, color='g') 93 plt.show()
4.运行结果