MindSpore前馈神经网络运用

实验经典介绍

本实验主要介绍使用MindSpore开发前馈神经网络,并使用Fashion-MNIST数据集训练和测试模型。

实验目的

  • 掌握如何使用MindSpore进行简单前馈神经网络的开发。
  • 了解如何使用MindSpore进行简单图片分类任务的训练。
  • 了解如何使用MindSpore进行简单图片分类任务的测试和预测。

预备知识

  • 熟练使用Python。
  • 具备一定的深度学习理论知识,如感知机、前馈神经网络、损失函数、优化器,训练策略等。
  • 了解华为云的基本使用方法,包括OBS(对象存储)、ModelArts(AI开发平台)、训练作业等功能。华为云官网:https://www.huaweicloud.com
  • 了解并熟悉MindSpore AI计算框架,MindSpore官网:https://www.mindspore.cn/

实验环境

  • MindSpore 1.0.0(MindSpore版本会定期更新,本指导也会定期刷新,与版本配套);
  • 华为云ModelArts(控制台左上角选择“华北-北京四”):ModelArts是华为云提供的面向开发者的一站式AI开发平台,集成了昇腾AI处理器资源池,用户可以在该平台下体验MindSpore。

实验准备

已经对ModelArts云环境很熟悉的玩家可以直接跳到实验步骤。

数据集准备

Fashion-MNIST是一个替代MNIST手写数字集的图像数据集。 它是由Zalando(一家德国的时尚科技公司)旗下的研究部门提供。其涵盖了来自10种类别的共7万个不同商品的正面图片。Fashion-MNIST的大小、格式和训练集/测试集划分与原始的MNIST完全一致。60000/10000的训练测试数据划分,28x28x1的灰度图片。

这里介绍一下经典的MNIST(手写字母)数据集。经典的MNIST数据集包含了大量的手写数字。十几年来,来自机器学习、机器视觉、人工智能、深度学习领域的研究员们把这个数据集作为衡量算法的基准之一。实际上,MNIST数据集已经成为算法作者的必测的数据集之一,但是MNIST数据集太简单了。很多深度学习算法在测试集上的准确率已经达到99.6%。

  • 从Fashion-MNIST GitHub仓库下载如下4个文件到本地并解压:
train-images-idx3-ubyte     training set images(47,042,560 bytes)
train-labels-idx1-ubyte     training set labels(61,440 bytes)
t10k-images-idx3-ubyte      test set images (7,843,840 bytes)
t10k-labels-idx1-ubyte      test set labels (12,288 bytes)

脚本准备

从课程gitee仓库上下载本实验相关脚本。将脚本和数据集组织为如下形式:

feedforward
├── Fashion-MNIST
│   ├── test
│   │   ├── t10k-images-idx3-ubyte
│   │   └── t10k-labels-idx1-ubyte
│   └── train
│       ├── train-images-idx3-ubyte
│       └── train-labels-idx1-ubyte
└── main.py

创建OBS桶

本实验需要使用华为云OBS存储脚本和数据集,可以参考快速通过OBS控制台上传下载文件了解使用OBS创建桶、上传文件、下载文件的使用方法(下文给出了操作步骤)。

提示: 华为云新用户使用OBS时通常需要创建和配置“访问密钥”,可以在使用OBS时根据提示完成创建和配置。也可以参考获取访问密钥并完成ModelArts全局配置获取并配置访问密钥。

打开OBS控制台,点击右上角的“创建桶”按钮进入桶配置页面,创建OBS桶的参考配置如下:

  • 区域:华北-北京四
  • 数据冗余存储策略:单AZ存储
  • 桶名称:全局唯一的字符串
  • 存储类别:标准存储
  • 桶策略:公共读
  • 归档数据直读:关闭
  • 企业项目、标签等配置:免

上传文件

