感知机-梯度下降

前言 近期跟随课程进度,学习简单地深度学习部分算法,我将以笔记和感悟的形式记录这一段学习过程,有不当之处欢迎各位批评指正。
简介 形象感知
接触过了一点学习算法之后,大致上可以分为两类。一类是依赖概率模型,一类依赖判别模型,本次学习的感知机属于非常简单的判别模型。它可以用于线性关系的二分类问题,比如我们制作一个分类器,该分类器用于将人的身材进行简单分类,最终分类的类型只有胖或者瘦两种结果。该分类器依赖于两个参数进行分类,身高和体重。那么在一定粗略的程度上,我们大致认为,越高越轻则人越瘦。那么我们可以用这样一个式子表示 y = a * 身高 + b * 体重 + c ,若y >0,则判断此人为瘦。我们希望人越高,越轻,则 y 越可能大于0,那么此模型应该是合理的。那么我们怎样找到合适的参数a,b,c呢?对于上述这个例子,当然存在很大的主观性,但是对于很多分类问题,事实上是很客观的,我们需要找到一组合适的参数让这个分类器更加准确和稳定。那么我们怎样找到一组合理的参数呢?不要着急,我们先弄明白背后的模型推导,这些问题就会一步步得到解决。
公式解释
【感知机-梯度下降】其实看明白上一个例子,应该就不难理解了。我们不妨将信号X取的小一点,我们取二维向量x[ x0,x1 ]^T作为特征向量,类比身高体重两个参数 w[w0,w1]作为权重系数,类似于a,b两个参数,为了引入sign(x)这个函数方便表示,我们添加一项 b,称为偏置,不难理解选取合适的偏置,我们可以得到一个以0为标准的结果。
模型 假设输入空间(特征向量)是X,输出空间为Y。输出Y表示实例的类别,则由输入空间到输出空间的表达形式为:
感知机-梯度下降
文章图片

其中sign是一个符号函数
感知机-梯度下降
文章图片

推导 关于找到合适的参数,我们首先想到的是采用试参法,在所举例子中或许我们不难得到一组较为合理的参数,但是大多数时候我们是很难通过人工试凑得到合理参数的,尤其是特征空间很大时。所以我们将采用梯度下降法找到合理参数。下面是数学推导,事实上并不麻烦,如果觉得这一部分过于繁琐,那么也可以直接选择跳过,只要你坚信,这一过程是正确的。
首先,我们需要构建一个Lossfunction 来评价一套参数的好坏,比如我们期望损失函数越小,这套参数的表线更优秀。
承接上个标题 模型 中的例子,我们试图在平面直角坐标系中给几个点分类,当然首先我们已经知道这几个点的类别,我们的工作是找出一套合适的参数让这个分类更科学。感知机-梯度下降
文章图片

就像紫色部分覆盖的两个点是我们默认的一类,绿色点是另一类。深紫色的线即为我们所需要找出的那一套合理的参数了。
那么我们选取什么作为损失函数呢?
我们可以直观的了解,其实存在无数条直线可以将这三个点正确的划分为两类,也即我们可也找到无数套参数。不难想到,在算法进行之初,我们未必能一次就找到合适的参数,我们可以用误分类点的数目来作为损失函数,误分类点个数越来越少时,表示参数越来越合理,但不妙的是我们无法用函数或者模型的形式给出错误分类的个数,因为它不具有规律性。
在这里,提供一种思路,我们采用当前错误分类点数到所找到的直线(也即参数)的距离来表示损失函数,自然当错误分类数达到0时,损失函数也就最小了。下面这个公式完全可以类比高中数学平面几何知识 点到直线的距离。
感知机-梯度下降
文章图片

那么下一个问题来了,哪些点是被我们当前错误分类的呢?
感知机-梯度下降
文章图片

yi是我们实现划分好的类别,可以理解为我们对一个人事先做好的胖瘦的评价。而 w * x + b是当前参数得到的结果,我们不关心数值,我们关心其符号,不难发现只要是被误判的点,都符合上边的式子。
那么误分类点的距离就是感知机-梯度下降
文章图片

进一步简化,我们将分母部分去掉,得到下式。
感知机-梯度下降
文章图片

再往下,我们需要用到梯度下降法进行参数的更新了,首先我们需要对参数求偏导数。
感知机-梯度下降
文章图片

选择一个误分类点(xi, yi),L(w,b)=-yi(w·xi+b),▽wL(w,b)=-yixi,▽bL(w,b)=-yi,对w和b进行更新:
感知机-梯度下降
文章图片

实现 算法叙述
1.导入训练数据,初始化参数 w[w0 w1],b
2.从训练数据集中摘取数据,判断其是否是错误分类的点
3.如果被错误分类,则更新w[w0 w1] 和b,如果没有被错误分类,跳过,进行4
4.转到2,直到不存在被错误分类的点。
代码实现(python)
话不多说,上代码

training_data = [[(3, 6), 1], [(4, 2), 1], [(2, 1), -1]] w = [0, 0] b = 0 # 判断是否是错误分类的点 def YN(data): global w,b result = 0 for i in range(len(data[0])): result += data[0][i] * w[i]# res = x0 * w0 + x1 + w1 result = ( result + b ) * data[1] # res = yi * ( x0 * w0 + x1 + w1 +b ) return result# 梯度下降法 def update(data): global w,b w[0] = w[0] + 1 * data[1] * data[0][0]# w0 = w0 + n * yi * x0 w[1] = w[1] + 1 * data[1] * data[0][1]# w1 = w1 + n * yi * x1 b = b + 1 * data[1]# b = b + n * yi# 检查每个点是否被正确分类 def check(): flag = False for data in training_data: if YN(data) <= 0:# 非正的即为错误分类的数据 flag = True update(data) if not flag: print ('w:' + str(w) + ' b:'+ str(b)) flag = Falsefor i in range(10): check()

输出结果
感知机-梯度下降
文章图片

用图形计算器作图得到
感知机-梯度下降
文章图片

可见,该分类器已经找到了一套合适的参数。

    推荐阅读