admin

  • 在2015年,由 OpenAI 的 DP Kingma 等发布了 《ADAM: A METHOD FOR STOCHASTIC OPTIMIZATION》算法后,由于其迭代效率提升非常明显,所以 ADAM(或其变种)就被广泛的采用。本文将继续对上一篇介绍的梯度下降算法进行优化,并介绍 ADAM 算法(一种对随机梯度下降算法的优化算法)的实现以及效果。

    Stochastic Gradient Descent 或者说 mini-batch解决了样本量巨大时,梯度下降迭代的问题。但是,也带了一些新的问题。最为主要的是,因为样本数据的波动,而导致每次梯度下降计算时,梯度方向的波动,从而降低了梯度下降迭代的效率。

    在前面的《Mini-batch Gradient Descent和随机梯度下降(SGD)》文章中,我们对比了 mini-batch 和 batch gradient descent 的在迭代时,目标函数下降的速度。

    可以看到,batch gradient descent 的目标函数下降非常稳定,而 Mini-batch 的实现则会有明显的波动。为了尝试修正这个问题,从而提高迭代效率,在神经网络算法上,逐渐探索出了一些较为高效的优化算法:Adam SGD。该算法将 RMSprop 和 “Exponential smoothing”的想法结合在一起,形成了一个较为高效的算法,在实践中被广为使用。


    Stochastic Gradient Descent 与 Momentum

    SGD 会在每次迭代时根据样本的偏差,展现出不同的偏差,所以,在使用SGD进行迭代时,观察其 cost函数下降,应该会有更加明显的波动(后续吧自己实现的程序改造后,尝试观察一下)。

    为了加快迭代的速度,一个折中的思路是,引入一个均值替换当前的梯度方向。该如何引入这个均值呢?梯度是一个随时计算推进,不断推进的变量,常用的均值计算可以参考:Moving average。最为常见的实现是使用“Exponential moving average”,这种平均值的计算,在迭代计算时实现非常简单。

    Momentum 就是 “Exponential moving average”实现时的参数“smoothing factor”,在神经网络中,经常使用 \( \beta \)表示(原因是 \( \alpha \) 已经表示学习率了 )。

    而这里的 Momentum ,也是 TensorFlow 在构造 SGD 算法时需要的另一个参数。

    关于Exponential moving average

    或者叫“Exponential smoothing”。我们看看这个算法的具体实现是怎样的?

    原始的迭代:\( w = w – \alpha \frac{\partial J}{\partial w} \)

    使用 “Exponential smoothing” 后的迭代:

    $$
    \begin{align}
    v_0 & = 0 \quad \partial{w}_t = \frac{\partial J}{\partial w}|_{(for \, sample \, t)} \\
    v_{t} & = \beta*v_{t-1} + (1-\beta)\partial{w}_{t} \\
    w & := w – \alpha v_t
    \end{align}
    $$

    考虑 \( \beta = 0.9 \),如果数学直觉比较好的话,可以看出,原本使用梯度\( \partial{w} \)进行迭代的,这里使用了一个梯度的“Exponential smoothing” \( v_t \)去替代。上面的式子中,\( v_t \) 如果展开有如下表达式:

    $$
    \begin{align}
    v_t & = (1-\beta)\partial{w}_{t} + \beta(1-\beta)\partial{w}_{t-1} + \beta^2(1-\beta)\partial{w}_{t-2} … \\
    & = \sum\limits_{i=0}^{t} \beta^{i}(1-\beta)\partial{w}_{i}
    \end{align}
    $$

    使用“Exponential smoothing” 之后,新的迭代方向 \( v_t \),可以理解为一个前面所有梯度方向的加权平均。离得越近的梯度,权重越高,例如,\( \partial{w}_{t} \)的权重是\( (1-\beta) \);而之前的梯度,则每次乘以一个 \( \beta \)衰减。

    Exponential moving average的“冷启动问题”与修正

    仔细观测上诉的 “Exponential moving average” 公式,可以注意到一个问题,就是其最初的几个点总是会偏小。其原因是,当前值的权重总是为 \( 1- \beta \),而因为是初始的几个值,并没有更前面的数据去“平均”当前值,也就会出现,初始值总是会偏小的问题。

    通常,如果样本量很大的事时候,则可以忽略这个问题,因为初始值偏小的点占比会非常少,可以忽略。如果要一定程度上解决这个问题,也有继续对上述的 “Exponential moving average”做了一些修正,可以考虑对 \( v_t \)的结果值做一个修正:\( v_t := \frac{vt}{1-\beta^t} \)。

    一般的,因为样本的数量总是比较大的,所以我们可以忽略这个问题,而无需做任何修正。

    RMSprop

    在前面的“Gradient Descent with Momentum”中,我们看到为了解决梯度波动较大的问题,使用了 “Exponential moving average” 去尝试将一些比较偏的梯度,拉倒一个较为平均的方向上来。RMSprop的想法也是类似的,这里通过了root mean square的想法进行平均值的计算。具体的,在进行 SGD 时,每次更新梯度,按照如下的方法进行更新:

    $$
    \begin{align}
    s_0 & = 0 \quad \partial{w}_t = \frac{\partial J}{\partial w}|_{(for \, sample \, t)} \\
    s_{t} & = \beta*s_{t-1} + (1-\beta)(\partial{w}_{t})^2 \\
    w & := w – \alpha \frac{\partial w}{\sqrt{s_{t}}}
    \end{align}
    $$

    说明:这里对梯度进行平方时,如果在程序中是一个梯度向量,那么这里“平方”也就是对梯度的每一个分量进行一次平方。

    在“Exponential smoothing”的实现中,是将当前值,使用一个加权平均替代。与“Exponential smoothing”类似的,原本的梯度方向,现在使用如下的方向去替代了:

    $$
    \begin{align}
    s_t & = \frac{\partial{w}_{t}}{\sqrt{(1-\beta)(\partial{w}_{t})^2 + \beta(1-\beta)(\partial{w}_{t-1})^2 + \beta^2(1-\beta)(\partial{w}_{t-2})^2 + \cdots }} \\
    & = \frac{\partial{w}_{t}}{\sqrt{\sum\limits_{i=1}^{t}\beta^i(1-\beta)(\partial{w}_{i})^2}} \\
    \end{align}
    $$

    Adam Gradient Descent

    这可能是实际使用最多的算法,全称是 Adaptive Moment Estimation 。该实现,将 “Momentum” 和 “RMSprop” 做了一定的融合,形成了新的“最佳实践” Adam。在融合上,具体的实现与两个细节点:

    (1) 在 Adam 中均使用了“修正”计算,即 \( \hat{v_t} = \frac{v_t}{1-(\beta_1)^t} \quad \hat{s_t} = \frac{s_t}{1-(\beta_1)^t} \)

    (2) 参数更新公式,使用了两个算法的融合: \( w := w – \alpha \frac{\hat{v_t}}{\sqrt{\hat{s_t}}} \)

    Adam optimization的效果对比

    在 Adam 的论文中对于效果做了非常多的评估,感兴趣的可以参考相关论文。

    这里根据之前完成的训练程序,也进行了优化,实现了Adam算法。在 MNIST 数据集的训练上,我们来看看 Adam 的效果:

    从右图可以看到,Adam(蓝色)明显的提升了迭代效率。依旧一定程度存在 mini-batch(绿色) 的梯度波动的问题。相比于,batch gradient descent (红色)算法,迭代效率大大增加,约在第10次迭代,即在第一个epoch 的第十批样本进行训练时,cost 就下降到了比较低的程度。

    关于 root mean square

    root mean square也叫二次平均值,考虑一组数据:\( {x_1,x_2, \cdots , x_n } \),其RMS则为:

    $$ x_{rms} = \sqrt{\frac{1}{n} \sum_{i=1}^n x_i^2} = \sqrt{\frac{1}{n} (x_1^2 + x_2^2 + \cdots + x_n^2)} $$

    补充说明

    可以看到,所有的这些优化都是面向“最优化”问题的。梯度下降是一个一阶优化(First-order Optimization)的方法,其核心就在与每次迭代时,应该如何去更新响应的参数值,在梯度下降中也就是如何去选择合适的学习率。

    牛顿法是典型的二阶优化(Second-order Optimization),在迭代时使用了二阶导数,所以,通常可以获得更好的迭代效率。但是因为二阶导数的计算复杂度会上升非常多(对应的矩阵可能是所有参数的平方,应该也有人尝试去算过了…)。这也是为什么在这个场景下,依旧是使用一阶优化方法的原因。

    如果想比较好的理解学习率、Momentum、RMSprop、Adam等内容,建议先了解梯度、数值方法、最优化问题等数学方法。

    到这里这个系列算是一个小阶段了,这是一个个人学习的笔记,从数学的梯度概念开始,逐步到神经网络训练的Adam优化算法,也包含部分动手实践的神经网络算法实现。完成的系列包括了:

  • Terraform 可以自动化的创建云端的资源,但是要想实现更高的灵活度,则需要更为灵活的使用Terraform的“Data Sources”能力。例如,在自动化的创建数据库时,云厂商允许创建的版本号是在动态变化的,例如,当前最新的允许的创建的MySQL版本通常是 8.0.40,但通常过了一个季度之后,就变成了 8.0.41。这时,对应的 Terraform 的脚本就需要调整或者传递参数就需要发生变化。而 Terraform 提供的 “Data Sources” 能力则可以很好的解决这个问题。

    在 Oracle 的 Terraform 中可以使用 “Data Source: oci_mysql_mysql_versions” 实现该能力。

    示例

    首先使用 data 命令定义该对象:

    data "oci_mysql_mysql_versions" "gmv" {
        compartment_id = oci_identity_compartment.oic.id
    }

    这里会获取该租户环境下支持的所有MySQL版本。

    然后,再使用 output 命令就可以获取并输出这些版本信息。详细的output命令如下:

    output "mysql_version" {
      value       = data.oci_mysql_mysql_versions.gmv.versions
    }

    详细的输出示例如下:

    mysql_version = tolist([
      {
        "version_family" = "8.0"
        "versions" = tolist([
          {
            "description" = "8.0.36"
            "version" = "8.0.36"
          },
          {
            "description" = "8.0.37"
            "version" = "8.0.37"
          },
          {
            "description" = "8.0.38"
            "version" = "8.0.38"
          },
          {
            "description" = "8.0.39"
            "version" = "8.0.39"
          },
          {
            "description" = "8.0.40"
            "version" = "8.0.40"
          },
          {
            "description" = "8.0.41"
            "version" = "8.0.41"
          },
        ])
      },
      {
        "version_family" = "8.4 - LTS"
        "versions" = tolist([
          {
            "description" = "8.4.0"
            "version" = "8.4.0"
          },
          {
            "description" = "8.4.1"
            "version" = "8.4.1"
          },
          {
            "description" = "8.4.2"
            "version" = "8.4.2"
          },
          {
            "description" = "8.4.3"
            "version" = "8.4.3"
          },
          {
            "description" = "8.4.4"
            "version" = "8.4.4"
          },
        ])
      },
      {
        "version_family" = "9 - Innovation"
        "versions" = tolist([
          {
            "description" = "9.1.0"
            "version" = "9.1.0"
          },
          {
            "description" = "9.1.1"
            "version" = "9.1.1"
          },
          {
            "description" = "9.1.2"
            "version" = "9.1.2"
          },
          {
            "description" = "9.2.0"
            "version" = "9.2.0"
          },
        ])
      },
    ])

    获取特定大版本的各小版本

    可以通过 data资源中新增filter模块以过滤出需要的对象。

    在 Terraform 中,关于 data 资源是否可以使用 filter,以及filter支持的完整度视乎并没有明确的说明。这需要更具不同的供应商的实现。常见的,在data resourcefilter可以支持“列表匹配”、“通配符匹配”或者“正则匹配”。具体的匹配方式,则需要通过文档、或者测试区验证。

    添加带正则匹配的 filter
    data "oci_mysql_mysql_versions" "gmv" {
        #Required
        compartment_id = oci_identity_compartment.oic.id
        filter {
            name = "version_family"
            values = ["8.0.*"]
            regex  = true
        }
    }

    通过 HCL 语言获取最新的版本
    output "latest_versions" {
      value = {
        for db_version in data.oci_mysql_mysql_versions.gmv.versions : db_version.version_family => sort([
          for v in db_version.versions : v.version
        ])[length(db_version.versions) - 1] // 取排序后的最后一个版本
      }
    }

    最后的输出如下:

    latest_versions = {
      "8.0" = "8.0.41"
      "8.4 - LTS" = "8.4.4"
      "9 - Innovation" = "9.2.0"
    }

    参考链接

  • 蛇年大吉!

    标题:清华大学数据库教授李国良入选 ACM Fellow; 阿里云 PolarDB 打破TPC-C记录

    重要更新

    清华大学李国良入选ACM Fellow,以表彰其在人机协同(human-in-the-loop)数据集成与基于学习的数据库系统领域做出的重要贡献。此外,李国良还是 openGauss 社区技术委员会主席。[6]

    阿里云 PolarDB 打破TPC-C记录[1][2],以更高的性能、更好的性价比超越之前OceanBase、TDSQL创下的记录。PolarDB本次使用的使用的版本为多主集群(Limitless),总计使用2340个数据节点,56,160个cores,1170个处理器[3]

    更新详情

    Azure(微软云)
    • Azure SQL Database 正式提供免费试用,该试用提供10个数据库、每个32GB的 serverless 实例,每月最多使用资源为100,000 vCore*秒 [5]
    GCP(谷歌云)
    • Cloud SQL for MySQL 5.6 和 5.7 ,PostgreSQL 9.6、10、11 和 12因为社区生命周期终止 (EOL) ,当前已加入 Cloud SQL 扩展支持阶段 [14][15]
    • Spanner 索引顾问在 GoogleSQL 和 PostgreSQL 方言数据库中均已普遍可用。索引顾问会分析您的查询,推荐新索引或对现有索引进行更改,以提高查询的性能[18]
    • Spanner 支持新的 SERIALAUTO_INCREMENT DDL 语法 [19]
    • BigQuery ML 支持多项生成式 AI 功能 [27]
    • Spanner 支持 GoogleSQL 和 PostgreSQL 方言数据库中的 `SELECT…FOR UPDATE` 查询语法[34]
    Oracle云
    • HeatWave 支持更改管理员密码 [40]
    • HeatWave 支持版本 9.2.0、8.4.4 和 8.0.41 [41]
    • OCI 上的 PostgreSQL 数据库增加了对 pg_cron 和 pgaudit 扩展的支持[42]
    火山云(字节)
    • DBW 提供用户组管理功能,通过将火山引擎子用户分配到用户组 [45]
    • DBW 支持批量开启、关闭和修改实例的安全管控 [46]
    AWS(亚马逊云)
    • DocumentDB 现在提供与 CloudShell 的一键连接 [51]
    • RDS Custom for SQL Server 使用 io2 Block Express 卷支持高达 64TiB 和 256,000 IOPS [57]
    • Timestream for InfluxDb 现已支持存储扩展 [60]
    • Aurora PostgreSQL Limitless Database 现在支持 PostgreSQL 16.6 [66]
    • ElastiCache 现在支持一键设置 EC2 和缓存之间的连接[68]

    参考链接

  • 一直以来都在较为系统对托管的 MySQL 进行性能测试(参考),本文较为系统将 Oracle Cloud 上托管 MySQL 的性能进行对比展示,可以帮助 Oracle Cloud 上的开发者较为系统了解其MySQL的性能情况。

    8.0.x 系列的性能对比

    这是当前的主要版本,也是当前的“稳定版”(LTS)。

    8.4.x 系列的性能对比

    这是当前另一个“稳定版”(LTS),也会是 8.0.x 系列之后另一个稳定版(LTS)。

    9.x.x 系列的性能对比

    该系列的版本为“创新版”。

    跨版本整体对比

    这里对比

    所有测试数据详情

    data202404_8036202409_8039202409_8402202409_9001202501_8040202501_8403202501_9102
    cpu_capacity103.3114.7111.393.7101.188.682

    测试实例配置信息

    shape=MySQL.4
    ha_type=Multi-FD
    preferred_ad=AP-TOKYO-1-AD-1
    region=tokyo
    storage_size=100

    小结

    整体上,在Oracle Cloud上,托管 MySQL 性能较为稳定,尤其是8.0.x系列,CPU资源也较为一致。从上述数据表格中,可以注意到 8.4.x系列和9.x系列,CPU资源略微要低一些。

  • 标题:清华大学教授李国良入选ACM Fellow;腾讯云MySQL只读分析引擎内测发布

    重要更新

    清华大学李国良入选ACM Fellow,以表彰其在人机协同(human-in-the-loop)数据集成与基于学习的数据库系统领域做出的重要贡献。此外,李国良还是 openGauss 社区技术委员会主席。[1]

    更新详情

    阿里云
    • 云盘加密—RDS MySQL存量云盘实例支持开启云盘加密功能。[4]
    GCP(谷歌云)
    • BigQuery 支持使用自然语言准备数据 [6]
    • Cloud SQL for PostgreSQL 版本 17 新增了部分扩展的支持 [15] [16]
    AWS(亚马逊云)
    • CloudWatch 为 Aurora PostgreSQL 提供执行计划捕获[21]
    • Amazon Aurora 现已在亚太地区(马来西亚)区域支持 R7g 和 R7i 实例[23]
    • Amazon Neptune 现支持开源 GraphRAG 工具包[24]
    • Amazon S3 Tables 已在另外五个 AWS 区域推出 [27]
    • Amazon Redshift 宣布支持两个新的地理空间 H3 索引函数[28]
    腾讯云
    • 云数据库 MySQL 只读分析引擎功能进入内测阶段。其针对业务中复杂查询 SQL,大数据的计算,多表 Join 等场景有着数量级性能提升,可广泛适用于业务中的慢查询、批量数据处理、对账查询等典型场景。[34]
    • TDSQL-C MySQL 版“只读分析引擎”发布了全新的问题修复版本 1.2404.20.0 [35]
    • 云数据库 PostgreSQL 开启64core 256GiB、64core 384GiB、64core 512GiB、90core 720GiB规格售卖。[36]

    参考链接

  • 标题:阿里云RDS发布AI插件,支持千问/文本向量等功能;腾讯云TDSQL全年零失误支持超60银行

    重要更新

    Gartner 数据库魔力象限完整报告正式对外发布,阿里云连续5年入选「领导者」象限,华为云进入挑战者象限[1][2]

    阿里云 RDS PostgreSQL 现推出AI插件“rds_ai”,集成了阿里云百炼的先进模型,包括通义千问、通用文本向量和通用文本排序等。通过该插件,您可以在RDS PostgreSQL数据库中轻松实现包括大模型问答、文本向量转换、文本排序、Top N相似向量检索以及RAG问答等多种应用场景。此外,rds_ai还支持自定义模型,您可以灵活添加所需模型,以在RDS PostgreSQL中实现丰富多样的AI应用[3]

    腾讯云数据库TDSQL支撑60+银行年终决算“零失误”。腾讯云数据库TDSQL和腾讯专有云TCE、专有云PaaS平台TCS、大数据平台TBDS、操作系统TencentOS、腾讯云TI平台等“6T“融合创新基础软件,为60多家银行及大型央企财务公司保驾护航,助力它们高效完成决算任务,并且「零失误」。[4]

    更新详情

    腾讯云
    • 云数据库 MySQL 8.0内核版本更新20240930。[27]
    TDSQL-C Link
    • TDSQL-C 支持将“只读分析引擎”加入到新数据库代理中 [28]
    • TDSQL-C 支持通过控制台查看“只读分析引擎”的监控信息、参数等信息。[29][30][31]
    • 云数据库 SQL Server 发布全新 TDE 透明数据加密功能,新增支持密钥来源为用户自定义(KMS)方式[32]
    • 云数据库 SQL Server 发布全新 SSL 加密功能,新增支持证书来源为用户自定义(KMS)方式[33]
    阿里云
    • 阿里云 RDS PG 发布新内核版本,支持了RDS ai、pgsql-http、pgsql-gzip、pgvector 0.8等[34]
    Azure(微软云)
    • 托管 MySQL 的加速日志现与客户管理密钥 (CMK) 支持并默认启用[5]
    • Azure Database for MySQL 中正式支持用户管理插件[6]
    GCP(谷歌云)
    • 现在可以通过配置复制的方式将数据从 Microsoft Azure 迁移到 Cloud SQL [8]
    AWS(亚马逊云)
    • Amazon RDS 在数据库预览环境中支持 MariaDB 11.7 [22]
    • Amazon ElastiCache/MemoryDB 现已支持服务配额(Service Quotas)[23][24]

    参考链接