自适应算法 - 从卡尔曼滤波到网络拥塞算法

      • 卡尔曼滤波
      • PID自适应算法
      • 网络拥塞算法

无论是卡尔曼滤波,还是网络拥塞算法,都可以看到自适应回归和权重的思想,而关于权重与自适应,再说下去,神经网络算法也是这样子的思想,所以,在这里,就所接触过的一些相关的算法做一些总结,当然,随着研究的深入,可能还会发现更多的总结想法,这些留待后续补充

卡尔曼滤波

卡尔曼滤波器是一个“optimal recursive data processing algorithm(最优化自回归数据处理算法)”,
广泛应用于机器人导航,控制,传感器数据融合甚至在军事方面的雷达系统以及导弹追踪等等。近年来更被应用于计算机图像处理,例如头脸识别,图像分割,图像边缘检测等等。

概念:高斯白噪声,从数学上来讲,就是服从于一定分布的随机变量。这个随机变量服从均值为0方差为sigma方的正态分布

假如要研究一个房间的温度,我们有两个值,经验的预测值(系统的预测值)和温度计的值(测量值)。用这两个值结合他们各自的噪声来估算出房间的实际温度值。

1.初始化与估算
对于k时刻的温度,个人预测值假设是23度,同时该值的高斯噪声的偏差是5度(5是这样得到的:如果k-1时刻估算出的最优温度值的偏差是3,你对自己预测的不确定度是4度,他们平方相加再开方,就是5)。
温度计此时得到了25度,同时该值的偏差是4度。
由上,可以看出,温度计的偏差比较小,所以权重应该大点,至于给多少权重,经常用的方法是协方差来权衡,所以可以用协方差来估算,Kg^2=5^2/(5^2+4^2),所以Kg=0.78
所以,我们最后得出来的实际温度值为:25*0.75+23*(1-0.78)=24.56度。

2.自适应
在进入k+1时刻之前,我们还要算出k时刻那个最优值(24.56度)的偏差。
我们要首先算出预测值(23度)的偏差,算法如下:((1-Kg)*5^2)^0.5=2.35,即更新了偏差,由5迭代为了2.35,就这样,不断递归,从而估算出最优的温度值。
Kg,就是卡尔曼增益(Kalman Gain)。他可以随不同的时刻而改变他自己的值

卡尔曼滤波算法

要引入一个离散控制过程的系统。该系统可用一个线性随机微分方程(Linear Stochastic Difference equation)来描述:
X(k)=A X(k-1)+B U(k)+W(k)
再加上系统的测量值:
Z(k)=H X(k)+V(k)
式子

X(k|k)= X(k|k-1)+Kg(k) (Z(k)-X(k|k-1)) ……… (1)
Kg(k)= P(k|k-1) / (P(k|k-1) + R) ……… (2)
P(k|k)=(1-Kg(k))P(k|k-1) ……… (3)

其中的推导过程便此略去
笔者总结:
可以看出,卡尔曼滤波算法的自适应能力,为什么需要卡尔曼滤波呢,因为作为传感器,测量的值是会抖动的,如果不加以滤波而直接用的话,可想而知是不行的, 所以便有均值滤波,一阶互补滤波,二阶互补滤波等,这里,卡尔曼滤波不仅依赖于前者数据,同时也一直更新前面数据的权重,这样子,便很好地抵消了数据的偶然性,也提高数据的利用速度

PID自适应算法

什么是PID,PID(比例(proportion)、积分(integral)、导数(derivative))
1、比例(P)控制 :控制器的输出与输入误差信号成比例关系。当仅有比例控制时系统输出存在稳态误差。
2、积分(I)控制 :控制器的输出与输入误差信号的积分成正比关系。为了消除稳态误差,在控制器中必须引入“积分项”。积分项对误差取决于时间的积分,随着时间的增加,积分项会增大。因此,比例+积分(PI)控制器,可以使系统在进入稳态后无稳态误差。
3、微分(D)控制:控制器的输出与输入误差信号的微分(即误差的变化率)成正比关系。 自动控制系统在克服误差的调节过程中可能会出现振荡甚至失稳。其原因是由于存在有较大惯性组件(环节)或有滞后组件,具有抑制误差的作用,其变化总是落后于误差的变化。解决的办法是使抑制误差的作用的变化“超前”,即在误差接近零时,抑制误差的作用就应该是零。这就是说,在控制器中仅引入“比例”项往往是不够的,比例项的作用仅是放大误差的幅值,而目前需要增加的是“微分项”,它能预测误差变化的趋势,这样,具有比例+微分的控制器,就能够提前使抑制误差的控制作用等于零,甚至为负值,从而避免了被控量的严重超调。所以对有较大惯性或滞后的被控对象,比例+微分(PD)控制器能改善系统在调节过程中的动态特性。

在PID控制器中,PID控制器的参数整定是控制系统设计的核心内容。这里只讲思想,就不讲这些内容了

这里放上笔者之前用过的PID算法部分代码

typedef struct
{
    float Kp; //比例调节的参数 
    float Ki; //积分调节的参数 
    float Kd; //微分调节的参数 
    int error[PID_DATA_MAX]; //输入误差的变化量累积
    int error_point; //输入误差变化数表指针,指向当前误差
                 //e_point = 5,e(n)=e[5],e(n-1)=e[4]
    int output; //调节计算到最后的输出量 即是变化量
} PID_Typedef;

PID计算,对结构体里面的数据进行运算

void PID_calc(PID_Typedef* pid)
{
    u8 i = 0;
    int tmp[3] = {0};
    //比例运算
    tmp[0] = pid->Kp * pid->error[pid->e_point];
    //积分运算
    for(i=0;i//累积求和
    {
        tmp[1] += pid->error[i];
    }
    tmp[1] *= pid->Ki;
    //微分运算
    if(pid->error_point == 0) i = PID_DATA_MAX - 1;
    else i = pid->error_point - 1;
    tmp[2] = pid->error[pid->error_point] - pid->error[i];
    tmp[2] *= pid->Kd;
    //输出偏移量求和
    pid->output = tmp[0] + tmp[1] + tmp[2];
}

笔者总结
在PID闭环控制中,我们可以看到,每一轮调节过后,都会通过反馈得到的误差进行再自适应调节,与卡尔曼算法如出一则

网络拥塞算法

从工业算法到网络应用,自适应迭代的思想也会相应的存在,如网络拥塞控制算法

慢启动
指数增加到ssthresh –> 加法增大直到网络拥塞 –> 乘法减小 –> 更新ssthresh为拥塞时窗口的一半 –> 从1继续慢开始
(当发送端收到连续三个重复的确认时,就执行“乘法减小”算法)
快重传
可以看出慢启动后发生拥塞就一下子降到了1,窗口有点小,可以改进
拥塞窗口 cwnd 现在不设置为 1,而是设置为慢开始门限 ssthresh 减半后的数值,然后开始执行拥塞避免算法(“加法增大”),使拥塞窗口缓慢地线性增大。

由上可以看出,当发生指数增加,加法增大后,如果出现网络拥塞,这时会进行反馈更新,阀值容器ssthresh更新为拥塞时窗口的一半,随后又会一直进行,像极了之前的步骤,很明显也是一种自适应算法

你可能感兴趣的:(算法,PHP与网络编程,算法,网络)