点击新建的OBS桶名,再打开“对象”标签页,通过“上传对象”、“新建文件夹”等功能,将脚本和数据集上传到OBS桶中。上传文件后,查看页面底部的“任务管理”状态栏(正在运行、已完成、失败),确保文件均上传完成。若失败请:

  • 参考上传对象大小限制/切换上传方式,
  • 参考上传对象失败常见原因。
  • 若无法解决请新建工单,产品类为“对象存储服务”,问题类型为“桶和对象相关”,会有技术人员协助解决。

实验步骤

推荐使用ModelArts训练作业进行实验,适合大规模并发使用。若使用ModelArts Notebook,请参考LeNet5及Checkpoint实验案例,了解Notebook的使用方法和注意事项。

代码梳理

导入MindSpore模块和辅助模块

用到的框架主要包括:

  • mindspore,用于神经网络的搭建
  • numpy,用于处理一些数据
  • matplotlib,用于画图、图像展示
  • struct,用于处理二进制文件
import os
import struct
import sys
from easydict import EasyDict as edictimport matplotlib.pyplot as plt
import numpy as npimport mindspore
import mindspore.dataset as ds
import mindspore.nn as nn
from mindspore import context
from mindspore.nn.metrics import Accuracy
from mindspore.train import Model
from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, LossMonitor, TimeMonitor
from mindspore import Tensorcontext.set_context(mode=context.GRAPH_MODE, device_target='Ascend')

变量定义

cfg = edict({'train_size': 60000,  # 训练集大小'test_size': 10000,  # 测试集大小'channel': 1,  # 图片通道数'image_height': 28,  # 图片高度'image_width': 28,  # 图片宽度'batch_size': 60,'num_classes': 10,  # 分类类别'lr': 0.001,  # 学习率'epoch_size': 20,  # 训练次数'data_dir_train': os.path.join('Fashion-MNIST', 'train'),'data_dir_test': os.path.join('Fashion-MNIST', 'test'),'save_checkpoint_steps': 1,  # 多少步保存一次模型'keep_checkpoint_max': 3,  # 最多保存多少个模型'output_directory': './model_fashion',  # 保存模型路径'output_prefix': "checkpoint_fashion_forward"  # 保存模型文件名字
})

读取并处理数据

读取数据

def read_image(file_name):''':param file_name: 文件路径:return:  训练或者测试数据如下是训练的图片的二进制格式[offset] [type]          [value]          [description]0000     32 bit integer  0x00000803(2051) magic number0004     32 bit integer  60000            number of images0008     32 bit integer  28               number of rows0012     32 bit integer  28               number of columns0016     unsigned byte   ??               pixel0017     unsigned byte   ??               pixel........xxxx     unsigned byte   ??               pixel'''file_handle = open(file_name, "rb")  # 以二进制打开文档file_content = file_handle.read()  # 读取到缓冲区中head = struct.unpack_from('>IIII', file_content, 0)  # 取前4个整数,返回一个元组offset = struct.calcsize('>IIII')imgNum = head[1]  # 图片数width = head[2]  # 宽度height = head[3]  # 高度bits = imgNum * width * height  # data一共有60000*28*28个像素值bitsString = '>' + str(bits) + 'B'  # fmt格式:'>47040000B'imgs = struct.unpack_from(bitsString, file_content, offset)  # 取data数据,返回一个元组imgs_array = np.array(imgs).reshape((imgNum, width * height))  # 最后将读取的数据reshape成 【图片数,图片像素】二维数组return imgs_arraydef read_label(file_name):''':param file_name::return:标签的格式如下:[offset] [type]          [value]          [description]0000     32 bit integer  0x00000801(2049) magic number (MSB first)0004     32 bit integer  60000            number of items0008     unsigned byte   ??               label0009     unsigned byte   ??               label........xxxx     unsigned byte   ??               labelThe labels values are 0 to 9.'''file_handle = open(file_name, "rb")  # 以二进制打开文档file_content = file_handle.read()  # 读取到缓冲区中head = struct.unpack_from('>II', file_content, 0)  # 取前2个整数,返回一个元组offset = struct.calcsize('>II')labelNum = head[1]  # label数bitsString = '>' + str(labelNum) + 'B'  # fmt格式:'>47040000B'label = struct.unpack_from(bitsString, file_content, offset)  # 取data数据,返回一个元组return np.array(label)def get_data():# 文件获取train_image = os.path.join(cfg.data_dir_train, 'train-images-idx3-ubyte')test_image = os.path.join(cfg.data_dir_test, "t10k-images-idx3-ubyte")train_label = os.path.join(cfg.data_dir_train, "train-labels-idx1-ubyte")test_label = os.path.join(cfg.data_dir_test, "t10k-labels-idx1-ubyte")# 读取数据train_x = read_image(train_image)test_x = read_image(test_image)train_y = read_label(train_label)test_y = read_label(test_label)return train_x, train_y, test_x, test_y

