用c++用4个凸函数(觉得啥好用用啥)去测试adam,rmsprop,adagrad算法的性能(谁先找到最优点)

news2024/12/23 19:45:43

为了测试 Adam、RMSProp 和 Adagrad 算法的性能,你可以使用四个凸函数进行实验。以下是一些常用的凸函数示例:

  1. Rosenbrock 函数:

    Rosenbrock函数

  2. Booth 函数:

    Booth函数

  3. Himmelblau 函数:

    Himmelblau函数

  4. Beale 函数:

    Beale函数

你可以选择其中一个或多个函数来测试算法的性能。对于每个函数,你可以使用不同的初始点,并应用 Adam、RMSProp 和 Adagrad 算法来寻找最优点。最优点可以通过达到较低的函数值或满足预定精度条件来定义。

在实验过程中,你可以记录每个算法在不同函数和初始点上找到最优点的迭代次数、计算时间以及最终的函数值。通过比较这些指标,你可以评估每个算法的性能和效果。

请注意,算法的性能可能会因函数的形状和参数设置而有所不同。因此,建议你在不同的凸函数上进行多次实验,以获得更全面的性能比较结果。

#include <iostream>
#include <cmath>
#include <vector>

// 定义凸函数类
class ConvexFunction {
public:
    virtual double evaluate(const std::vector<double>& x) = 0;
};

// Rosenbrock 函数
class RosenbrockFunction : public ConvexFunction {
public:
    double evaluate(const std::vector<double>& x) override {
        double sum = 0.0;
        for (size_t i = 0; i < x.size() - 1; ++i) {
            double term1 = pow(x[i + 1] - pow(x[i], 2), 2);
            double term2 = pow(1 - x[i], 2);
            sum += 100 * term1 + term2;
        }
        return sum;
    }
};

// Booth 函数
class BoothFunction : public ConvexFunction {
public:
    double evaluate(const std::vector<double>& x) override {
        double term1 = pow(x[0] + 2 * x[1] - 7, 2);
        double term2 = pow(2 * x[0] + x[1] - 5, 2);
        return term1 + term2;
    }
};

// Himmelblau 函数
class HimmelblauFunction : public ConvexFunction {
public:
    double evaluate(const std::vector<double>& x) override {
        double term1 = pow(pow(x[0], 2) + x[1] - 11, 2);
        double term2 = pow(x[0] + pow(x[1], 2) - 7, 2);
        return term1 + term2;
    }
};

// Beale 函数
class BealeFunction : public ConvexFunction {
public:
    double evaluate(const std::vector<double>& x) override {
        double term1 = pow(1.5 - x[0] + x[0] * x[1], 2);
        double term2 = pow(2.25 - x[0] + x[0] * pow(x[1], 2), 2);
        double term3 = pow(2.625 - x[0] + x[0] * pow(x[1], 3), 2);
        return term1 + term2 + term3;
    }
};

// Adam 算法
std::vector<double> adam(const ConvexFunction& func, const std::vector<double>& initial_x, double learning_rate, int max_iterations) {
    std::vector<double> x = initial_x;
    std::vector<double> m(x.size(), 0.0);
    std::vector<double> v(x.size(), 0.0);
    double beta1 = 0.9;
    double beta2 = 0.999;
    double epsilon = 1e-8;

    for (int i = 0; i < max_iterations; ++i) {
        // 计算梯度
        std::vector<double> gradient(x.size(), 0.0);
        for (size_t j = 0; j < x.size(); ++j) {
            std::vector<double> x_plus_delta = x;
            x_plus_delta[j] += epsilon;
            double f_plus_delta = func.evaluate(x_plus_delta);
            gradient[j] = (f_plus_delta - func.evaluate(x)) / epsilon;
        }

        // 更新参数
        for (size_t j = 0; j < x.size(); ++j) {
            m[j] = beta1 * m[j] + (1 - beta1) * gradient[j];
            v[j] = beta2 * v[j] + (1 - beta2) * pow(gradient[j], 2);
            double m_hat = m[j] / (1 - pow(beta1, i + 1));
            double v_hat = v[j] / (1 - pow(beta2, i + 1));
            x[j] -= learning_rate * m_hat / (sqrt(v_hat) + epsilon);
        }
    }

    return x;
}

// RMSProp 算法
std::vector<double> rmsprop(const ConvexFunction& func, const std::vector<double>& initial_x, double learning_rate, double decay_rate, int max_iterations) {
    std::vector<double> x = initial_x;
    std::vector<double> cache(x.size(), 0.0);
    double epsilon = 1e-8;

    for (int i = 0; i < max_iterations; ++i) {
        // 计算梯度
        std::vector<double> gradient(x.size(), 0.0);
        for (size_t j = 0; j < x.size(); ++j) {
            std::vector<double> x_plus_delta = x;
            x_plus_delta[j] += epsilon;
            double f_plus_delta = func.evaluate(x_plus_delta);
            gradient[j] = (f_plus_delta - func.evaluate(x)) / epsilon;
        }

        // 更新参数
        for (size_t j = 0; j < x.size(); ++j) {
            cache[j] = decay_rate * cache[j] + (1 - decay_rate) * pow(gradient[j], 2);
            x[j] -= learning_rate * gradient[j] / (sqrt(cache[j]) + epsilon);
        }
    }

    return x;
}

