diff --git a/optimizer/README.md b/optimizer/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..30b2e28828f00db65b00569d5d06f7107149f7b1
--- /dev/null
+++ b/optimizer/README.md
@@ -0,0 +1,825 @@
+# 优化实验
+
+## 实验介绍
+
+本实验主要介绍如何使用MindSpore进行优化实验。共包含两个实验分别为:
+
+- 实验一:利用不同优化器求解函数极值点实验
+- 实验二:鸢尾花数据在不同优化器下的分类实验
+
+通过分析无优化器、SGD优化器、Momentum优化器、Adam优化器模型在求极值点和分类任务下的结果 ,得到不同优化器的作用。
+
+## 实验目的
+
+- 掌握MindSpore中优化器的使用及其作用。
+- 了解如何使用MindSpore进行SGD、Momentum、Adam优化器实验。
+- 了解不同优化器原理。
+
+## 预备知识
+
+- 熟练使用Python。
+- 具备一定的深度学习理论知识,如感知机、损失函数、优化器,训练策略等。
+- 了解华为云的基本使用方法,包括[ModelArts(AI开发平台)](https://www.huaweicloud.com/product/modelarts.html)、[训练作业](https://support.huaweicloud.com/engineers-modelarts/modelarts_23_0046.html)等功能。华为云官网:https://www.huaweicloud.com
+- 了解并熟悉MindSpore AI计算框架,MindSpore官网:https://www.mindspore.cn/
+
+## 实验环境
+
+- MindSpore 0.5.0(MindSpore版本会定期更新,本指导也会定期刷新,与版本配套);
+- 华为云ModelArts:ModelArts是华为云提供的面向开发者的一站式AI开发平台,集成了昇腾AI处理器资源池,用户可以在该平台下体验MindSpore。ModelArts官网:https://www.huaweicloud.com/product/modelarts.html
+
+## 实验准备
+
+### 创建OBS桶
+
+本实验需要使用华为云OBS存储脚本,可以参考[快速通过OBS控制台上传下载文件](https://support.huaweicloud.com/qs-obs/obs_qs_0001.html)了解使用OBS创建桶、上传文件、下载文件的使用方法。
+
+> **提示:** 华为云新用户使用OBS时通常需要创建和配置“访问密钥”,可以在使用OBS时根据提示完成创建和配置。也可以参考[获取访问密钥并完成ModelArts全局配置](https://support.huaweicloud.com/prepare-modelarts/modelarts_08_0002.html)获取并配置访问密钥。
+
+创建OBS桶的参考配置如下:
+
+- 区域:华北-北京四
+- 数据冗余存储策略:单AZ存储
+- 桶名称:全局唯一的字符串
+- 存储类别:标准存储
+- 桶策略:公共读
+- 归档数据直读:关闭
+- 企业项目、标签等配置:免
+
+### 数据集准备
+
+#### 求函数极值点
+
+为了评价优化器的特性,我们模拟了一个目标函数求极值过程。定义不同优化器求其极值,与目标结果比较。
+
+目标函数Beale 公式:
+
+$$
+f(x_1,x_2)=(1.5−x_1+x_1x_2)^2+(2.25−x_1+x_1x_2^2)^2+(2.625−x_1+x_1x_2^3)^2
+$$
+
+表面如下图:
+
+

+
+
+方程极值点$ (x_1, x_2) = (3, 0.5) $
+
+我们需要通过各种不同的优化器来优化目标函数。优化器的主要目的是通过迭代找到目标函数的极小值或者极大值。常用的优化器有:SGD、Momentum、NAG、Adagrad、Adam等。
+
+定义目标函数beale、目标函数的偏导函数dbeale_dx,并画出目标函数和极值点
+
+```python
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.colors as plt_cl
+
+# ------------------定义目标函数beale、目标函数的偏导函数dbeale_dx,并画出目标函数---------------------
+# 定义函数beale
+def beale(x1, x2):
+ return (1.5 - x1 + x1 * x2) ** 2 + (2.25 - x1 + x1 * x2 ** 2) ** 2 + (2.625 - x1 + x1 * x2 ** 3) ** 2
+
+# 定义函数beale的偏导
+def dbeale_dx(x1, x2):
+ dfdx1 = 2 * (1.5 - x1 + x1 * x2) * (x2 - 1) + 2 * (2.25 - x1 + x1 * x2 ** 2) * (x2 ** 2 - 1) + 2 * (
+ 2.625 - x1 + x1 * x2 ** 3) * (x2 ** 3 - 1)
+ dfdx2 = 2 * (1.5 - x1 + x1 * x2) * x1 + 2 * (2.25 - x1 + x1 * x2 ** 2) * (2 * x1 * x2) + 2 * (
+ 2.625 - x1 + x1 * x2 ** 3) * (3 * x1 * x2 ** 2)
+ return dfdx1, dfdx2
+step_x1, step_x2 = 0.2, 0.2
+X1, X2 = np.meshgrid(np.arange(-5, 5 + step_x1, step_x1),
+ np.arange(-5, 5 + step_x2, step_x2))
+Y = beale(X1, X2)
+print("目标结果 (x_1, x_2) = (3, 0.5)")
+
+# 定义画图函数
+def gd_plot(x_traj):
+ plt.rcParams['figure.figsize'] = [6, 6]
+ plt.contour(X1, X2, Y, levels=np.logspace(0, 6, 30),
+ norm=plt_cl.LogNorm(), cmap=plt.cm.jet)
+ plt.title('2D Contour Plot of Beale function(Momentum)')
+ plt.xlabel('$x_1$')
+ plt.ylabel('$x_2$')
+ plt.axis('equal')
+ plt.plot(3, 0.5, 'k*', markersize=10)
+ if x_traj is not None:
+ x_traj = np.array(x_traj)
+ plt.plot(x_traj[:, 0], x_traj[:, 1], 'k-')
+ plt.show()
+
+gd_plot(None)
+```
+
+ 目标结果 (x_1, x_2) = (3, 0.5)
+
+
+
+#### 鸢尾花分类数据集
+
+鸢尾花数据集(Iris Dataset)是模式识别最著名的数据集之一。共收集了三类鸢尾花,即Setosa鸢尾花、Versicolour鸢尾花和Virginica鸢尾花,每一类鸢尾花收集了50条样本记录,共计150条。
+
+数据集包括4个属性,分别为花萼的长、花萼的宽、花瓣的长和花瓣的宽。对花瓣我们可能比较熟悉,花萼是什么呢?花萼是花冠外面的绿色被叶,在花尚未开放时,保护着花蕾。四个属性的单位都是cm,属于数值变量,1个标签,表示鸢尾花的分类。
+
+在Iris数据集的官网[Iris Data Set](http://archive.ics.uci.edu/ml/datasets/Iris)上下载[iris.data](http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data)文件。
+
+### 脚本准备
+
+从[课程gitee仓库](https://gitee.com/mindspore/course)上下载本实验相关脚本。
+
+### 上传文件
+
+将脚本和数据集上传到OBS桶中,组织为如下形式:
+
+```
+optimizer
+├── main1.py
+├── main2.py
+└── iris
+ └── iris.data
+```
+
+## 实验步骤
+
+### 实验一:求函数极值点实验
+
+#### 无优化器模型训练、测试、预测
+
+原理:无优化器训练不更新参数,不管训练多少次,模型的参数没有发生变化。模型效果与模型初始化参数关系较大。
+
+下面是不使用优化器求解Beale 公式极值点实现。
+
+```python
+# ------------------------------------------------------------无优化器-------------------------------------------
+def gd_no(df_dx, x0, conf_para=None):
+ if conf_para is None:
+ conf_para = {}
+ conf_para.setdefault('n_iter', 1000) # 迭代次数
+ conf_para.setdefault('learning_rate', 0.001) # 设置学习率
+ x_traj = []
+ x_traj.append(x0)
+ v = np.zeros_like(x0)
+ for iter in range(1, conf_para['n_iter'] + 1):
+ x_traj.append(x_traj[-1])
+ return x_traj
+
+x0 = np.array([1.0, 1.5])
+conf_para_no = {'n_iter': 2000, 'learning_rate': 0.005}
+x_traj_no = gd_no(dbeale_dx, x0, conf_para_no)
+print("无优化器求得极值点 (x_1, x_2) = (%s, %s)" % (x_traj_no[-1][0], x_traj_no[-1][1]))
+gd_plot(x_traj_no)
+```
+
+```
+无优化器求得极值点 (x_1, x_2) = (1.0, 1.5)
+```
+
+#### SGD优化器模型训练、测试、预测
+
+梯度下降法:梯度下降(gradient descent)在机器学习中应用十分的广泛,是求解无约束优化问题最简单和最古老的方法之一。通过迭代,参数向梯度的反方向更新,直到收敛。
+
+$$
+W_{new} = W - \eta\frac{\partial J(W)}{\partial W}
+$$
+
+其中$ \frac{\partial J(W)}{\partial W} $ 表示损失函数 J 关于参数W的梯度;$ \eta $表示学习率;
+
+>**缺点:**
+>
+>- 有可能会陷入局部最小值;
+>- 不会收敛,最终会一直在最小值附近波动,并不会达到最小值并停留在此;
+>- 下降速度慢;
+>- 选择合适的学习率比较困难;
+>- 在所有方向上统一的缩放梯度,不适用于稀疏数据;
+
+下面是使用SGD优化器求解Beale 公式极值点实现。
+
+```python
+# ------------------------------------------------------------SGD-------------------------------------------
+def gd_sgd(df_dx, x0, conf_para=None):
+ if conf_para is None:
+ conf_para = {}
+ conf_para.setdefault('n_iter', 1000) # 迭代次数
+ conf_para.setdefault('learning_rate', 0.001) # 设置学习率
+ x_traj = []
+ x_traj.append(x0)
+ v = np.zeros_like(x0)
+ for iter in range(1, conf_para['n_iter'] + 1):
+ dfdx = np.array(df_dx(x_traj[-1][0], x_traj[-1][1]))
+ v = - conf_para['learning_rate'] * dfdx
+ x_traj.append(x_traj[-1] + v)
+ return x_traj
+
+x0 = np.array([1.0, 1.5])
+conf_para_sgd = {'n_iter': 2000, 'learning_rate': 0.005}
+x_traj_sgd = gd_sgd(dbeale_dx, x0, conf_para_sgd)
+print("SGD求得极值点 (x_1, x_2) = (%s, %s)" % (x_traj_sgd[-1][0], x_traj_sgd[-1][1]))
+gd_plot(x_traj_sgd)
+```
+
+```
+SGD求得极值点 (x_1, x_2) = (2.981957257903412, 0.4954609564102124)
+```
+
+
+
+#### Momentum优化器模型训练、测试、预测
+
+Momentum:是动量优化法中的一种(Momentum、NAG),即使用动量(Momentum)的随机梯度下降法(SGD),主要思想是引入一个积攒历史梯度信息的动量来加速SGD。其参数优化公式如下所示:
+
+$$
+v_{new} = \gamma v - \eta\frac{\partial J(W)}{\partial W} \\
+W_{new} = W + v_{new}
+$$
+
+其中$ \frac{\partial J(W)}{\partial W} $ 表示损失函数 J 关于参数W的梯度;$ \eta $表示学习率;$ \gamma $表示动量的大小,一般取值为0.9。
+
+这个算法和之前的梯度下降法(SGD)相比,唯一不同的就是多了一个$ \gamma v$。这一改动使Momentum会观察历史梯度,若当前梯度的方向与历史梯度一致(表明当前样本不太可能为异常点),则会增强这个方向的梯度;若当前梯度与历史梯方向不一致,则梯度会衰减。一种形象的解释是:我们把一个球推下山,球在下坡时积聚动量,在途中变得越来越快,γ可视为空气阻力,若球的方向发生变化,则动量会衰减。
+
+>**优点:**
+>
+>- 参考了历史梯度,增加了稳定性;
+>- 由于引入加速动量,加快收敛速度。下降初期时,使用上一次参数更新,下降方向一致,乘上较大的$ \gamma $能够进行很好的加速;
+>- 还有一定摆脱局部最优的能力。下降中后期时,在局部最小值来回震荡的时候,梯度趋近于0,$ \gamma $使得更新幅度增大,跳出陷阱(局部最优);
+
+下面是使用Momentum优化器求解Beale 公式极值点实现。
+
+```python
+# -------------------------------------------------------Momentum---------------------------------
+def gd_momentum(df_dx, x0, conf_para=None):
+ if conf_para is None:
+ conf_para = {}
+ conf_para.setdefault('n_iter', 1000) # 迭代次数
+ conf_para.setdefault('learning_rate', 0.001) # 设置学习率
+ conf_para.setdefault('momentum', 0.9) # 设置动量参数
+ x_traj = []
+ x_traj.append(x0)
+ v = np.zeros_like(x0)
+ for iter in range(1, conf_para['n_iter'] + 1):
+ dfdx = np.array(df_dx(x_traj[-1][0], x_traj[-1][1]))
+ v = conf_para['momentum'] * v - conf_para['learning_rate'] * dfdx
+ x_traj.append(x_traj[-1] + v)
+ return x_traj
+
+x0 = np.array([1.0, 1.5])
+conf_para_momentum = {'n_iter': 500, 'learning_rate': 0.005}
+x_traj_momentum = gd_momentum(dbeale_dx, x0, conf_para_momentum)
+print("Momentum求得极值点 (x_1, x_2) = (%s, %s)" % (x_traj_momentum[-1][0], x_traj_momentum[-1][1]))
+gd_plot(x_traj_momentum)
+```
+
+```
+Momentum求得极值点 (x_1, x_2) = (3.0004236971560485, 0.5001057348328146)
+```
+
+
+
+#### 自适应优化器模型训练、测试、预测
+
+自适应学习率优化算法主要有:AdaGrad算法,RMSProp算法,Adam算法以及AdaDelta算法。
+
+**AdaGrad**
+
+AdaGrad的基本思想是对每个变量用不同的学习率。这个学习率在一开始比较大,用于快速梯度下降。随着优化过程的进行,对于已经下降很多的变量,则减缓学习率,对于还没怎么下降的变量,则保持一个较大的学习率。其参数优化公式如下所示:
+
+$$
+G_{new} = G + (\frac{\partial J(W)}{\partial W})^2 \\
+W_{new} = W - \frac{\eta}{(\sqrt{G_{new}} + \varepsilon)}\cdot\frac{\partial J(W)}{\partial W}
+$$
+
+其中$ \frac{\partial J(W)}{\partial W} $ 表示损失函数 J 关于参数W的梯度;$ \eta $表示学习率,一般取值0.01;$ \varepsilon $是一个很小的数,防止分母为0;$G_{new}$表示了前t 步参数$W$梯度的平方累加。把沿路的Gradient的平方根,作为Regularizer。分母作为Regularizer项的工作机制如下:
+
+1. 训练前期,梯度较小,使得Regularizer项很大,放大梯度。[激励阶段]
+2. 训练后期,梯度较大,使得Regularizer项很小,缩小梯度。[惩罚阶段]
+
+>**优点:**
+>
+>- 在数据分布稀疏的场景,能更好利用稀疏梯度的信息,比标准的SGD算法更有效地收敛;
+>- 对每个变量用不同的学习率,对输入参数学习率的依赖小,容易调节参数;
+
+>**缺点:**
+>
+>- 主要缺陷来自分母项的对梯度平方不断累积,随之时间步地增加,分母项越来越大,最终导致学习率收缩到太小无法进行有效更新;
+
+**RMSProp**
+
+为了解决 Adagrad 学习率急剧下降问题,RMSProp保留过去梯度的微分平方数项,旨在消除梯度下降中的摆动。与Momentum的效果一样,某一维度的导数比较大,则指数加权平均就大,某一维度的导数比较小,则其指数加权平均就小,这样就保证了各维度导数都在一个量级,进而减少了摆动。允许使用一个更大的学习率η。其参数优化公式如下所示:
+
+$$
+v_{new} = \gamma\cdot v + (1 - \gamma)\cdot{(\frac{\partial J(W)}{\partial W})}^2 \\
+W_{new} = W - \frac{\eta}{(\sqrt{v_{new}} + \varepsilon)}(\frac{\partial J(W)}{\partial W})
+$$
+
+其中$ \frac{\partial J (W)}{\partial W} $ 表示损失函数 J 关于参数W的梯度;$ \eta $表示学习率,一般取值0.001;$ \varepsilon $是一个很小的数,防止分母为0;$ \gamma $表示动量的大小,一般取值为0.9。
+
+**Adam**
+
+Adam算法是另一种计算每个参数的自适应学习率的方法。相当于 RMSprop + Momentum。除了像RMSprop存储了过去梯度的平方 $ v_t $ 的指数衰减平均值 ,也像 momentum 一样保持了过去梯度$ m_t $ 的指数衰减平均值。其参数优化公式如下所示:
+
+$$
+m_{new} = \beta _1 m + (1 - \beta _1)(\frac{\partial J(W)}{\partial W})
+$$
+
+$$
+v_{new} = \beta _2 v + (1 - \beta _2)(\frac{\partial J(W)}{\partial W})^2
+$$
+
+由于$\frac{m_0}{v_0}$初始化为0,会导致$\frac{m_{new}}{v_{new}}$偏向于0,尤其在训练初期阶段,所以,此处需要对梯度均值$\frac{m_{new}}{v_{new}}$进行偏差纠正,降低偏差对训练初期的影响。
+
+$$
+\hat{m_{new}} = m_{new} / (1 - \beta _1)
+$$
+
+$$
+\hat{v_{new}} = v_{new} / (1 - \beta _2)
+$$
+
+$$
+W_{new} = W - \eta\frac{1}{\sqrt{\hat{v_{new}}} + \varepsilon}\hat{m_{new}}
+$$
+
+其中$ \frac{\partial J (W)}{\partial W} $ 表示损失函数 J 关于参数W的梯度;$ \eta $表示学习率,一般取值0.001;$ \varepsilon $是一个很小的数,一般取值10e−8,防止分母为0;$ \beta _1 $ $ \beta _2 $分别表示一阶和二阶动量的大小,一般取值为$ \beta _1 = 0.9 $ $ \beta _2 = 0.99 $。
+
+>**优点**
+>
+>- 能够克服AdaGrad梯度急剧减小的问题,在很多应用中都展示出优秀的学习率自适应能力;
+>- 实现简单,计算高效,对内存需求少;
+>- 参数的更新不受梯度的伸缩变换影响;
+>- 超参数具有很好的解释性,且通常无需调整或仅需很少的微调;
+>- 更新的步长能够被限制在大致的范围内(初始学习率);
+>- 能自然地实现步长退火过程(自动调整学习率);
+>- 很适合应用于大规模的数据及参数的场景;
+>- 适用于不稳定目标函数;
+>- 适用于梯度稀疏或梯度存在很大噪声的问题;
+
+下面是使用自适应优化器求解Beale 公式极值点实现。
+
+```python
+# ----------------------------------------------------adagrad-----------------------------
+def gd_adagrad(df_dx, x0, conf_para=None):
+ if conf_para is None:
+ conf_para = {}
+ conf_para.setdefault('n_iter', 1000) # 迭代次数
+ conf_para.setdefault('learning_rate', 0.001) # 学习率
+ conf_para.setdefault('epsilon', 1e-7)
+ x_traj = []
+ x_traj.append(x0)
+ r = np.zeros_like(x0)
+ for iter in range(1, conf_para['n_iter'] + 1):
+ dfdx = np.array(df_dx(x_traj[-1][0], x_traj[-1][1]))
+ r += dfdx ** 2
+ x_traj.append(x_traj[-1] - conf_para['learning_rate'] / (np.sqrt(r) + conf_para['epsilon']) * dfdx)
+ return x_traj
+
+x0 = np.array([1.0, 1.5])
+conf_para_adag = {'n_iter': 500, 'learning_rate': 2}
+x_traj_adag = gd_adagrad(dbeale_dx, x0, conf_para_adag)
+print("Adagrad求得极值点 (x_1, x_2) = (%s, %s)" % (x_traj_adag[-1][0], x_traj_adag[-1][1]))
+gd_plot(x_traj_adag)
+```
+
+ Adagrad求得极值点 (x_1, x_2) = (2.9993173156940776, 0.49982846432011524)
+
+
+
+从结果可以看出:无优化器参数不更新,求函数极值点无效。SGD、Momentum、自适应优化器求得的极值点与目标点(3.0, 0.5)较近。SGD、Momentum、自适应优化器求解极值点方法有效。其中SGD优化器实验需要的迭代次数2000多,相比与后边Momentum优化器多迭代1500次,证明了SGD优化器收敛速度慢。从图像可以看出自适应优化器对收敛方向把握比较好。
+
+### 实验二:鸢尾花分类实验
+
+#### 导入MindSpore模块和辅助模块
+
+```python
+import csv
+import os
+import time
+
+import numpy as np
+from easydict import EasyDict as edict
+from matplotlib import pyplot as plt
+
+import mindspore
+from mindspore import nn
+from mindspore import context
+from mindspore import dataset
+from mindspore.train.callback import TimeMonitor, LossMonitor
+from mindspore import Tensor
+from mindspore.train import Model
+from mindspore.train.callback import ModelCheckpoint, CheckpointConfig
+
+context.set_context(mode=context.GRAPH_MODE, device_target="Ascend")
+```
+
+#### 变量定义
+
+```python
+cfg = edict({
+ 'data_size': 150,
+ 'train_size': 120, #训练集大小
+ 'test_size': 30 , #测试集大小
+ 'feature_number': 4, #输入特征数
+ 'num_class': 3, #分类类别
+ 'batch_size': 30,
+ 'data_dir': 'iris.data',
+ 'save_checkpoint_steps': 5, #多少步保存一次模型
+ 'keep_checkpoint_max': 1, #最多保存多少个模型
+ 'out_dir_no_opt': './model_iris/no_opt', #保存模型路径,无优化器模型
+ 'out_dir_sgd': './model_iris/sgd', #保存模型路径,SGD优化器模型
+ 'out_dir_momentum': './model_iris/momentum', #保存模型路径,momentum模型
+ 'out_dir_adam': './model_iris/adam', #保存模型路径,adam优化器模型
+ 'output_prefix': "checkpoint_fashion_forward" #保存模型文件名
+})
+```
+
+#### 读取数据并预处理
+
+读取Iris数据集`iris.data`,并作检查。
+
+```python
+with open(cfg.data_dir) as csv_file:
+ data = list(csv.reader(csv_file, delimiter=','))
+print(data[0:5]); print(data[50:55]); print(data[100:105]) # 打印部分数据
+```
+
+ [['5.1', '3.5', '1.4', '0.2', 'Iris-setosa'], ['4.9', '3.0', '1.4', '0.2', 'Iris-setosa'], ['4.7', '3.2', '1.3', '0.2', 'Iris-setosa'], ['4.6', '3.1', '1.5', '0.2', 'Iris-setosa'], ['5.0', '3.6', '1.4', '0.2', 'Iris-setosa']]
+ [['7.0', '3.2', '4.7', '1.4', 'Iris-versicolor'], ['6.4', '3.2', '4.5', '1.5', 'Iris-versicolor'], ['6.9', '3.1', '4.9', '1.5', 'Iris-versicolor'], ['5.5', '2.3', '4.0', '1.3', 'Iris-versicolor'], ['6.5', '2.8', '4.6', '1.5', 'Iris-versicolor']]
+ [['6.3', '3.3', '6.0', '2.5', 'Iris-virginica'], ['5.8', '2.7', '5.1', '1.9', 'Iris-virginica'], ['7.1', '3.0', '5.9', '2.1', 'Iris-virginica'], ['6.3', '2.9', '5.6', '1.8', 'Iris-virginica'], ['6.5', '3.0', '5.8', '2.2', 'Iris-virginica']]
+
+共150条数据,将数据集的4个属性作为自变量X。将数据集的3个类别映射为{0, 1,2},作为因变量Y。
+
+```python
+label_map = {'Iris-setosa': 0,'Iris-versicolor': 1,'Iris-virginica':2 }
+X = np.array([[float(x) for x in s[:-1]] for s in data[:cfg.data_size]], np.float32)
+Y = np.array([label_map[s[-1]] for s in data[:cfg.data_size]], np.int32)
+```
+
+取样本的前两个属性进行2维可视化。发现Iris-setosa类和其他两类是线性可分的。Iris-versicolor类和Iris-virginica类是线性不可分的。
+
+```python
+plt.scatter(X[:50, 0], X[:50, 1], label='Iris-setosa')
+plt.scatter(X[50:100, 0], X[50:100, 1], label='Iris-versicolor')
+plt.scatter(X[100:, 0], X[100:, 1], label='Iris-virginica')
+plt.xlabel('sepal length')
+plt.ylabel('sepal width')
+plt.legend()
+```
+
+
+
+将数据集分为训练集120条,测试集30条。
+
+```python
+# 将数据集分为训练集120条,测试集30条。
+train_idx = np.random.choice(cfg.data_size, cfg.train_size, replace=False)
+test_idx = np.array(list(set(range(cfg.data_size)) - set(train_idx)))
+X_train, Y_train = X[train_idx], Y[train_idx]
+X_test, Y_test = X[test_idx], Y[test_idx]
+print('训练数据x尺寸:', X_train.shape)
+print('训练数据y尺寸:', Y_train.shape)
+print('测试数据x尺寸:', X_test.shape)
+print('测试数据y尺寸:', Y_test.shape)
+```
+
+ 训练数据x尺寸: (120, 4)
+ 训练数据y尺寸: (120,)
+ 测试数据x尺寸: (30, 4)
+ 测试数据y尺寸: (30,)
+
+使用MindSpore GeneratorDataset接口将numpy.ndarray类型的数据转换为Dataset。
+
+```python
+def gen_data(X_train, Y_train, epoch_size):
+ XY_train = list(zip(X_train, Y_train))
+ ds_train = dataset.GeneratorDataset(XY_train, ['x', 'y'])
+ ds_train.set_dataset_size(cfg.train_size)
+ ds_train = ds_train.shuffle(buffer_size=cfg.train_size).batch(cfg.batch_size, drop_remainder=True)
+ XY_test = list(zip(X_test, Y_test))
+ ds_test = dataset.GeneratorDataset(XY_test, ['x', 'y'])
+ ds_test.set_dataset_size(cfg.test_size)
+ ds_test = ds_test.shuffle(buffer_size=cfg.test_size).batch(cfg.test_size, drop_remainder=True)
+ return ds_train, ds_test
+```
+
+为了更好的观察loss变化,重写Lossmonitor。
+
+```python
+class SubLossMonitor(LossMonitor):
+ def epoch_end(self, run_context):
+ pass
+
+ def step_end(self, run_context):
+ cb_params = run_context.original_args()
+ step_loss = cb_params.net_outputs
+
+ if isinstance(step_loss, (tuple, list)) and isinstance(step_loss[0], Tensor):
+ step_loss = step_loss[0]
+ if isinstance(step_loss, Tensor):
+ step_loss = np.mean(step_loss.asnumpy())
+
+ self.losses.append(step_loss)
+ cur_step_in_epoch = int((cb_params.cur_step_num - 1) % cb_params.batch_num) + 1
+
+ if isinstance(step_loss, float) and (np.isnan(step_loss) or np.isinf(step_loss)):
+ raise ValueError("Epoch: [{:3d}/{:3d}], step: [{:5d}/{:5d}]. "
+ "Invalid loss, terminating training.".format(
+ cb_params.cur_epoch_num - 1, cb_params.epoch_num,
+ cur_step_in_epoch, cb_params.batch_num))
+
+ if self._per_print_times != 0 and cb_params.cur_step_num % self._per_print_times == 0:
+ print("epoch: {} step {}, loss: {}, avg loss: {:5.3f}".format(cb_params.cur_epoch_num,
+ cur_step_in_epoch,
+ step_loss, np.mean(self.losses)), flush=True)
+```
+
+#### 定义训练、测试、预测过程
+
+```python
+# 训练
+def train(network, net_opt, ds_train, prefix, directory, print_times):
+ net_loss = nn.SoftmaxCrossEntropyWithLogits(is_grad=False, sparse=True, reduction="mean")
+ model = Model(network, loss_fn=net_loss, optimizer=net_opt, metrics={"acc"})
+ loss_cb = SubLossMonitor(per_print_times=print_times)
+ config_ck = CheckpointConfig(save_checkpoint_steps=cfg.save_checkpoint_steps,
+ keep_checkpoint_max=cfg.keep_checkpoint_max)
+ ckpoint_cb = ModelCheckpoint(prefix=prefix, directory=directory, config=config_ck)
+ print("============== Starting Training ==============")
+ model.train(epoch_size, ds_train, callbacks=[ckpoint_cb, loss_cb], dataset_sink_mode=False)
+ return model
+```
+
+```python
+# 评估预测
+def eval_predict(model, ds_test):
+ # 使用测试集评估模型,打印总体准确率
+ metric = model.eval(ds_test)
+ print(metric)
+ # 预测
+ test_ = ds_test.create_dict_iterator().get_next()
+ test = Tensor(test_['x'], mindspore.float32)
+ predictions = model.predict(test)
+ predictions = predictions.asnumpy()
+ for i in range(10):
+ p_np = predictions[i, :]
+ p_list = p_np.tolist()
+ print('第' + str(i) + '个sample预测结果:', p_list.index(max(p_list)), ' 真实结果:', test_['y'][i])
+```
+
+#### 无优化器训练、测试、预测
+
+```python
+# --------------------------------------------------无优化器-----------------------------------
+epoch_size = 20
+print('------------------无优化器--------------------------')
+# 数据
+ds_train, ds_test = gen_data(X_train, Y_train, epoch_size)
+# 定义网络并训练
+network = nn.Dense(cfg.feature_number, cfg.num_class)
+model = train(network, None, ds_train, "checkpoint_no_opt", cfg.out_dir_no_opt, 4)
+# 评估预测
+eval_predict(model, ds_test)
+```
+
+ ============== Starting Training ==============
+ epoch: 1 step 4, loss: 1.0889194011688232, avg loss: 1.085
+ epoch: 2 step 4, loss: 1.0786006450653076, avg loss: 1.085
+ epoch: 3 step 4, loss: 1.087601900100708, avg loss: 1.085
+ epoch: 4 step 4, loss: 1.0797476768493652, avg loss: 1.085
+ epoch: 5 step 4, loss: 1.0873146057128906, avg loss: 1.085
+ epoch: 6 step 4, loss: 1.0899147987365723, avg loss: 1.085
+ epoch: 7 step 4, loss: 1.0889571905136108, avg loss: 1.085
+ epoch: 8 step 4, loss: 1.0873101949691772, avg loss: 1.085
+ epoch: 9 step 4, loss: 1.0905265808105469, avg loss: 1.085
+ epoch: 10 step 4, loss: 1.0831623077392578, avg loss: 1.085
+ epoch: 11 step 4, loss: 1.0847382545471191, avg loss: 1.085
+ epoch: 12 step 4, loss: 1.079599142074585, avg loss: 1.085
+ epoch: 13 step 4, loss: 1.086871862411499, avg loss: 1.085
+ epoch: 14 step 4, loss: 1.0913140773773193, avg loss: 1.085
+ epoch: 15 step 4, loss: 1.0870290994644165, avg loss: 1.085
+ epoch: 16 step 4, loss: 1.0817103385925293, avg loss: 1.085
+ epoch: 17 step 4, loss: 1.0873748064041138, avg loss: 1.085
+ epoch: 18 step 4, loss: 1.0746941566467285, avg loss: 1.085
+ epoch: 19 step 4, loss: 1.0819764137268066, avg loss: 1.085
+ epoch: 20 step 4, loss: 1.0972342491149902, avg loss: 1.085
+ {'acc': 0.43333333333333335}
+ 第0个sample预测结果: 2 真实结果: 2
+ 第1个sample预测结果: 0 真实结果: 0
+ 第2个sample预测结果: 0 真实结果: 0
+ 第3个sample预测结果: 2 真实结果: 1
+ 第4个sample预测结果: 2 真实结果: 1
+ 第5个sample预测结果: 2 真实结果: 2
+ 第6个sample预测结果: 2 真实结果: 1
+ 第7个sample预测结果: 2 真实结果: 2
+ 第8个sample预测结果: 2 真实结果: 2
+ 第9个sample预测结果: 2 真实结果: 0
+
+#### SGD优化器模型训练、测试、预测
+
+```python
+# ---------------------------------------------------SGD-------------------------------------
+epoch_size = 200
+lr = 0.01
+print('-------------------SGD优化器-----------------------')
+# 数据
+ds_train, ds_test = gen_data(X_train, Y_train, epoch_size)
+# 定义网络并训练、测试、预测
+network = nn.Dense(cfg.feature_number, cfg.num_class)
+net_opt = nn.SGD(network.trainable_params(), lr)
+model = train(network, net_opt, ds_train, "checkpoint_sgd", cfg.out_dir_sgd, 40)
+# 评估预测
+eval_predict(model, ds_test)
+```
+
+```
+============== Starting Training ==============
+epoch: 10 step 4, loss: 0.9191734194755554, avg loss: 0.885
+epoch: 20 step 4, loss: 0.7677731513977051, avg loss: 0.764
+epoch: 30 step 4, loss: 0.7029662132263184, avg loss: 0.678
+epoch: 40 step 4, loss: 0.6191470623016357, avg loss: 0.633
+epoch: 50 step 4, loss: 0.5822886228561401, avg loss: 0.588
+epoch: 60 step 4, loss: 0.5903770923614502, avg loss: 0.562
+epoch: 70 step 4, loss: 0.48483023047447205, avg loss: 0.533
+epoch: 80 step 4, loss: 0.5035678148269653, avg loss: 0.514
+epoch: 90 step 4, loss: 0.44619810581207275, avg loss: 0.502
+epoch: 100 step 4, loss: 0.5394692420959473, avg loss: 0.483
+epoch: 110 step 4, loss: 0.4881630837917328, avg loss: 0.472
+epoch: 120 step 4, loss: 0.48909181356430054, avg loss: 0.462
+epoch: 130 step 4, loss: 0.48934054374694824, avg loss: 0.449
+epoch: 140 step 4, loss: 0.44362297654151917, avg loss: 0.438
+epoch: 150 step 4, loss: 0.4909963607788086, avg loss: 0.430
+epoch: 160 step 4, loss: 0.38809025287628174, avg loss: 0.421
+epoch: 170 step 4, loss: 0.43030044436454773, avg loss: 0.417
+epoch: 180 step 4, loss: 0.40883880853652954, avg loss: 0.408
+epoch: 190 step 4, loss: 0.4194946885108948, avg loss: 0.399
+epoch: 200 step 4, loss: 0.41460859775543213, avg loss: 0.397
+{'acc': 0.9666666666666667}
+第0个sample预测结果: 0 真实结果: 0
+第1个sample预测结果: 0 真实结果: 0
+第2个sample预测结果: 0 真实结果: 0
+第3个sample预测结果: 0 真实结果: 0
+第4个sample预测结果: 1 真实结果: 1
+第5个sample预测结果: 1 真实结果: 1
+第6个sample预测结果: 2 真实结果: 2
+第7个sample预测结果: 2 真实结果: 2
+第8个sample预测结果: 2 真实结果: 2
+第9个sample预测结果: 2 真实结果: 2
+```
+
+#### Momentum优化器模型训练、测试、预测
+
+```python
+# ----------------------------------------------------Momentum-------------------------------
+epoch_size = 20
+lr = 0.01
+print('-------------------Momentum优化器-----------------------')
+# 数据
+ds_train, ds_test = gen_data(X_train, Y_train, epoch_size)
+# 定义网络并训练
+network = nn.Dense(cfg.feature_number, cfg.num_class)
+net_opt = nn.Momentum(network.trainable_params(), lr, 0.9)
+model = train(network, net_opt, ds_train, "checkpoint_momentum", cfg.out_dir_momentum, 4)
+# 评估预测
+eval_predict(model, ds_test)
+```
+
+ ============== Starting Training ==============
+ epoch: 1 step 4, loss: 1.0203474760055542, avg loss: 1.059
+ epoch: 2 step 4, loss: 0.9105612635612488, avg loss: 0.989
+ epoch: 3 step 4, loss: 0.808910608291626, avg loss: 0.863
+ epoch: 4 step 4, loss: 0.7031147480010986, avg loss: 0.775
+ epoch: 5 step 4, loss: 0.5979485511779785, avg loss: 0.680
+ epoch: 6 step 4, loss: 0.6117547750473022, avg loss: 0.612
+ epoch: 7 step 4, loss: 0.46994972229003906, avg loss: 0.569
+ epoch: 8 step 4, loss: 0.5184788703918457, avg loss: 0.553
+ epoch: 9 step 4, loss: 0.5600728988647461, avg loss: 0.514
+ epoch: 10 step 4, loss: 0.46992775797843933, avg loss: 0.489
+ epoch: 11 step 4, loss: 0.4271170496940613, avg loss: 0.474
+ epoch: 12 step 4, loss: 0.49392855167388916, avg loss: 0.466
+ epoch: 13 step 4, loss: 0.44602206349372864, avg loss: 0.442
+ epoch: 14 step 4, loss: 0.45520901679992676, avg loss: 0.439
+ epoch: 15 step 4, loss: 0.3911263346672058, avg loss: 0.421
+ epoch: 16 step 4, loss: 0.4466801881790161, avg loss: 0.415
+ epoch: 17 step 4, loss: 0.4483078718185425, avg loss: 0.421
+ epoch: 18 step 4, loss: 0.4541526734828949, avg loss: 0.405
+ epoch: 19 step 4, loss: 0.3124566078186035, avg loss: 0.397
+ epoch: 20 step 4, loss: 0.43211615085601807, avg loss: 0.388
+ {'acc': 1.0}
+ 第0个sample预测结果: 2 真实结果: 2
+ 第1个sample预测结果: 2 真实结果: 2
+ 第2个sample预测结果: 2 真实结果: 2
+ 第3个sample预测结果: 1 真实结果: 1
+ 第4个sample预测结果: 0 真实结果: 0
+ 第5个sample预测结果: 0 真实结果: 0
+ 第6个sample预测结果: 1 真实结果: 1
+ 第7个sample预测结果: 0 真实结果: 0
+ 第8个sample预测结果: 0 真实结果: 0
+ 第9个sample预测结果: 0 真实结果: 0
+
+#### Adam优化器模型训练、测试、预测
+
+```python
+# ----------------------------------------------------Adam-----------------------------------
+epoch_size = 15
+lr = 0.1
+print('------------------Adam优化器--------------------------')
+# 数据
+ds_train, ds_test = gen_data(X_train, Y_train, epoch_size)
+# 定义网络并训练
+network = nn.Dense(cfg.feature_number, cfg.num_class)
+net_opt = nn.Adam(network.trainable_params(), learning_rate=lr)
+model = train(network, net_opt, ds_train, "checkpoint_adam", cfg.out_dir_adam, 4)
+# 评估预测
+eval_predict(model, ds_test)
+```
+
+```
+============== Starting Training ==============
+epoch: 1 step 4, loss: 0.779292106628418, avg loss: 0.987
+epoch: 2 step 4, loss: 0.6459528207778931, avg loss: 0.649
+epoch: 3 step 4, loss: 0.4705578088760376, avg loss: 0.528
+epoch: 4 step 4, loss: 0.44921058416366577, avg loss: 0.463
+epoch: 5 step 4, loss: 0.39382368326187134, avg loss: 0.412
+epoch: 6 step 4, loss: 0.35060781240463257, avg loss: 0.369
+epoch: 7 step 4, loss: 0.26220306754112244, avg loss: 0.346
+epoch: 8 step 4, loss: 0.270007461309433, avg loss: 0.324
+epoch: 9 step 4, loss: 0.2567645311355591, avg loss: 0.301
+epoch: 10 step 4, loss: 0.38261109590530396, avg loss: 0.314
+epoch: 11 step 4, loss: 0.3241625130176544, avg loss: 0.282
+epoch: 12 step 4, loss: 0.2498287558555603, avg loss: 0.253
+epoch: 13 step 4, loss: 0.23713502287864685, avg loss: 0.259
+epoch: 14 step 4, loss: 0.2676781117916107, avg loss: 0.253
+epoch: 15 step 4, loss: 0.1873977780342102, avg loss: 0.234
+{'acc': 1.0}
+第0个sample预测结果: 2 真实结果: 2
+第1个sample预测结果: 2 真实结果: 2
+第2个sample预测结果: 2 真实结果: 2
+第3个sample预测结果: 0 真实结果: 0
+第4个sample预测结果: 0 真实结果: 0
+第5个sample预测结果: 1 真实结果: 1
+第6个sample预测结果: 2 真实结果: 2
+第7个sample预测结果: 2 真实结果: 2
+第8个sample预测结果: 0 真实结果: 0
+第9个sample预测结果: 0 真实结果: 0
+```
+
+>**结果分析:**
+>
+>从无优化器、SGD、momentum、adam优化器的loss上看:
+>1. 无优化器训练loss基本没有发生变化,测试结果效果差。多运行几次发现结果偏差太大,学员可以自己尝试。
+>2. SGD优化器loss下降速度很慢,而且在接近收敛处loss下降非常缓慢。增大学习率,减少迭代次数,会出现收敛到局部最优解的情况,学员可以自己尝试。
+>3. Momentum优化器loss下降速度较快,充分说明Momentum优化器改进了SGD收敛速度慢的问题。改变参数,比较不同学习率和迭代次数的结果,会发现该优化器稳定性很强,学习率容易选择。相比于SGD优化器容易调参。
+>4. adam优化器loss下降速度最快快,只需要15 epoch就可以达到收敛。改变模型学习率多跑几次,会发现,adam优化器可以适应不用的学习率,容易调节参数。
+
+### 适配训练作业
+
+创建训练作业时,运行参数会通过脚本传参的方式输入给脚本代码,脚本必须解析传参才能在代码中使用相应参数。如data_url和train_url,分别对应数据存储路径(OBS路径)和训练输出路径(OBS路径)。脚本对传参进行解析后赋值到args变量里,在后续代码里可以使用。
+
+```python
+import argparse
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_url', required=True, default=None, help='Location of data.')
+parser.add_argument('--train_url', required=True, default=None, help='Location of training outputs.')
+args, unknown = parser.parse_known_args()
+```
+
+MindSpore暂时没有提供直接访问OBS数据的接口,需要通过MoXing提供的API与OBS交互。将OBS中存储的数据拷贝至执行容器:
+
+```python
+import moxing as mox
+mox.file.copy_parallel(src_url=os.path.join(args.data_url, 'iris.data'), dst_url='iris.data')
+```
+
+如需将训练输出(如模型Checkpoint)从执行容器拷贝至OBS,请参考:
+
+```python
+import moxing as mox
+mox.file.copy_parallel(src_url='model_iris', dst_url=args.train_url)
+```
+
+### 创建训练作业
+
+可以参考[使用常用框架训练模型](https://support.huaweicloud.com/engineers-modelarts/modelarts_23_0238.html)来创建并启动训练作业。
+
+>**创建训练作业的参考配置:**
+>
+>- 算法来源:常用框架->Ascend-Powered-Engine->MindSpore;
+>- 代码目录:选择上述新建的OBS桶中的optimizer目录;
+>- 启动文件:选择上述新建的OBS桶中的optimizer目录下的`main1.py/main2.py`;
+>- 数据来源:数据存储位置->选择上述新建的OBS桶中的optimizer目录下的iris目录;
+>- 训练输出位置:选择上述新建的OBS桶中的optimizer目录并在其中创建model_iris目录;
+>- 作业日志路径:同训练输出位置;
+>- 规格:Ascend:1*Ascend 910;
+>- 其他均为默认;
+
+>**启动并查看训练过程:**
+>
+>1. 点击提交以开始训练;
+>2. 在训练作业列表里可以看到刚创建的训练作业,在训练作业页面可以看到版本管理;
+>3. 点击运行中的训练作业,在展开的窗口中可以查看作业配置信息,以及训练过程中的日志,日志会不断刷新,等训练作业完成后也可以下载日志到本地进行查看;
+>4. 参考上述代码梳理,在日志中找到对应的打印信息,检查实验是否成功;
+
+## 实验小结
+
+本实验目的是使用MindSpore对比不同优化器算法,通过比较不同优化器实验结果,得到如下结论:
+
+> - 无优化器条件训练,不更新参数,训练loss基本不变。模型与初始化参数关系大,随机性较强,效果差,不适合应用;
+> - 有优化器条件下训练,更新模型参数。训练loss改变;
+> - SGD优化器收敛速度慢,参数不容易调节;
+> - Momentum优化器是SGD加入历史梯度动量,增加了稳定性,收敛速度有明显提高,参数较SGD容易调节;
+> - Adam优化器是 RMSprop + Momentum。可以适应不同学习率,可以自动为不同参数调节学习率。稳定性高,参数容易调节;
\ No newline at end of file
diff --git a/optimizer/images/ada.png b/optimizer/images/ada.png
new file mode 100644
index 0000000000000000000000000000000000000000..b4ecb696b8a9043bef449373d678a5575894d582
Binary files /dev/null and b/optimizer/images/ada.png differ
diff --git a/optimizer/images/exp.png b/optimizer/images/exp.png
new file mode 100644
index 0000000000000000000000000000000000000000..eaaf708c3cafac409bd20696ddcf24f201540e02
Binary files /dev/null and b/optimizer/images/exp.png differ
diff --git a/optimizer/images/gold.png b/optimizer/images/gold.png
new file mode 100644
index 0000000000000000000000000000000000000000..21be226a4b43be529233fb3886c2f445825eb873
Binary files /dev/null and b/optimizer/images/gold.png differ
diff --git a/optimizer/images/iris.png b/optimizer/images/iris.png
new file mode 100644
index 0000000000000000000000000000000000000000..1504d960a348565b03fb814682ebde3ad37b5f5f
Binary files /dev/null and b/optimizer/images/iris.png differ
diff --git a/optimizer/images/mom.png b/optimizer/images/mom.png
new file mode 100644
index 0000000000000000000000000000000000000000..e29dde27de0fefd8993077875d1284e45ae354a1
Binary files /dev/null and b/optimizer/images/mom.png differ
diff --git a/optimizer/images/sgd.png b/optimizer/images/sgd.png
new file mode 100644
index 0000000000000000000000000000000000000000..313b68098552dbb309ce73f957c59135f0c4ce0a
Binary files /dev/null and b/optimizer/images/sgd.png differ
diff --git a/optimizer/main1.py b/optimizer/main1.py
new file mode 100644
index 0000000000000000000000000000000000000000..9047a1f1fa5e4426282138d8ebbc06752eb93ba9
--- /dev/null
+++ b/optimizer/main1.py
@@ -0,0 +1,122 @@
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.colors as plt_cl
+
+# ------------------定义目标函数beale、目标函数的偏导函数dbeale_dx,并画出目标函数---------------------
+# 定义函数beale
+def beale(x1, x2):
+ return (1.5 - x1 + x1 * x2) ** 2 + (2.25 - x1 + x1 * x2 ** 2) ** 2 + (2.625 - x1 + x1 * x2 ** 3) ** 2
+
+# 定义函数beale的偏导
+def dbeale_dx(x1, x2):
+ dfdx1 = 2 * (1.5 - x1 + x1 * x2) * (x2 - 1) + 2 * (2.25 - x1 + x1 * x2 ** 2) * (x2 ** 2 - 1) + 2 * (
+ 2.625 - x1 + x1 * x2 ** 3) * (x2 ** 3 - 1)
+ dfdx2 = 2 * (1.5 - x1 + x1 * x2) * x1 + 2 * (2.25 - x1 + x1 * x2 ** 2) * (2 * x1 * x2) + 2 * (
+ 2.625 - x1 + x1 * x2 ** 3) * (3 * x1 * x2 ** 2)
+ return dfdx1, dfdx2
+step_x1, step_x2 = 0.2, 0.2
+X1, X2 = np.meshgrid(np.arange(-5, 5 + step_x1, step_x1),
+ np.arange(-5, 5 + step_x2, step_x2))
+Y = beale(X1, X2)
+print("目标结果 (x_1, x_2) = (3, 0.5)")
+
+# 定义画图函数
+def gd_plot(x_traj):
+ plt.rcParams['figure.figsize'] = [6, 6]
+ plt.contour(X1, X2, Y, levels=np.logspace(0, 6, 30),
+ norm=plt_cl.LogNorm(), cmap=plt.cm.jet)
+ plt.title('2D Contour Plot of Beale function(Momentum)')
+ plt.xlabel('$x_1$')
+ plt.ylabel('$x_2$')
+ plt.axis('equal')
+ plt.plot(3, 0.5, 'k*', markersize=10)
+ if x_traj is not None:
+ x_traj = np.array(x_traj)
+ plt.plot(x_traj[:, 0], x_traj[:, 1], 'k-')
+ plt.show()
+
+gd_plot(None)
+
+# ------------------------------------------------------------无优化器-------------------------------------------
+def gd_no(df_dx, x0, conf_para=None):
+ if conf_para is None:
+ conf_para = {}
+ conf_para.setdefault('n_iter', 1000) # 迭代次数
+ conf_para.setdefault('learning_rate', 0.001) # 设置学习率
+ x_traj = []
+ x_traj.append(x0)
+ v = np.zeros_like(x0)
+ for iter in range(1, conf_para['n_iter'] + 1):
+ x_traj.append(x_traj[-1])
+ return x_traj
+
+x0 = np.array([1.0, 1.5])
+conf_para_no = {'n_iter': 2000, 'learning_rate': 0.005}
+x_traj_no = gd_no(dbeale_dx, x0, conf_para_no)
+print("无优化器求得极值点 (x_1, x_2) = (%s, %s)" % (x_traj_no[-1][0], x_traj_no[-1][1]))
+gd_plot(x_traj_no)
+
+# ------------------------------------------------------------SGD-------------------------------------------
+def gd_sgd(df_dx, x0, conf_para=None):
+ if conf_para is None:
+ conf_para = {}
+ conf_para.setdefault('n_iter', 1000) # 迭代次数
+ conf_para.setdefault('learning_rate', 0.001) # 设置学习率
+ x_traj = []
+ x_traj.append(x0)
+ v = np.zeros_like(x0)
+ for iter in range(1, conf_para['n_iter'] + 1):
+ dfdx = np.array(df_dx(x_traj[-1][0], x_traj[-1][1]))
+ v = - conf_para['learning_rate'] * dfdx
+ x_traj.append(x_traj[-1] + v)
+ return x_traj
+
+x0 = np.array([1.0, 1.5])
+conf_para_sgd = {'n_iter': 2000, 'learning_rate': 0.005}
+x_traj_sgd = gd_sgd(dbeale_dx, x0, conf_para_sgd)
+print("SGD求得极值点 (x_1, x_2) = (%s, %s)" % (x_traj_sgd[-1][0], x_traj_sgd[-1][1]))
+gd_plot(x_traj_sgd)
+
+# -------------------------------------------------------Momentum---------------------------------
+def gd_momentum(df_dx, x0, conf_para=None):
+ if conf_para is None:
+ conf_para = {}
+ conf_para.setdefault('n_iter', 1000) # 迭代次数
+ conf_para.setdefault('learning_rate', 0.001) # 设置学习率
+ conf_para.setdefault('momentum', 0.9) # 设置动量参数
+ x_traj = []
+ x_traj.append(x0)
+ v = np.zeros_like(x0)
+ for iter in range(1, conf_para['n_iter'] + 1):
+ dfdx = np.array(df_dx(x_traj[-1][0], x_traj[-1][1]))
+ v = conf_para['momentum'] * v - conf_para['learning_rate'] * dfdx
+ x_traj.append(x_traj[-1] + v)
+ return x_traj
+
+x0 = np.array([1.0, 1.5])
+conf_para_momentum = {'n_iter': 500, 'learning_rate': 0.005}
+x_traj_momentum = gd_momentum(dbeale_dx, x0, conf_para_momentum)
+print("Momentum求得极值点 (x_1, x_2) = (%s, %s)" % (x_traj_momentum[-1][0], x_traj_momentum[-1][1]))
+gd_plot(x_traj_momentum)
+
+# ----------------------------------------------------adagrad-----------------------------
+def gd_adagrad(df_dx, x0, conf_para=None):
+ if conf_para is None:
+ conf_para = {}
+ conf_para.setdefault('n_iter', 1000) # 迭代次数
+ conf_para.setdefault('learning_rate', 0.001) # 学习率
+ conf_para.setdefault('epsilon', 1e-7)
+ x_traj = []
+ x_traj.append(x0)
+ r = np.zeros_like(x0)
+ for iter in range(1, conf_para['n_iter'] + 1):
+ dfdx = np.array(df_dx(x_traj[-1][0], x_traj[-1][1]))
+ r += dfdx ** 2
+ x_traj.append(x_traj[-1] - conf_para['learning_rate'] / (np.sqrt(r) + conf_para['epsilon']) * dfdx)
+ return x_traj
+
+x0 = np.array([1.0, 1.5])
+conf_para_adag = {'n_iter': 500, 'learning_rate': 2}
+x_traj_adag = gd_adagrad(dbeale_dx, x0, conf_para_adag)
+print("Adagrad求得极值点 (x_1, x_2) = (%s, %s)" % (x_traj_adag[-1][0], x_traj_adag[-1][1]))
+gd_plot(x_traj_adag)
diff --git a/optimizer/main2.py b/optimizer/main2.py
new file mode 100644
index 0000000000000000000000000000000000000000..4420586c34643e7fe657cae92dace6b5e8ed8b82
--- /dev/null
+++ b/optimizer/main2.py
@@ -0,0 +1,189 @@
+import csv
+import os
+import time
+
+import numpy as np
+from easydict import EasyDict as edict
+from matplotlib import pyplot as plt
+
+import mindspore
+from mindspore import nn
+from mindspore import context
+from mindspore import dataset
+from mindspore.train.callback import TimeMonitor, LossMonitor
+from mindspore import Tensor
+from mindspore.train import Model
+from mindspore.train.callback import ModelCheckpoint, CheckpointConfig
+
+context.set_context(mode=context.GRAPH_MODE, device_target="Ascend")
+
+# 解析执行本脚本时的传参
+import argparse
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_url', required=True, default=None, help='Location of data.')
+parser.add_argument('--train_url', required=True, default=None, help='Location of training outputs.')
+args, unknown = parser.parse_known_args()
+
+import moxing as mox
+mox.file.copy_parallel(src_url=os.path.join(args.data_url, 'iris.data'), dst_url='iris.data') # 将OBS桶中数据拷贝到容器中
+
+cfg = edict({
+ 'data_size': 150,
+ 'train_size': 120, # 训练集大小
+ 'test_size': 30, # 测试集大小
+ 'feature_number': 4, # 输入特征数
+ 'num_class': 3, # 分类类别
+ 'batch_size': 30,
+ 'data_dir': 'iris.data', # 执行容器中数据集所在路径
+ 'save_checkpoint_steps': 5, # 多少步保存一次模型
+ 'keep_checkpoint_max': 1, # 最多保存多少个模型
+ 'out_dir_no_opt': './model_iris/no_opt', # 保存模型路径,无优化器模型
+ 'out_dir_sgd': './model_iris/sgd', # 保存模型路径,SGD优化器模型
+ 'out_dir_momentum': './model_iris/momentum', # 保存模型路径,momentum模型
+ 'out_dir_adam': './model_iris/adam', # 保存模型路径,adam优化器模型
+ 'output_prefix': "checkpoint_fashion_forward" # 保存模型文件名
+})
+
+
+# 读取数据并预处理:
+with open(cfg.data_dir) as csv_file:
+ data = list(csv.reader(csv_file, delimiter=','))
+
+# 共150条数据,将数据集的4个属性作为自变量X。将数据集的3个类别映射为{0, 1,2},作为因变量Y。
+label_map = {'Iris-setosa': 0, 'Iris-versicolor': 1, 'Iris-virginica': 2}
+X = np.array([[float(x) for x in s[:-1]] for s in data[:cfg.data_size]], np.float32)
+Y = np.array([label_map[s[-1]] for s in data[:150]], np.int32)
+
+# 将数据集分为训练集120条,测试集30条。
+train_idx = np.random.choice(cfg.data_size, cfg.train_size, replace=False)
+test_idx = np.array(list(set(range(cfg.data_size)) - set(train_idx)))
+X_train, Y_train = X[train_idx], Y[train_idx]
+X_test, Y_test = X[test_idx], Y[test_idx]
+print('训练数据x尺寸:', X_train.shape)
+print('训练数据y尺寸:', Y_train.shape)
+print('测试数据x尺寸:', X_test.shape)
+print('测试数据y尺寸:', Y_test.shape)
+
+# 使用MindSpore GeneratorDataset接口将numpy.ndarray类型的数据转换为Dataset。
+def gen_data(X_train, Y_train, epoch_size):
+ XY_train = list(zip(X_train, Y_train))
+ ds_train = dataset.GeneratorDataset(XY_train, ['x', 'y'])
+ ds_train.set_dataset_size(cfg.train_size)
+ ds_train = ds_train.shuffle(buffer_size=cfg.train_size).batch(cfg.batch_size, drop_remainder=True)
+ XY_test = list(zip(X_test, Y_test))
+ ds_test = dataset.GeneratorDataset(XY_test, ['x', 'y'])
+ ds_test.set_dataset_size(cfg.test_size)
+ ds_test = ds_test.shuffle(buffer_size=cfg.test_size).batch(cfg.test_size, drop_remainder=True)
+ return ds_train, ds_test
+
+
+# 继承并重写LossMonitor
+class SubLossMonitor(LossMonitor):
+ def epoch_end(self, run_context):
+ pass
+
+ def step_end(self, run_context):
+ cb_params = run_context.original_args()
+ step_loss = cb_params.net_outputs
+
+ if isinstance(step_loss, (tuple, list)) and isinstance(step_loss[0], Tensor):
+ step_loss = step_loss[0]
+ if isinstance(step_loss, Tensor):
+ step_loss = np.mean(step_loss.asnumpy())
+
+ self.losses.append(step_loss)
+ cur_step_in_epoch = int((cb_params.cur_step_num - 1) % cb_params.batch_num) + 1
+
+ if isinstance(step_loss, float) and (np.isnan(step_loss) or np.isinf(step_loss)):
+ raise ValueError("Epoch: [{:3d}/{:3d}], step: [{:5d}/{:5d}]. "
+ "Invalid loss, terminating training.".format(
+ cb_params.cur_epoch_num - 1, cb_params.epoch_num,
+ cur_step_in_epoch, cb_params.batch_num))
+
+ if self._per_print_times != 0 and cb_params.cur_step_num % self._per_print_times == 0:
+ print("epoch: {} step {}, loss: {}, avg loss: {:5.3f}".format(cb_params.cur_epoch_num,
+ cur_step_in_epoch,
+ step_loss, np.mean(self.losses)), flush=True)
+
+
+# 训练
+def train(network, net_opt, ds_train, prefix, directory, print_times):
+ net_loss = nn.SoftmaxCrossEntropyWithLogits(is_grad=False, sparse=True, reduction="mean")
+ model = Model(network, loss_fn=net_loss, optimizer=net_opt, metrics={"acc"})
+ loss_cb = SubLossMonitor(per_print_times=print_times)
+ config_ck = CheckpointConfig(save_checkpoint_steps=cfg.save_checkpoint_steps,
+ keep_checkpoint_max=cfg.keep_checkpoint_max)
+ ckpoint_cb = ModelCheckpoint(prefix=prefix, directory=directory, config=config_ck)
+ print("============== Starting Training ==============")
+ model.train(epoch_size, ds_train, callbacks=[ckpoint_cb, loss_cb], dataset_sink_mode=False)
+ return model
+
+
+# 评估预测
+def eval_predict(model, ds_test):
+ # 使用测试集评估模型,打印总体准确率
+ metric = model.eval(ds_test)
+ print(metric)
+ # 预测
+ test_ = ds_test.create_dict_iterator().get_next()
+ test = Tensor(test_['x'], mindspore.float32)
+ predictions = model.predict(test)
+ predictions = predictions.asnumpy()
+ for i in range(10):
+ p_np = predictions[i, :]
+ p_list = p_np.tolist()
+ print('第' + str(i) + '个sample预测结果:', p_list.index(max(p_list)), ' 真实结果:', test_['y'][i])
+
+
+# --------------------------------------------------无优化器-----------------------------------
+epoch_size = 20
+print('------------------无优化器--------------------------')
+# 数据
+ds_train, ds_test = gen_data(X_train, Y_train, epoch_size)
+# 定义网络并训练
+network = nn.Dense(cfg.feature_number, cfg.num_class)
+model = train(network, None, ds_train, "checkpoint_no_opt", cfg.out_dir_no_opt, 4)
+# 评估预测
+eval_predict(model, ds_test)
+
+# ---------------------------------------------------SGD-------------------------------------
+epoch_size = 200
+lr = 0.01
+print('-------------------SGD优化器-----------------------')
+# 数据
+ds_train, ds_test = gen_data(X_train, Y_train, epoch_size)
+# 定义网络并训练、测试、预测
+network = nn.Dense(cfg.feature_number, cfg.num_class)
+net_opt = nn.SGD(network.trainable_params(), lr)
+model = train(network, net_opt, ds_train, "checkpoint_sgd", cfg.out_dir_sgd, 40)
+# 评估预测
+eval_predict(model, ds_test)
+
+# ----------------------------------------------------Momentum-------------------------------
+epoch_size = 20
+lr = 0.01
+print('-------------------Momentum优化器-----------------------')
+# 数据
+ds_train, ds_test = gen_data(X_train, Y_train, epoch_size)
+# 定义网络并训练
+network = nn.Dense(cfg.feature_number, cfg.num_class)
+net_opt = nn.Momentum(network.trainable_params(), lr, 0.9)
+model = train(network, net_opt, ds_train, "checkpoint_momentum", cfg.out_dir_momentum, 4)
+# 评估预测
+eval_predict(model, ds_test)
+
+# ----------------------------------------------------Adam-----------------------------------
+epoch_size = 15
+lr = 0.1
+print('------------------Adam优化器--------------------------')
+# 数据
+ds_train, ds_test = gen_data(X_train, Y_train, epoch_size)
+# 定义网络并训练
+network = nn.Dense(cfg.feature_number, cfg.num_class)
+net_opt = nn.Adam(network.trainable_params(), learning_rate=lr)
+model = train(network, net_opt, ds_train, "checkpoint_adam", cfg.out_dir_adam, 4)
+# 评估预测
+eval_predict(model, ds_test)
+
+# -------------------------------------------------------------------------------------------
+mox.file.copy_parallel(src_url='model_iris', dst_url=args.train_url) # 将容器输出拷贝到OBS桶中