数据预处理和处理结果图片展示

train_x, train_y, test_x, test_y = get_data()
train_x = train_x.reshape(-1, 1, cfg.image_height, cfg.image_width)
test_x = test_x.reshape(-1, 1, cfg.image_height, cfg.image_width)
train_x = train_x / 255.0
test_x = test_x / 255.0
train_x = train_x.astype('Float32')
test_x = test_x.astype('Float32')
train_y = train_y.astype('int32')
test_y = test_y.astype('int32')
print('训练数据集样本数:', train_x.shape[0])
print('测试数据集样本数:', test_y.shape[0])
print('通道数/图像长/宽:', train_x.shape[1:])
print('一张图像的标签样式:', train_y[0])  # 一共10类,用0-9的数字表达类别。plt.figure()
plt.imshow(train_x[0,0,...])
plt.colorbar()
plt.grid(False)
plt.show()
训练数据集数量: 60000
测试数据集数量: 10000
通道数/图像长/宽: (1, 28, 28)
一张图像的标签样式: 9

使用MindSpore GeneratorDataset接口将numpy.ndarray类型的数据转换为Dataset

# 转换数据类型为Dataset
XY_train = list(zip(train_x, train_y))
ds_train = ds.GeneratorDataset(XY_train, ['x', 'y'])
ds_train = ds_train.shuffle(buffer_size=cfg.train_size).batch(cfg.batch_size, drop_remainder=True)
XY_test = list(zip(test_x, test_y))
ds_test = ds.GeneratorDataset(XY_test, ['x', 'y'])
ds_test = ds_test.shuffle(buffer_size=cfg.test_size).batch(cfg.batch_size, drop_remainder=True)

定义前馈神经网络

前馈神经网络是一种最简单的神经网络,各神经元分层排列(其中每一层包含若干个神经元)。每个神经元只与前一层的神经元相连,接收前一层的输出,并输出给下一层,各层间没有反馈。是目前应用最广泛、发展最迅速的人工神经网络之一。第0层叫输入层,最后一层叫输出层,其他中间层叫做隐含层(或隐藏层、隐层)。隐层可以是一层,也可以是多层,是由全连接层堆叠而成。

# 定义前馈神经网络
class Forward_fashion(nn.Cell):def __init__(self, num_class=10):  # 一共分十类,图片通道数是1super(Forward_fashion, self).__init__()self.num_class = num_classself.flatten = nn.Flatten()self.fc1 = nn.Dense(cfg.channel * cfg.image_height * cfg.image_width, 128)self.relu = nn.ReLU()self.fc2 = nn.Dense(128, self.num_class)def construct(self, x):x = self.flatten(x)x = self.fc1(x)x = self.relu(x)x = self.fc2(x)return x

训练

使用Fashion-MNIST数据集对上述定义的前馈神经网络模型进行训练。训练策略如下表所示,可以调整训练策略并查看训练效果。

