4.1感知机模型的基本概念
4.1.1定义
- 感知机模型是一种二分类的线性分类模型,输入k维线性空间中的向量,输出一个实例的类别(正反类别分别用+1和-1来表示),可以将这个分类过程用一个函数来表示:
%3Dsign(%5Comega%20x%20%2B%20b)%0A#card=math&code=y%3Df%28x%29%3Dsign%28%5Comega%20x%20%2B%20b%29%0A)
- 这里的参数和就是感知机的模型参数,其中,而实数b是一个偏置(bias),这里的sign函数是一个特殊的函数,当输入的x是正数或者0的时候函数值就是1,输入的x是负数的时候函数值就是-1.
4.1.2基于超平面的理解
- 可以把样本集里面的N个k维的向量看成是k维线性空间中的点,感知机的目标就是找到一个划分这个点集的超平面S,使得平面S的两侧分别是两种类型的点,后面的测试集的分类就基于测试集中数据所对应的点和超平面的位置关系来划分,在正例的一侧,反例的一侧则小于0.
- 因此感知机的学习目标就是根据样本数据学习出超平面的方程
4.1.3基于神经元的理解
- 其实感知机可以看成是一种非常简单的二层神经网络,输入层的内容是k维向量的k个特征,输出层的结果就是向量的分类情况(分为+1和-1)两种,
- 输出层的神经元存在一个阈值,如果超过了这个阈值,神经元就会被激活,神经元存在一个激活函数#card=math&code=f%28x%29),因此这个二层神经网络可以用下面的式子来表示:
%3Df(%5Comega%20x-%5Ctheta)%0A#card=math&code=y%3Df%28%5Csum_%7Bi%3D1%7D%5E%7Bk%7D%5Comega_ix_i-%5Ctheta%29%3Df%28%5Comega%20x-%5Ctheta%29%0A)
其中就是每个神经元的权重,也对应于定义式中的,而阈值则是定义中的bias的相反数,函数f被称为激活函数,可以选用sign函数,也可以选用sigmoid函数
- 这两个函数的区别是
- sign是实数域不连续的函数
- sigmoid是连续的,当选取sign函数作为激活函数的时候,这个感知机模型的表达式就和超平面的理解中完全一致
- 感知机其实就是一种简单的前馈神经网络
4.2感知机模型的求解
4.2.1损失函数loss
- 感知机的训练集必须要求是线性可分的,而感知机的的性能评估要考虑被误分类的点的情况,为了选择一个关于参数和b连续的损失函数,
- 一个比较自然的选择就是根据各个点到超平面S的距离之和,即有:
%0A#card=math&code=L%3D-%5Cfrac%7B1%7D%7B%7C%7C%5Comega%7C%7C%7D%5Csum_%7Bx_i%5Cin%20M%7Dy_i%28%5Comega%20x_i%2Bb%29%0A)
这里的M表示数据集D中被误分类的点的集合,因此感知机中的损失函数可以定义为:
%3D-%5Csum%7Bx_i%5Cin%20M%7Dy_i(%5Comega%20x_i%2Bb)%0A#card=math&code=L%28%5Comega%2C%20b%29%3D-%5Csum%7Bx_i%5Cin%20M%7Dy_i%28%5Comega%20x_i%2Bb%29%0A)
因此感知机模型的求解目标就变成了:
%3D-%5Csum%7Bx_i%5Cin%20M%7Dy_i(%5Comega%20x_i%2Bb)%0A#card=math&code=%5Cmin%20L%28%5Comega%2Cb%29%3D-%5Csum%7Bx_i%5Cin%20M%7Dy_i%28%5Comega%20x_i%2Bb%29%0A)
4.2.2基于随机梯度下降法的求解
- 对损失函数求梯度可以得到:
%3D-%5Csum%7Bx_i%5Cin%20M%7Dy_ix_i%0A#card=math&code=%5Cnabla%7B%5Comega%7DL%28%5Comega%2C%20b%29%3D-%5Csum_%7Bx_i%5Cin%20M%7Dy_ix_i%0A)
%3D-%5Csum%7Bx_i%5Cin%20M%7Dy_i%0A#card=math&code=%5Cnabla%7Bb%7DL%28%5Comega%2C%20b%29%3D-%5Csum_%7Bx_i%5Cin%20M%7Dy_i%0A)
因此可以在学习的过程中,先确定一组参数的初值,并选择好学习率,(注意学习率不能超过1),然后进行如下步骤开始学习:
- 在训练集中选取一组数据#card=math&code=%28x_i%2Cy_i%29)
- 如果这组数据是误分类的,也就是说%5Cle%200#card=math&code=yi%28%5Comega_kx_i%2Bb_k%29%5Cle%200),那么就要:![](https://g.yuque.com/gr/latex?w%7Bk%2B1%7D%3Dwk%2B%5Ceta%20y_ix_i%0A#card=math&code=w%7Bk%2B1%7D%3Dwk%2B%5Ceta%20y_ix_i%0A)
![](https://g.yuque.com/gr/latex?b%7Bk%2B1%7D%3Dbk%2B%5Ceta%20y_i%0A#card=math&code=b%7Bk%2B1%7D%3Db_k%2B%5Ceta%20y_i%0A) - 回到第二步继续循环,直到训练集中没有误分类的点,结束模型的训练
4.3 感知机的代码实现
def perceptron(X, y):
"""
PERCEPTRON Perceptron Learning Algorithm.
INPUT: X: training sample features, P-by-N matrix.
y: training sample labels, 1-by-N row vector.
OUTPUT: w: learned perceptron parameters, (P+1)-by-1 column vector.
iter: number of iterations
"""
P, N = X.shape
w = np.zeros((P + 1, 1))
iters = 0
# YOUR CODE HERE
# begin answer
learning_rate = 0.01
expand_row = np.ones((N, 1))
new_x = np.column_stack((expand_row, X.T))
while True:
iters += 1
ok = 0
for i in range(N):
predict_class = np.matmul(new_x[i], w)
# 表示该方案的分类是正确的
if y[0][i] * predict_class[0] > 0:
ok += 1
else:
w[:, 0] += new_x[i].T * y[0][i] * learning_rate
learning_rate *= 0.99
if ok == N:
break
# 测试非线性可分的数据集可能陷入死循环,设置一个上限及时退出止损
# 到这里还没退出说明数据非线性导致算法失效了
elif iters >= 200:
break
return w, iters