Add to favourites
News Local and Global in your language
17th of January 2018

因特网



python实现自适应线性感知器算法 - CSDN博客

原创 2017年12月20日 21:39:52

在之前的文章中有介绍过感知器,自适应线性神经网络(Adaptive Linear Neuron,Adaline)是在Frank Rosenblatt提取感知器算法之后的几年,Bernard Widrow和Tedd Hoff提出的Adaline算法,它是对感知器算法的改进。它的核心思想是通过对代价函数做最小优化,这也是机器学习算法的核心思想,以及之后的逻辑斯蒂回归、支持向量机等都采用了这种思想。Adeline算法更新权重的规则是通过一个联系的线性激励函数来完成的,而之前的感知器算法是通过单位阶跃函数(在0处不连续),这是两种算法最主要的区别。线性激励函数在更新权重的同时,我们使用量化器对类标进行预测,这里所使用的量化器其实也是一个单位阶跃函数,量化器的使用是在训练好模型之后,通过量化器来预测类标。

一、代价函数

代价函数就是指在机器学习的监督算法中,在学习阶段我们需要定义一个目标函数,而这个目标函数通常是需要我们做最小优化处理的代价函数。在Adeline算法中,所使用的代价函数是模型的预测值与实际值之间的误差平方和,公式如下,系数为1/2的目的是为了方便与求导之后的2相乘抵消,方便计算。

连续激励函数相对于单位阶跃函数的优点:

1、代价函数可导

2、代价函数是一个凸函数,可以通过梯度下降算法求权重,而且能保证模型对样本进行分类时代价函数最小

通过下面的图来了解梯度下降的过程:

可以将梯度下降的过程理解成一个下山的过程,想象一下你站在山顶,为了能保证以最快的速度下上,你会寻找一个梯度最大的方向迈出一步。想象一下,当长度一样的时候,坡度越陡(梯度越大)的时候,是不是垂直方向的长度是最大的,y = x sinα,当阿尔法为90度的时候,y最大。下上的步长就由学习速率和梯度的斜率决定。

为什么是梯度的反方向而不是梯度方向?

因为梯度的反方向是函数值下降最快的方向,而梯度方向是函数值增长最快的方向,这里推荐一篇知乎专栏博客的解释https://zhuanlan.zhihu.com/p/24913912,为了便于大家理解,通过上面的梯度下降图简单介绍一下,对于只有一个自变量的情况下,函数的斜率就是导数,而有两个及以上的自变量都称为偏导。而这里只有一个变量,这里的梯度其实也就是导数,可以看到初始的值是大于全局最小值所对应的,如果想要让初始的向全局最小值的靠近,那么我们就需要增加初始的值,而在初始所对应的梯度(导数)是小于0的,为了是增加所以应该是梯度的反方向,当初始值在全局最小值的右边的时候也是这样的。下面推导一下代价函数对于某一个权重的偏导数

仔细一看,最后推导出来的公式貌似和之前的感知器的好像是一样的,其实不一样,感知器的激活函数是阶跃函数,而自适应线性神经元的激活函数是线性的(f(x)=x)。而且在训练模型的时候,自适应线性神经元的权重更新是基于训练集中的所有样本完成的,而感知器是每次一个样本进行权重更新,所以这种更新权重的方法被称之为批量梯度下降算法。

二、python实现自适应神经线性单元

1、初始化自适应线性神经元

#初始化类,默认学习率为0.01,迭代次数为50次 def __init__(self,eta=0.01,n_iter=50): self.eta = eta self.n_iter = n_iter

2、通过权重和输入来计算输出

#根据输入的X和权重计算输出值 def net_input(self,X): #通过numpy的矩阵点乘进行计算 return np.dot(X,self.w_[1:])+self.w_[0]

3、定义线性激活函数f(x)=x

#定义线性激活函数 def activation(self,X): return self.net_input(X)

4、根据输入和权重预测输出类标

#预测类标函数 def predict(self,X): return np.where(self.activation(X) >= 0 ,1,-1)

5、通过输入和输出数据训练模型获取权重

#通过输入的X和输出的Y计算权重 def fit(self,X,Y): #初始化权重 self.w_ = np.zeros(1+X.shape[1]) #定义损失值 self.cost_ = [] #迭代 for i in range(self.n_iter): #计算预测的输出值 output = self.net_input(X) #计算损失值,errors是一个向量 errors = (Y-output) #批量更新权重 self.w_[1:] += self.eta * X.T.dot(errors) #更新w0的权重 self.w_[0] += self.eta * errors.sum() #计算损失值 cost = (errors**2).sum() / 2 #记录每次迭代的损失值 self.cost_.append(cost) return self Read More




Leave A Comment

More News

互联网

中新网IT新闻

CSDN博客推荐文章

Disclaimer and Notice:WorldProNews.com is not the owner of these news or any information published on this site.