batch size number of epochs learning rate input shape optimizer
60 20 0.001 (1,28,28) Adam
# 构建网络
network = Forward_fashion(cfg.num_classes)
# 定义模型的损失函数,优化器
net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean")
net_opt = nn.Adam(network.trainable_params(), cfg.lr)
# 训练模型
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))
config_ck = CheckpointConfig(save_checkpoint_steps=cfg.save_checkpoint_steps,keep_checkpoint_max=cfg.keep_checkpoint_max)
ckpoint_cb = ModelCheckpoint(prefix=cfg.output_prefix, directory=cfg.output_directory, config=config_ck)
print("============== Starting Training ==============")
model.train(cfg.epoch_size, ds_train, callbacks=[ckpoint_cb, loss_cb], dataset_sink_mode=False)
============== Starting Training ==============
epoch: 1 step: 1000, loss is 0.6812696
epoch: 2 step: 1000, loss is 0.39710096
epoch: 3 step: 1000, loss is 0.43427807
epoch: 4 step: 1000, loss is 0.3170758
epoch: 5 step: 1000, loss is 0.24550956
epoch: 6 step: 1000, loss is 0.4204946
epoch: 7 step: 1000, loss is 0.35653585
epoch: 8 step: 1000, loss is 0.31376493
epoch: 9 step: 1000, loss is 0.27455378
epoch: 10 step: 1000, loss is 0.18871705
epoch: 11 step: 1000, loss is 0.20512795
epoch: 12 step: 1000, loss is 0.2589024
epoch: 13 step: 1000, loss is 0.31454447
epoch: 14 step: 1000, loss is 0.24145015
epoch: 15 step: 1000, loss is 0.32082427
epoch: 16 step: 1000, loss is 0.27023837
epoch: 17 step: 1000, loss is 0.34484679
epoch: 18 step: 1000, loss is 0.41191268
epoch: 19 step: 1000, loss is 0.07990202
epoch: 20 step: 1000, loss is 0.26586318

评估测试

# 使用测试集评估模型,打印总体准确率
metric = model.eval(ds_test, dataset_sink_mode=False)
print(metric)

预测

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat','Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']#从测试集中取出一组样本,输入模型进行预测
test_ = ds_test.create_dict_iterator()._get_next()
#利用key值选出样本
test = Tensor(test_['x'], mindspore.float32)
predictions = model.predict(test)
softmax = nn.Softmax()
predictions = softmax(predictions)predictions = predictions.asnumpy()
true_label = test_['y'].asnumpy()
true_image = test_['x'].asnumpy()for i in range(15):p_np = predictions[i, :]pre_label = np.argmax(p_np)print('第' + str(i) + '个sample预测结果:', class_names[pre_label], '   真实结果:', class_names[true_label[i]])

对预测结果可视化

# -------------------定义可视化函数--------------------------------
# 输入预测结果序列,真实标签序列,以及图片序列
# 目标是根据预测值对错,让其标签显示为红色或者蓝色。对:标签为蓝色;错:标签为红色
def plot_image(predicted_label, true_label, img):plt.grid(False)plt.xticks([])plt.yticks([])# 显示对应图片plt.imshow(img, cmap=plt.cm.binary)# 显示预测结果的颜色,如果对上了是蓝色,否则为红色if predicted_label == true_label:color = 'blue'else:color = 'red'# 显示对应标签的格式,样式plt.xlabel('{},({})'.format(class_names[predicted_label],class_names[true_label]), color=color)
# 将预测的结果以柱状图形状显示蓝对红错
def plot_value_array(predicted_label, true_label,predicted_array):plt.grid(False)plt.xticks([])plt.yticks([])this_plot = plt.bar(range(10), predicted_array, color='#777777')plt.ylim([0, 1])this_plot[predicted_label].set_color('red')this_plot[true_label].set_color('blue')
# 预测15个图像与标签,并展现出来
num_rows = 5
num_cols = 3
num_images = num_rows * num_cols
plt.figure(figsize=(2 * 2 * num_cols, 2 * num_rows))for i in range(num_images):plt.subplot(num_rows, 2 * num_cols, 2 * i + 1)pred_np_ = predictions[i, :]predicted_label = np.argmax(pred_np_)image_single = true_image[i, 0, ...]plot_image(predicted_label, true_label[i], image_single)plt.subplot(num_rows, 2 * num_cols, 2 * i + 2)plot_value_array(predicted_label, true_label[i], pred_np_)
plt.show()


