感知机(perceptron)是机器学习中一种经典的线性分类模型, 是一种最简单的前馈神经网络. 它的基本思想是在 n 维空间中利用超平面对(线性可分的)两类数据进行分割. 下面我们先看感知机的数学定义:
数学定义与几何意义
设 X ∈ R n \mathcal{X} \in \mathbb{R}^n X∈Rn 为输入空间, Y = { − 1 , 1 } \mathcal{Y}=\{-1, 1\} Y={
−1,1} 为输出空间. 对于实例 ( x , y ) (x, y) (x,y), 其中 x ∈ X x \in \mathcal{X} x∈X 为 n 维特征向量, y ∈ Y y \in \mathcal{Y} y∈Y 为其对应的类别. 函数族
F = { f : X → Y ∣ f = s i g n ( w ⋅ x + b ) , w ∈ R n , b ∈ R } \mathcal{F}=\{f: \mathcal{X} \rightarrow \mathcal{Y} | f=sign(w \cdot x + b), w \in \mathbb{R}^n, b\in \mathbb{R} \} F={
f:X→Y∣f=sign(w⋅x+b),w∈Rn,b∈R}
中的函数即为感知机, 而它们全体构成了(由感知机函数组成的)假设空间 F \mathcal{F} F.
几何角度上来讲, 感知机模型是通过寻找 n 维空间中的某个法向量为 w w w , 截距为 b b b 的超平面(其由线性方程 w ⋅ x + b = 0 w \cdot x + b = 0 w⋅x+b=0来确定), 将所有位于输入空间中的实例点(由特征向量表示)分成两部分, 位于超平面正侧的点给予+1的预测值, 背侧的点给予-1的预测值.
当然我们也会从以上描述发现, 本质上分离超平面是一个线性函数, 当输入空间中正实例点与负实例点线性不可分时, 感知机模型将出现问题, 例如在训练过程中算法不收敛等. 这时就需要用到一些其他的方法(如非线性模型)或技巧(如SVM中的核函数).
模型构建与训练
为了使接下来的讨论有意义, 我们不妨先假设训练集中的两类实例点是线性可分的, 即存在某个超平面 S S S
S = { x ∈ R n ∣ w ⋅ x + b = 0 w ∈ R n , b ∈ R } S = \{x \in \mathbb{R}^n | w \cdot x + b = 0 \quad w \in \mathbb{R}^n, b \in \mathbb{R}\} S={
x∈Rn∣w⋅x+b=0w∈Rn,b∈R}
使得对于任意的 x ∈ X x \in \mathcal{X} x∈X, 若其对应 y = 1 y = 1 y=1, 则有 w ⋅ x + b > 0 w \cdot x + b> 0 w⋅x+b>0; 若其对应 y = − 1 y = -1 y=−1, 则有 w ⋅ x + b < 0 w \cdot x + b< 0 w⋅x+b<0.
接着我们要考虑损失函数. 最简单的损失函数定义方法是对误分类点进行计数, 但这种损失函数同时面临两个问题: 首先计数函数关于训练参数 w , b w, b w,b 不可导, 这意味着我们无法采用最经典的梯度下降方法来对损失函数进行优化; 其次是计数损失函数并不能完全反映当前模型的优劣, 因为其完全忽略了实例点与分离超平面的距离而只考虑分类正确与否(我们可以很容易想到, 当一个误分类点距离分离超平面越远, 意味着错误"越离谱", 我们当然需要给予严重的错误更大的惩罚, 而不是将所有误分类点一视同仁).
很自然地, 我们想到要利用实例点到分离超平面的距离来定义损失函数. 对于已经分类正确的点, 当然不会有什么"损失", 我们只需考虑那些误分类点即可.对于空间中任意一点 x 0 x_0 x0, 其到超平面 w ⋅ x + b = 0 w \cdot x + b =0 w⋅x+b=0 的距离为
1 ∣ ∣ w ∣ ∣ ∣ w ⋅ x + b ∣ \frac{1}{||w||} |w \cdot x + b| ∣∣w∣∣1∣w⋅x+b∣
将所有误分类点到分离超平面的距离相加, 我们得到损失函数 L L L :
L ( w , b ) = − 1 ∣ ∣ w ∣ ∣ ∑ x i ∈ M y i ( w ⋅ x + b ) L(w, b) = - \frac{1}{||w||} \sum_{x_i \in M} y_i (w \cdot x + b) L(w,b)=−∣∣w∣∣1xi∈M∑yi(w⋅x+b)
其中 M M M 为所有误分类点的集合. 注意到上式中我们用到一点小技巧, 通过与 y y y 相乘, 在保证值没有发生改变的前提下, 移除了原先距离公式中出现的绝对值符号, 极大方便了后续利用梯度下降进行优化.
同时我们可以发现, 移除掉上式中的 1 ∣ ∣ w ∣ ∣ \frac{1}{||w||} ∣∣w∣∣1 也是完全可以的. 这是因为, 作为一个优化问题, 感知机算法的解可能并不唯一, 而只要满足条件的解存在, 那么这个解所对应的损失函数的值必定为0 (即所有实例点都被正确分类), 也就是说如果最后算法能收敛到理想的结果, 作为系数的 1 ∣ ∣ w ∣ ∣ \frac{1}{||w||} ∣∣w∣∣1 其实无关紧要. 因此为了方便我们之后的叙述中将它去掉. 当然我们会在之后给出严格的证明, 来确保当两类实例点线性可分时, 去掉这个系数后, (随机)梯度下降方法依旧合理且有效.
直观来看, 上面这个损失函数符合我们的期待: 首先函数值非负; 其次, 误分类点越多、误分类点距离分离超平面越远, 损失函数也相应增大, 反之损失函数则减小. 事实上, 我们也可以把感知机的损失函数看作是对所有实例点的合页损失函数(hinge-loss)求和而得.
构建好损失函数, 接下来就是对其进行优化直到其达到最小值. 通常采用的做法是利用随机梯度下降: 对于当前的分离超平面(或者说当前参数 w , b w, b w,b)进行更新, 若无误分类点, 则损失函数为0, 已经达到最优; 否则从误分类点中任意选取一个, 计算该实例点对当前损失函数的梯度的"贡献值", 从而得到一个方向, 然后我们将参数 w , b w, b w,b 沿该方向的反方向移动来降低损失函数的值.
注意到对于之前定义的损失函数 L L L 以及当前的误分类点集 M M M, 损失函数的梯度为
∇ w L ( w , b ) = − ∑ x i ∈ M y i x i ∇ b L ( w , b ) = − ∑ x i ∈ M y i \begin{aligned} \nabla_w L(w, b) &= - \sum_{x_i \in M} y_i x_i \\ \nabla_b L(w, b) &= - \sum_{x_i \in M} y_i \end{aligned} ∇wL(w,b)∇bL(w,b)=−xi∈M∑yixi=−xi∈M∑yi
而对于某个随机选取的误分类点 ( x i , y i ) (x_i, y_i) (xi,yi), 容易看出其对损失函数的梯度贡献为 ( − y i x i , − y i ) (-y_i x_i, -y_i) (−yixi,−yi). 因此, 在依据此误分类点更新分离超平面参数时, 我们有
w n e w = w o l d + η y i x i b n e w = b o l d + η y i \begin{aligned} w_{new} &= w_{old} + \eta y_i x_i \\ b_{new} &= b_{old} + \eta y_i \end{aligned} wnewbnew=wold+ηyixi=bold<