不同优化器在分类任务中的表现(二)
前言
上一篇文章中我们主要通过编写各优化器函数,找到其在目标函数上的极小值,得到不同优化器的作用。本篇文章我们将接着上一篇的学习,继续详细介绍不同优化器在鸢尾花数据集上的分类表现。
鸢尾花数据在不同优化器下的分类表现
这一部分主要通过构建全连接网络,体会有无优化器的全连接网络的差别,从而深入理解优化器在神经网络模型构建中的作用,主要设计流程如下:
创建实验环境:在ModelArts平台创建MindSpore环境。
导入实验所需模块:该步骤通常都是程序编辑的第一步,将实验代码所需要用到的模块包用import命令进行导入。
导入数据集并预处理:神经网络的训练离不开数据,这里对数据进行导入。同时,因为全连接网络只能接收固定维度的输入数据,所以,要对数据集进行预处理,以符合网络的输入维度要求。同时,设定好每一次训练的Batch的大小,以Batch Size为单位进行输入。
构建神经网络:利用mindspore.nn的cell模块搭建全连接网络,包含输入层,隐藏层,输出层。
无优化器模型预测:主要是初始化网络后,不经过训练,直接进行预测任务。
有优化器模型训练并预测:与通常训练完网络并进行预测的步骤相同。重点是结合上一步,体会优化器对于神经网络的作用。
创建实验环境
本文推荐在华为云ModelArts实验平台完成实验,也可在本地搭建python3.7.5和MindSpore1.1.1环境完成实验。
开发平台介绍
-
ModelArts是面向开发者的一站式AI开发平台,为机器学习与深度学习提供海量数据预处理及半自动化标注、大规模分布式Training、自动化模型生成,及端-边-云模型按需部署能力,帮助用户快速创建和部署模型,管理全周期AI工作流。
ModelArts官网:https://www.huaweicloud.com/product/modelarts.html
-
MindSpore 最佳匹配昇腾芯片的开源AI计算框架,支持Asend、GPU、CPU平台。MindSpore官网:https://www.mindspore.cn
进入ModelArts
点击官网地址,进入ModelArts主页。点击“立即使用”按钮,输入用户名和密码登录,进入ModelArts使用页面。
创建ModelArts notebook
我们在ModelArts中创建一个notebook开发环境,ModelArts notebook提供网页版的Python开发环境,可以方便的编写、运行代码,并查看运行结果。
创建mindspore1.2-CPU环境的notebook,如下图所示。
创建Mindspore环境的Kernel
打开Notebook控制台后,新建或打开MindSpore环境的ipynb文件,即可开始编辑实验代码。
导入模块、读取鸢尾花数据集并预处理、构建神经网络
本文主要进行鸢尾花数据集标签的识别,鸢尾花数据集共收集了三类鸢尾花,即Setosa鸢尾花、Versicolour鸢尾花和Virginica鸢尾花,每一类鸢尾花收集了50条样本记录,共计150条。
数据集包括4个属性,分别为花萼的长、花萼的宽、花瓣的长和花瓣的宽。对花瓣我们可能比较熟悉,花萼是什么呢?花萼是花冠外面的绿色被叶,在花尚未开放时,保护着花蕾。四个属性的单位都是cm,属于数值变量,1个标签,表示鸢尾花的分类。
用到的框架主要包括:MindSpore1.2.0,专用于搭建整体的网络框架,这里主要用于神经网络的搭建。另外 os也被引入,它提供了丰富的函数,主要用来处理文件和目录。
导入模块和鸢尾花数据集
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="CPU")#导入数据,载入
#变量定义
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" #保存模型文件名
})
#鸢尾花数据集,本数据集共有150个带标签的数据
with open(cfg.data_dir) as csv_file:
data = list(csv.reader(csv_file, delimiter=','))
label_map = {'setosa': 0,'versicolor': 1,'virginica':2 }
#分别获取数据中的特征值X和标签值Y
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)
# 将数据集分为训练集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]
数据预处理
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'])
#设定数据集大小
#打乱操作并设定batchsize
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'])
#设定数据集大小
#打乱操作并设定batchsize
ds_test = ds_test.shuffle(buffer_size=cfg.test_size).batch(cfg.test_size, drop_remainder=True)
return ds_train, ds_test
定义训练、评估、测试函数
# 训练函数
def train(network, net_opt, ds_train, prefix, directory, print_times):
#定义网络损失函数
net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean")
#定义模型
model = Model(network, loss_fn=net_loss, optimizer=net_opt, metrics={"acc"})
#定义损失值指标
loss_cb = LossMonitor(per_print_times=int(cfg.train_size / cfg.batch_size))
#设置checkpoint
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
class_names=['setosa', 'versicolor', 'virginica']
# 评估预测函数
def eval_predict(model, ds_test):
# 使用测试集评估模型,打印总体准确率
metric = model.eval(ds_test)
print(metric)
# 预测
test_ = ds_test.create_dict_iterator().__next__()
test = Tensor(test_['x'], mindspore.float32)
predictions = model.predict(test)
predictions = predictions.asnumpy()
true_label = test_['y'].asnumpy()
for i in range(10):
p_np = predictions[i, :]
pre_label = np.argmax(p_np)
print('第' + str(i) + '个sample预测结果:', class_names[pre_label], ' 真实结果:', class_names[true_label[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)
输出结果:
------------------无优化器--------------------------
============== Starting Training ==============
epoch: 1 step: 4, loss is 1.1123106
epoch: 2 step: 4, loss is 1.1202087
epoch: 3 step: 4, loss is 1.1081936
epoch: 4 step: 4, loss is 1.1139123
epoch: 5 step: 4, loss is 1.1177686
epoch: 6 step: 4, loss is 1.1094363
epoch: 7 step: 4, loss is 1.1057143
epoch: 8 step: 4, loss is 1.1137706
epoch: 9 step: 4, loss is 1.1225764
epoch: 10 step: 4, loss is 1.1169411
epoch: 11 step: 4, loss is 1.115051
epoch: 12 step: 4, loss is 1.1098907
epoch: 13 step: 4, loss is 1.1069646
epoch: 14 step: 4, loss is 1.1149268
epoch: 15 step: 4, loss is 1.1180775
epoch: 16 step: 4, loss is 1.1170397
epoch: 17 step: 4, loss is 1.1150074
epoch: 18 step: 4, loss is 1.1237894
epoch: 19 step: 4, loss is 1.1233115
epoch: 20 step: 4, loss is 1.116143
{'acc': 0.43333333333333335}
第0个sample预测结果: versicolor 真实结果: virginica
第1个sample预测结果: versicolor 真实结果: versicolor
第2个sample预测结果: versicolor 真实结果: virginica
第3个sample预测结果: versicolor 真实结果: setosa
第4个sample预测结果: versicolor 真实结果: versicolor
第5个sample预测结果: versicolor 真实结果: setosa
第6个sample预测结果: setosa 真实结果: virginica
第7个sample预测结果: versicolor 真实结果: versicolor
第8个sample预测结果: versicolor 真实结果: setosa
第9个sample预测结果: versicolor 真实结果: virginica
SGD优化器模型训练并预测
epoch_size = 300
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)
输出结果:
-------------------SGD优化器-----------------------
============== Starting Training ==============
epoch: 1 step: 4, loss is 1.0863036
epoch: 2 step: 4, loss is 1.0471957
epoch: 3 step: 4, loss is 1.0281278
epoch: 4 step: 4, loss is 1.0003911
epoch: 5 step: 4, loss is 1.0010878
epoch: 6 step: 4, loss is 0.9402846
epoch: 7 step: 4, loss is 0.936496
epoch: 8 step: 4, loss is 0.9070135
epoch: 9 step: 4, loss is 0.8746185
epoch: 10 step: 4, loss is 0.8588983
epoch: 11 step: 4, loss is 0.8791269
epoch: 12 step: 4, loss is 0.8409094
epoch: 13 step: 4, loss is 0.8171078
epoch: 14 step: 4, loss is 0.78627276
...
{'acc': 1.0}
第0个sample预测结果: versicolor 真实结果: versicolor
第1个sample预测结果: virginica 真实结果: virginica
第2个sample预测结果: virginica 真实结果: virginica
第3个sample预测结果: setosa 真实结果: setosa
第4个sample预测结果: virginica 真实结果: virginica
第5个sample预测结果: versicolor 真实结果: versicolor
第6个sample预测结果: versicolor 真实结果: versicolor
第7个sample预测结果: setosa 真实结果: setosa
第8个sample预测结果: virginica 真实结果: virginica
第9个sample预测结果: setosa 真实结果: setosa
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)
输出结果:
-------------------Momentum优化器-----------------------
============== Starting Training ==============
epoch: 1 step: 4, loss is 1.0810095
epoch: 2 step: 4, loss is 0.94718075
epoch: 3 step: 4, loss is 0.8274425
epoch: 4 step: 4, loss is 0.66691095
epoch: 5 step: 4, loss is 0.6318491
epoch: 6 step: 4, loss is 0.57523024
epoch: 7 step: 4, loss is 0.56330514
epoch: 8 step: 4, loss is 0.481749
epoch: 9 step: 4, loss is 0.39138663
epoch: 10 step: 4, loss is 0.4436511
epoch: 11 step: 4, loss is 0.4150259
epoch: 12 step: 4, loss is 0.4283092
epoch: 13 step: 4, loss is 0.41189855
epoch: 14 step: 4, loss is 0.38341784
epoch: 15 step: 4, loss is 0.38927388
epoch: 16 step: 4, loss is 0.39323956
epoch: 17 step: 4, loss is 0.38287503
epoch: 18 step: 4, loss is 0.43862677
epoch: 19 step: 4, loss is 0.3592914
epoch: 20 step: 4, loss is 0.35841298
{'acc': 0.9666666666666667}
第0个sample预测结果: versicolor 真实结果: versicolor
第1个sample预测结果: versicolor 真实结果: versicolor
第2个sample预测结果: virginica 真实结果: virginica
第3个sample预测结果: versicolor 真实结果: versicolor
第4个sample预测结果: versicolor 真实结果: versicolor
第5个sample预测结果: virginica 真实结果: versicolor
第6个sample预测结果: setosa 真实结果: setosa
第7个sample预测结果: versicolor 真实结果: versicolor
第8个sample预测结果: virginica 真实结果: virginica
第9个sample预测结果: virginica 真实结果: virginica
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)
-----------------Adam优化器--------------------------
============== Starting Training ==============
epoch: 1 step: 4, loss is 0.85976017
epoch: 2 step: 4, loss is 0.6710789
epoch: 3 step: 4, loss is 0.5583926
epoch: 4 step: 4, loss is 0.5004689
epoch: 5 step: 4, loss is 0.37697986
epoch: 6 step: 4, loss is 0.39567876
epoch: 7 step: 4, loss is 0.3641772
epoch: 8 step: 4, loss is 0.31769836
epoch: 9 step: 4, loss is 0.33615974
epoch: 10 step: 4, loss is 0.36870608
epoch: 11 step: 4, loss is 0.31535652
epoch: 12 step: 4, loss is 0.29351452
epoch: 13 step: 4, loss is 0.27576455
epoch: 14 step: 4, loss is 0.24675885
epoch: 15 step: 4, loss is 0.31923586
{'acc': 1.0}
{'acc': 0.9666666666666667}
第0个sample预测结果: setosa 真实结果: setosa
第1个sample预测结果: versicolor 真实结果: versicolor
第2个sample预测结果: versicolor 真实结果: versicolor
第3个sample预测结果: versicolor 真实结果: versicolor
第4个sample预测结果: setosa 真实结果: setosa
第5个sample预测结果: virginica 真实结果: virginica
第6个sample预测结果: versicolor 真实结果: versicolor
第7个sample预测结果: virginica 真实结果: virginica
第8个sample预测结果: setosa 真实结果: setosa
第9个sample预测结果: setosa 真实结果: setosa
总结
到此我们完成了优化器的编写与有无优化器网络预测结果对比两个实验。
通过完成此实验可以理解优化器的原理与作用,并具备独立编写优化器函数的能力。
- 点赞
- 收藏
- 关注作者
评论(0)