适配训练作业(可跳过)

创建训练作业时,运行参数会通过脚本传参的方式输入给脚本代码,脚本必须解析传参才能在代码中使用相应参数。如data_url和train_url,分别对应数据存储路径(OBS路径)和训练输出路径(OBS路径)。脚本对传参进行解析后赋值到args变量里,在后续代码里可以使用。

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数据的接口,需要通过ModelArts自带的moxing框架与OBS交互。将OBS桶中的数据拷贝至执行容器中,供MindSpore使用:

import moxing
# src_url形如's3://OBS/PATH',为OBS桶中数据集的路径,dst_url为执行容器中的路径
moxing.file.copy_parallel(src_url=args.data_url, dst_url='Fashion-MNIST/')

如需将训练输出(如模型Checkpoint)从执行容器拷贝至OBS,请参考:

import moxing
# src_url为执行容器中的路径,dst_url形如's3://OBS/PATH',目录若不存在则会新建
moxing.file.copy_parallel(src_url='model_fashion', dst_url=args.train_url)

创建训练作业

可以参考使用常用框架训练模型来创建并启动训练作业。

打开ModelArts控制台-训练管理-训练作业,点击“创建”按钮进入训练作业配置页面,创建训练作业的参考配置:

  • 算法来源:常用框架->Ascend-Powered-Engine->MindSpore;
  • 代码目录:选择上述新建的OBS桶中的feedforward目录;
  • 启动文件:选择上述新建的OBS桶中的feedforward目录下的main.py
  • 数据来源:数据存储位置->选择上述新建的OBS桶中的feedforward目录下的Fashion-MNIST目录;
  • 训练输出位置:选择上述新建的OBS桶中的feedforward目录并在其中创建model_fashion目录;
  • 作业日志路径:同训练输出位置;
  • 规格:Ascend:1*Ascend 910;
  • 其他均为默认;

启动并查看训练过程:

  1. 点击提交以开始训练;
  2. 在训练作业列表里可以看到刚创建的训练作业,在训练作业页面可以看到版本管理;
  3. 点击运行中的训练作业,在展开的窗口中可以查看作业配置信息,以及训练过程中的日志,日志会不断刷新,等训练作业完成后也可以下载日志到本地进行查看;
  4. 参考上述代码梳理,在日志中找到对应的打印信息,检查实验是否成功;

运行成功。

实验小结

本实验展示了如何使用MindSpore进行Fashion-MNIST数据集分类。

首先训练前馈神经网络,然后使用训练后的前馈神经网络模型对Fashion-MNIST测试数据进行分类,从结果上分析准确率大于80%,即前馈神经网络学习到了Fashion-MNIST数据集分类。

