关于SGD、Adam、Adamw控制变量的对比实验

随机梯度下降算法(SGD)是最基本的梯度下降算法,对比BGD算法,SGD算法由于不是基于全部的数据,而是在每轮迭代中,随机优化某一条数据上的损失函数使更新速度大大加快。但其准确度会下降。Adam算法是基于AdaGrad算法和RMSProp算法,可以结合动量和自适应学习的集大成者,是目前应用最广泛的算法。Adamw算法效果与Adam相同,但效率更高,因为Adamw直接将正项的梯度加入反响传播的公式中年,省去了手动输入。我们通过计算接近x=6上y=(sin(x))^2+cos(x)+5y=(sin(x))2+cos(x)+5极小值点所需要迭代的次数,来对比SGD、Adam、Adamw算法的优缺点。下列就是有关SGD、Adam、Adamw算法的控制变量对比实验:

SGD

为了求得方程y=(sin(x))^2+cos(x)+5y=(sin(x))2+cos(x)+5的极小值点,我们可以通过计算此点的梯度,再求得靠近此点的梯度,梯度变化较小的点就是我们所需要求得的极值点。下面是用SGD代码实现的:

   #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    int main()
        {
    double x = 6;
    double lr = 1e-2;//学习效率
    double error = 1e-6;//误差范围
    double  grad = 2 * sin(x) * cos(x) - sin(x);//梯度
    int step=0;//循环次数
    while(1){
    if(fabs(grad)>error)
    {
        step++;
        x = x - grad * lr;
        grad = 2 * sin(x) * cos(x) - sin(x);
        printf(" %d %lf %lf\n", step,x, sin(x) * sin(x) + cos(x) + 5);
    }
    else{
        return 0;
    }
    }

SGD代码实现的结果:

    ./SGD
    1174 6.283183 6.000000
    1175 6.283183 6.000000
    1176 6.283183 6.000000
    1177 6.283183 6.000000
    1178 6.283183 6.000000
    1179 6.283183 6.000000
    1180 6.283183 6.000000
    1181 6.283183 6.000000
    1182 6.283183 6.000000
    1183 6.283183 6.000000
    1184 6.283183 6.000000
    1185 6.283183 6.000000
    1186 6.283183 6.000000
    1187 6.283183 6.000000
    1188 6.283183 6.000000
    1189 6.283183 6.000000
    1190 6.283183 6.000000
    1191 6.283183 6.000000
    1192 6.283183 6.000000
    1193 6.283183 6.000000
    1194 6.283183 6.000000
    1195 6.283183 6.000000
    1196 6.283184 6.000000
    1197 6.283184 6.000000
    1198 6.283184 6.000000
    1199 6.283184 6.000000

由此可以看出,SGD算法实现求得函数的极小值需要迭代多次。

Adam

同SGD算法一样,Adam算法也需要通过计算所在x处的梯度变化来判断极小值点的坐标,与SGD算法不同的是,Adam算法结合了AdaGrad算法和RMSProp算法,其准确率和迭代次数大大提升。通过设置相同的学习效率和误差范围,我们可以清楚的比较Adam算法和SGD算法,下面是用Adam算法实现的:

    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    void main(){
    double x=6,alpha=1e-3;//学习效率
    double grad=2*sin(x)*cos(x)-sin(x);//梯度
    double v=80;//动量
    double error=0.9e-3;//误差范围
    double r=80;//控制学习率
    double p1=0.99,p2=0.999;
    int step=0;//循环次数
    while(fabs(grad)>error){
        step++;
    grad=2*sin(x)*cos(x)-sin(x);
    v=p1*v+(1-p1)*grad;
    r=p2*r+(1-p2)*grad*grad;
    v=v/(1-pow(p1,step));
    r=r/(1-pow(p2,step));
    x=x-((alpha*v)/(sqrt(r)+1e-7))*grad;
    printf("%d %lf %lf\n",step,x,sin(x)*sin(x)+cos(x)+5);
    }
    }

Adam算法运行结果:

./Adam
    1 6.007204 6.036410
    2 6.022906 6.032547
    3 6.050224 6.026283
    4 6.089712 6.018310
    5 6.137491 6.010482
    6 6.185524 6.004742
    7 6.225285 6.001673
    8 6.252467 6.000472
    9 6.268149 6.000113
    10 6.276089 6.000025
    11 6.279800 6.000006
    12 6.281486 6.000001
    13 6.282264 6.000000
    14 6.282640 6.000000
    15 6.282832 6.000000

由此可见,Adam算法的效率相比SGD大大提升,其迭代次数大大减少,是当今运用最为广泛的算法。

Adamw

Adamw算法和是基于Adam算法进行改进的算法。其在计算梯度的时候会加上对正则项求梯度的结果,不需要手动的输入,因而效率相比Adam更高。通过控制与Adam算法相同的参数学习效率,误差范围,动量以及控制学习率,通过不断的改变schedule multiplier,找到最优解,我们可以清楚的看到Adamw算法的优势所在,下面是用Adamw实现的:

  #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    void main(){
        double learning_rate=1e-3;//学习效率
        double p1=0.99,p2=0.999;
        double x=6;
        double grad=2*sin(x)*cos(x)-sin(x);// 梯度
        double v=80,r=80;
        double error=0.9e-3;//误差范围
        int step=0;//循环次数
        double n=0.0094;//schedule multiplier
        while(fabs(grad)>error){
            step++;
            grad=2*sin(x)*cos(x)-sin(x)+x*n;
            v=p1*v+(1-p1)*grad;
            r=p2*r+(1-p2)*grad*grad;    
            v=v/(1-pow(p1,step));
            r=r/(1-pow(p2,step));
            x=x-n*(learning_rate*v/sqrt(r)+1e-7)+x*n;
            printf("%d %lf %lf\n",step,x,sin(x)*sin(x)+cos(x)+5);
        }
}

Adamw算法运行的结果:

   ./Adamw
    1 6.056137 6.025006
    2 6.112478 6.014324
    3 6.168866 6.006485
    4 6.225153 6.001681
    5 6.281243 6.000002

由此可见,通过调节适合的schedule multiplier,Adamw算法所需要的迭代次数相比Adam所需要的次数更少,效率更高。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值