自适应感知机(Adaline)是感知机的优化和改进,Adaline规则和感知机之间的关键差异在于Adaline规则的权重更新是基于线性激活函数,而感知机是基于单位阶跃函数,Adaline的线性激活函数 ϕ ( z )是净输入的等同函数:
ϕ ( w T x )= w T x
虽然线性激活函数可用于学习权重,但仍然使用阈值函数做最终预测,这类似于先前的单位阶跃函数,图2-8及图2-9是感知机与自适应算法的主要区别。
在学习过程中优化目标函数是有监督机器学习算法的一个关键,该目标函数通常是要最小化的代价函数,对于自适应神经元来说,可以把学习权重的代价函数 J 定义为在计算结果和真正的分类标签之间的误差平方和:
图2-8 感知机
图2-9 自适应线性神经元
寻找最小均方误差就像下山一样,每次算法循环都相当于下降一步,下降一步的步幅取决于学习率,与图2-10中的权值点的切线斜率相关。
图2-10 权值
每次权值逼近均方误差最小点的过程就是梯度下降(gradient descent)。因此,权值更新:
w = w + Δ w
权值变化:
Δ w =-η Δ J ( w )
其中,Δ J ( w )是代价函数对权值的偏导函数。
最终得到的权值更新公式如下:
Adaline算法是基于全部的训练数据,而感知机算法是每个样本都要计算一次误差。
如果学习率设置为0.01,输出结果如图2-11(a)所示,均方误差最小的点是第一个点,然后越来越大。当学习率设置为0.0001时,输出结果如图2-11(b)所示,误差在逐渐减小,但是没有收敛的趋势。
图2-11 学习率
学习率设置得偏大或偏小都会大幅降低算法效率。采取的方法是进行数据标准化(standardization),公式如下:
其中, μ j 为均值; σ j 为标准差。经过标准化的数据,会体现出一些数学分布的特点。标准化后,再次使用0.01的学习率进行训练分类,如图2-12所示。
图2-12 使用0.01的学习率进行训练分类
最后分类的平面图如图2-13所示。
具体的实现代码如下:
#encoding:utf-8 __author__= 'Matter' import numpy as np class AdalineGD(object): #自适应线性神经网络 #参数1为eta:float,学习率 #参数2为n_iter:int,循环次数 #--------属性--------# #属性1为w_:1d_array,拟合后权值 #属性2为errors_:list,每次迭代的错误分类
图2-13 分类平面图
#初始化 def__init__(self,eta=0.01,n_iter=10): self.eta=eta self.n_iter=n_iter #训练模型 def fit(self,X,y): self.w_=np.zeros(1+X.shape[1]) self.errors_=[] self.cost_=[] for i in range(self.n_iter): output= self.net_input(X) errors=(y-output) self.w_[1:]+=self.eta * X.T.dot(errors) self.w_[0]+=self.eta * errors.sum() cost=(errors * * 2).sum()/2.0 self.cost_.append(cost) return self #输入和权值的点积,即公式的z函数 def net_input(self,X): return np.dot(X,self.w_[1:])+ self.w_[0] #线性激活函数 def activation(self,X): return self.net_input(X) #利用阶跃函数返回分类标签 def predict(self,X): return np.where(self.activation(X)>=0.0,1,-1)