MindSpore前馈神经网络运用相关推荐

  1. 【深度学习】基于MindSpore和pytorch的Softmax回归及前馈神经网络

    1 实验内容简介 1.1 实验目的 (1)熟练掌握tensor相关各种操作: (2)掌握广义线性回归模型(logistic模型.sofmax模型).前馈神经网络模型的原理: (3)熟练掌握基于mind ...

  2. MindSpore循环神经网络

    MindSpore循环神经网络 一. 神经网络的组成 神经元模型:首先简单的了解以下构成神经网络的最基础单元:神经元.每个神经元与其它神经元相连,处于激活状态时,就会向相连的神经元发送相应信号.从而改 ...

  3. 机器学习与高维信息检索 - Note 5 - (深度)前馈神经网络((Deep) Feedforward Neural Networks)及基于CVXOPT的相关实例

    Note 5 - (深度)前馈神经网络((Deep) Feedforward Neural Networks)及相关实例 5.1 FNN的定义和动机 粗略地说,前馈神经网络(FNN)是一种特殊的函数类 ...

  4. 基于Numpy构建全连接前馈神经网络进行手写数字识别

    文章目录 (一) 问题描述 (二) 设计简要描述 (三) 程序清单 (四) 结果分析 (五) 调试报告 (六) 实验小结 (一) 问题描述 不使用任何机器学习框架,仅仅通过Numpy库构建一个最简单的 ...

  5. keras构建前馈神经网络(feedforward neural network)进行分类模型构建基于早停法(Early stopping)

    keras构建前馈神经网络(feedforward neural network)进行分类模型构建基于早停法(Early stopping) 当我们训练深度学习神经网络的时候通常希望能获得最好的泛化性 ...

  6. keras构建前馈神经网络(feedforward neural network)进行多分类模型训练学习

    keras构建前馈神经网络(feedforward neural network)进行多分类模型训练学习 前馈神经网络(feedforward neural network)是一种最简单的神经网络,各 ...

  7. keras构建前馈神经网络(feedforward neural network)进行分类模型构建并加入L2正则化

    keras构建前馈神经网络(feedforward neural network)进行分类模型构建并加入L2正则化 正则化(Regularization)是机器学习中一种常用的技术,其主要目的是控制模 ...

  8. Keras构建前馈神经网络并使用callbacks输出acc以及loss曲线(训练接、验证集)及效果可视化

    Keras构建前馈神经网络并使用callbacks输出acc以及loss曲线(训练接.验证集)及效果可视化 在每个training/epoch/batch结束时,如果我们想执行某些任务,例如模型缓存. ...

  9. keras构建前馈神经网络(feedforward neural network)进行回归模型构建和学习

    keras构建前馈神经网络(feedforward neural network)进行回归模型构建和学习 我们不必在"回归"一词上费太多脑筋.英国著名统计学家弗朗西斯·高尔顿(Fr ...

  10. 【Deep Learning笔记】前馈神经网络和BP算法

    文章目录 1 前馈神经网络 1.1 网络训练一些定义 2 反向传播算法 2.1 前言 2.2 符号约定 2.3 反向传播算法的推导 2.4 总结过程 3 收敛和局部极值 4 神经网络杂谈 1 前馈神经 ...

最新文章

  1. PyTorch 《动手学深度学习》学习笔记(Dive-into-DL-Pytorch)
  2. 案例 | 日活提升 50%,海尔智慧厨房平台如何引领行业革命?
  3. l2-006 树的遍历
  4. 2015电大c语言,2015电大本科C语言程序设计A试题汇总.doc
  5. ES6之let原理+回调函数等待队列——五个完全相同的按钮,点第i个按钮弹出i
  6. openstack 手动安装版 功能测试
  7. shell之任务控制
  8. [NOIP2011] 玛雅游戏
  9. BlockingQueue接口分析
  10. react小书没读完的记录
  11. python移动文件夹下所有文件到另一个文件夹
  12. 关于:WindowsOffice 产品语言包
  13. UG编程加工之非切削移动
  14. 十二烷基硫酸钠(SDS)将Fe3O4磁性纳米粒子定量地修饰到多壁碳纳米管|化学试剂
  15. 数据库expecting ''', found 'EOF'异常——原载于我的百度空间
  16. Tracup|工作时节省时间的三个奇异但是有用的小妙招
  17. Java 实现扫雷与高胜率低耗时自动扫雷 AI (下)
  18. (附源码)springboot基于微信小程序的校园外卖系统 毕业设计091024
  19. 如何重装java tm_彻底重装JDK的方法
  20. 渗透测试 对头像上传漏洞检测与修复

热门文章

  1. QQ聊天记录的相关代码
  2. Massive MIMO简介
  3. 蒟蒻的NOIP2017游记
  4. excel 将日期转换为8位数字
  5. 《活着》余华——有庆的死亡
  6. android 指纹是否设置,检查Android是否支持指纹识别以及是否已经录入指纹
  7. 骇客基础知识:第3部分
  8. 密码学大事件! SHA-1 哈希碰撞实例
  9. 服务器被恶意攻击可以报警吗?
  10. MIPI DSI 接口协议介绍