# Adam — MindSpore Signal+ 使用手册 alpha 文档

# Adam

> 使用 Adam 算法更新参数权重。支持 Nesterov 动量。

> 算法逻辑如下：

> \[\begin{split}m_t = m_{t-1} + (g_t - m_{t-1}) \cdot (1 - \beta_1) \\ v_t = v_{t-1} + (g_t^2 - v_{t-1}) \cdot (1 - \beta_2) \\ \hat{lr} = lr \cdot \frac{\sqrt{1 - \beta_2^t}}{1 - \beta_1^t}\end{split}\]

> 如果不启用 Nesterov：

> \[w_t = w_{t-1} - \hat{lr} \cdot \frac{m_t}{\sqrt{v_t} + \epsilon}\]

> 如果启用 Nesterov：

> \[w_t = w_{t-1} - \hat{lr} \cdot \frac{m_t \cdot \beta_1 + (1 - \beta_1) \cdot g_t}{\sqrt{v_t} + \epsilon}\]
> 输入：

>   - m - 一阶矩向量地址（输入/输出）。

>   - v - 二阶矩向量地址（输入/输出）。

>   - gradient - 梯度向量地址。

>   - weight - 权重向量地址（输入/输出）。

>   - beta1 - 一阶矩估计的指数衰减率。

>   - beta2 - 二阶矩估计的指数衰减率。

>   - beta1_power - \(\beta_1^t\) 的值（指针形式传入）。

>   - beta2_power - \(\beta_2^t\) 的值（指针形式传入）。

>   - eps - 数值稳定性项 epsilon。

>   - learning_rate - 学习率。

>   - nesterov - 是否启用 Nesterov 动量（0: 不启用, 1: 启用）。

>   - start - 计算的起始索引（包含）。

>   - end - 计算的结束索引（不包含）。

>   - core_mask - 核掩码（仅适用于共享存储版本）。

> 输出：

>   - m - 更新后的一阶矩。

>   - v - 更新后的二阶矩。

>   - weight - 更新后的权重。

> 支持平台：

>   `FT78NE` `MT7004`

> 备注

> - 仅支持 fp32 数据类型。

共享存储版本:

void fp_adam_s(float *m, float *v, const float *gradient, float *weight, float beta1, float beta2, float *beta1_power, float *beta2_power, float eps, float learning_rate, int nesterov, int start, int end, int core_mask)

  C调用示例：

       1#include <stdio.h>
       2
       3int main(int argc, char* argv[]) {
       4    // 假设所有数据均位于DDR空间
       5    float* m = (float*)0xC0000000;
       6    float* v = (float*)0xC1000000;
       7    float* gradient = (float*)0xC2000000;
       8    float* weight = (float*)0xC3000000;
       9
      10    // 标量参数
      11    float beta1 = 0.9f;
      12    float beta2 = 0.999f;
      13    float beta1_power_val = 0.9f;   // beta1^1
      14    float beta2_power_val = 0.999f; // beta2^1
      15    float* beta1_power = &beta1_power_val;
      16    float* beta2_power = &beta2_power_val;
      17    float eps = 1e-8f;
      18    float learning_rate = 0.001f;
      19    int nesterov = 1;
      20
      21    int start = 0;
      22    int end = 800000; // 元素总数
      23    int core_mask = 0xff; // 使用所有核心
      24
      25    fp_adam_s(m, v, gradient, weight, beta1, beta2, beta1_power, beta2_power,
      26              eps, learning_rate, nesterov, start, end, core_mask);
      27
      28    return 0;
      29}

私有存储版本:

void fp_adam_p(float *m, float *v, const float *gradient, float *weight, float beta1, float beta2, float *beta1_power, float *beta2_power, float eps, float learning_rate, int nesterov, int start, int end)

  C调用示例：

       1#include <stdio.h>
       2
       3int main(int argc, char* argv[]) {
       4    // 假设所有数据均位于L2/AM空间
       5    float* m = (float*)0x10820000;
       6    float* v = (float*)0x10830000;
       7    float* gradient = (float*)0x10840000;
       8    float* weight = (float*)0x10850000;
       9
      10    float beta1 = 0.9f;
      11    float beta2 = 0.999f;
      12    float beta1_power_val = 0.9f;
      13    float beta2_power_val = 0.999f;
      14    float eps = 1e-8f;
      15    float learning_rate = 0.001f;
      16    int nesterov = 0;
      17    int start = 0;
      18    int end = 2000;
      19
      20    fp_adam_p(m, v, gradient, weight, beta1, beta2, &beta1_power_val, &beta2_power_val,
      21              eps, learning_rate, nesterov, start, end);
      22
      23    return 0;
      24}