// Adagrad 算法
std::vector<double> adagrad(const ConvexFunction& func, const std::vector<double>& initial_x, double learning_rate, int max_iterations) {
    std::vector<double> x = initial_x;
    std::vector<double> cache(x.size(), 0.0);
    double epsilon = 1e-8;

    for (int i = 0; i < max_iterations; ++i) {
        // 计算梯度
        std::vector<double> gradient(x.size(), 0.0);
        for (size_t j = 0; j < x.size(); ++j) {
            std::vector<double> x_plus_delta = x;
            x_plus_delta[j] += epsilon;
            double f_plus_delta = func.evaluate(x_plus_delta);
            gradient[j] = (f_plus_delta - func.evaluate(x)) / epsilon;
        }

        // 更新参数
        for (size_t j = 0; j < x.size(); ++j) {
            cache[j] += pow(gradient[j], 2);
            x[j] -= learning_rate * gradient[j] / (sqrt(cache[j]) + epsilon);
        }
    }

    return x;
}

int main() {
    // 创建凸函数对象
    RosenbrockFunction rosenbrock;
    BoothFunction booth;
    HimmelblauFunction himmelblau;
    BealeFunction beale;

    // 设置算法参数
    double learning_rate = 0.01;
    double decay_rate = 0.9;
    int max_iterations = 1000;

    // 初始化初始点
    std::vector<double> initial_x = { 0.0, 0.0 };

    // 使用 Adam 算法找到最优点
    std::vector<double> adam_result = adam(rosenbrock, initial_x, learning_rate, max_iterations);
    std::cout << "Adam Result: (" << adam_result[0] << ", " << adam_result[1] << ")" << std::endl;

    // 使用 RMSProp 算法找到最优点
    std::vector<double> rmsprop_result = rmsprop(rosenbrock, initial_x, learning_rate, decay_rate, max_iterations);
    std::cout << "RMSProp Result: (" << rmsprop_result[0] << ", " << rmsprop_result[1] << ")" << std::endl;

    // 使用 Adagrad 算法找到最优点
    std::vector<double> adagrad_result = adagrad(rosenbrock, initial_x, learning_rate, max_iterations);
    std::cout << "Adagrad Result: (" << adagrad_result[0] << ", " << adagrad_result[1] << ")" << std::endl;

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1698339.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

光线追踪技术在AI去衣中的革命性角色

引言&#xff1a; 随着人工智能和计算机图形学的飞速发展&#xff0c;AI去衣技术已经从理论走向实践&#xff0c;为影视制作、虚拟现实、在线试衣等领域提供了强大的技术支持。在这一过程中&#xff0c;光线追踪技术以其卓越的渲染能力和逼真的光影效果&#xff0c;成为AI去衣领…

C++开发面试常问总结

一些面试总结 TCP粘包了解吗&#xff1f;解决办法&#xff1f;讲一下乐观锁悲观锁git中 git pull和git fetch的区别1.虚函数实现机制&#xff1a;2.进程和线程的区别&#xff1a;3.TCP三次握手、四次挥手&#xff1a;4.HTTP状态码&#xff0c;报头&#xff1a;5.智能指针&#…

MySql基础(一)--最详细基础入门,看完就懂啦(辛苦整理,想要宝宝的赞和关注嘻嘻)

前言 希望你向太阳一样&#xff0c;有起有落&#xff0c;不失光彩~ 一、数据库概述 1. 什么是数据库 数据库就是存储数据的仓库&#xff0c;其本质是一个文件系统&#xff0c;数据按照特定的格式将数据存储起来&#xff0c;用户可以对数据库中的数据进行增加&#xff0c;修改&…

【Django项目】 音乐网站spotify复刻

代码&#xff1a;https://github.com/tomitokko/spotify-clone 注&#xff1a;该项目不是自己提供mp3文件&#xff0c;而是使用spotify 的api接口获取。

奇舞周刊第529期:万字长文入门前端全球化

周五快乐&#xff08;图片由midjourney生成&#xff09; 奇舞推荐 ■ ■ ■ 万字长文入门前端全球化 目前国内企业正积极开拓国际市场&#xff0c;国际化已成为重要的发展方向&#xff0c;因此产品设计和开发更需考虑国际化。本文介绍了语言标识、文字阅读顺序等诸多知识。然后…

【编译原理复习笔记】中间语言

中间语言 中间语言的特点和作用 &#xff08;1&#xff09;独立于机器 &#xff08;2&#xff09;复杂性介于源语言和目标语言之间 中间语言可以使编译程序的结构在逻辑上更为简单明确 常用的中间语言 后缀式 图表示&#xff1a;抽象语法树&#xff0c;有向无环图 三地址代…

淘宝x5sec

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018601872 本文章未…

LeetCode 264 —— 丑数 II

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 第一个丑数是 1 1 1&#xff0c;由于丑数的质因子只包含 2 、 3 、 5 2、3、5 2、3、5&#xff0c;所以后面的丑数肯定是前面的丑数分别乘以 2 、 3 、 5 2、3、5 2、3、5 后得到的数字。 这样&#xff0c;我…

类的内存对齐位段位图布隆过滤器哈希切割一致性哈希

文章目录 一、类的内存对齐1.1规则1.2原因 二、位段2.1介绍2.2内存分配问题2.3跨平台问题2.4使用的注意事项 三、位图的应用3.1 给40亿个不重复的无符号整数&#xff0c;找给定的一个数。&#xff08;int的范围可以到达42亿多&#xff09;3.2 给定100亿个整数&#xff0c;设计算…

openEuler 22.03 LTS SP3源码编译部署OpenStack-Caracal

openEuler 22.03 LTS SP3源码编译部署OpenStack-Caracal 说明机器详情安装操作系统注意事项基础准备Controller节点 && Compute节点 && Block节点关闭防火墙关闭selinux设置静态IP更新安装前准备Controller节点 && Compute节点 && Block节点设…

auto关键字(C++11)

auto关键字&#xff08;C11&#xff09; 文章目录 auto关键字&#xff08;C11&#xff09;前言一、auto使用规则二、auto不适用的场景三、auto推荐适用的场景总结 前言 在C11中&#xff0c;auto关键字能够自动推导出变量的实际类型&#xff0c;可以帮助我们写出更加简洁、现代…

开发公众号自定义菜单之创建菜单

文章目录 申请测试账号换取Token接口测试提交自定义菜单查看效果校验菜单配置清空菜单配置结束语 申请测试账号 https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?actionshowinfo&tsandbox/index 或 得到appid和secret 换取Token 使用appid和secret换取token令牌…

Python应用实战,用动画生成冒泡排序的过程

写在前言 hello&#xff0c;大家好&#xff0c;我是一点&#xff0c;专注于Python编程&#xff0c;如果你也对感Python感兴趣&#xff0c;欢迎关注交流。 希望可以持续更新一些有意思的文章&#xff0c;如果觉得还不错&#xff0c;欢迎点赞关注&#xff0c;有啥想说的&#x…

解决文件夹打开出错问题:原因、数据恢复与预防措施

在我们日常使用电脑或移动设备时&#xff0c;有时会遇到一个非常棘手的问题——文件夹打开出错。这种错误可能会让您无法访问重要的文件和数据&#xff0c;给工作和生活带来极大的不便。本文将带您深入了解文件夹打开出错的原因&#xff0c;并提供有效的数据恢复方案&#xff0…

栈和队列的基本见解

1.栈 1.1栈的基本概念和结构&#xff1a; 栈是一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出的原则。 压栈&#xff1a;栈的插入操作叫做进栈/压栈…

Vxe UI 表单设计器、零代码平台

vxe-pc-ui Vxe UI 表单设计器、零代码表单设计器 安装 Vxe UI PC端组件库 官方文档 查看 github、gitee // ...import VxeUI from vxe-pc-uiimport vxe-pc-ui/lib/style.css// ...// ...createApp(App).use(VxeUI).mount(#app)// ...使用 vxe-form-design 设计器组件 vxe-fo…

QML的Image 路径问题(source)

四种路径格式 在 QML 中&#xff0c;当你使用 Image 元素的 source 属性来指定一个图片的路径时&#xff0c;有几种不同的方式可以指定这个路径&#xff0c;每种方式都有其特定的用途和上下文。 相对路径&#xff1a; QML 文件和一个名为 close.png 的图片在同一目录下&#x…

列表元素添加的艺术:从单一到批量

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、向列表中添加单一元素 1. append方法 2. insert方法 三、向列表中添加批量…

CentOS网络配置(三种网络模式:桥接、NAT、Host-Only)

目录 1、虚拟机网络模式 1.1 桥接 1.2 NAT 1.3 Host-Only 2、桥接模式 3、仅主机模式 4、NAT模式 5、centos网络配置 5、virtualbox 下centos7网络配置 5.1管理 ——> 全局设定 ——> 网络&#xff0c;新加网络 5.2 具体虚拟机设置&#xff0c;网络设置&#…

软件设计师笔记2

文章目录 软考知识点总结1. 计算机组成原理网络与信息安全数据结构与算法AOE网 编译原理操作系统软件设计软件测试数据库计算机软件产权其它 软考知识点总结 1. 计算机组成原理 cpu控制器&#xff0c;专门产生指令操作&#xff0c;送到计算机各个部位执行处理 DMA&#xff08…