Are you sure you want to delete this task? Once this task is deleted, it cannot be recovered.
chenzomi 24c9001cf8 | 1 year ago | |
---|---|---|
.. | ||
images | 1 year ago | |
README.md | 1 year ago | |
letnet5_en.md | 1 year ago | |
main.py | 1 year ago |
LeNet5 + MNIST被誉为深度学习领域的“Hello world”。本实验主要介绍使用MindSpore在MNIST手写数字数据集上开发和训练一个LeNet5模型,并验证模型精度。
MNIST是一个手写数字数据集,训练集包含60000张手写数字,测试集包含10000张手写数字,共10类。MNIST数据集的官网:THE MNIST DATABASE。
train-images-idx3-ubyte.gz: training set images (9912422 bytes)
train-labels-idx1-ubyte.gz: training set labels (28881 bytes)
t10k-images-idx3-ubyte.gz: test set images (1648877 bytes)
t10k-labels-idx1-ubyte.gz: test set labels (4542 bytes)
从课程gitee仓库上下载本实验相关脚本。将脚本和数据集组织为如下形式:
lenet5
├── MNIST
│ ├── test
│ │ ├── t10k-images-idx3-ubyte
│ │ └── t10k-labels-idx1-ubyte
│ └── train
│ ├── train-images-idx3-ubyte
│ └── train-labels-idx1-ubyte
└── main.py
使用ModelArts训练作业/Notebook时,需要使用华为云OBS存储实验脚本和数据集,可以参考快速通过OBS控制台上传下载文件了解使用OBS创建桶、上传文件、下载文件的使用方法(下文给出了操作步骤)。
提示: 华为云新用户使用OBS时通常需要创建和配置“访问密钥”,可以在使用OBS时根据提示完成创建和配置。也可以参考获取访问密钥并完成ModelArts全局配置获取并配置访问密钥。
打开OBS控制台,点击右上角的“创建桶”按钮进入桶配置页面,创建OBS桶的参考配置如下:
点击新建的OBS桶名,再打开“对象”标签页,通过“上传对象”、“新建文件夹”等功能,将脚本和数据集上传到OBS桶中。上传文件后,查看页面底部的“任务管理”状态栏(正在运行、已完成、失败),确保文件均上传完成。若失败请:
ModelArts提供了训练作业服务,训练作业资源池大,且具有作业排队等功能,适合大规模并发使用。使用训练作业时,如果有修改代码和调试的需求,有如下三个方案:
在本地修改代码后重新上传;
使用PyCharm ToolKit配置一个本地Pycharm+ModelArts的开发环境,便于上传代码、提交训练作业和获取训练日志。
在ModelArts上创建Notebook,然后设置Sync OBS功能,可以在线修改代码并自动同步到OBS中。因为只用Notebook来编辑代码,所以创建CPU类型最低规格的Notebook就行。
创建训练作业时,运行参数会通过脚本传参的方式输入给脚本代码,脚本必须解析传参才能在代码中使用相应参数。如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桶内的数据集至执行容器。
import moxing
# src_url形如's3://OBS/PATH',为OBS桶中数据集的路径,dst_url为执行容器中的路径
moxing.file.copy_parallel(src_url=args.data_url, dst_url='MNIST/')
方式二(推荐),拷贝他人共享的OBS桶内的数据集至执行容器,前提是他人账户下的OBS桶已设为公共读/公共读写。若在创建桶时桶策略为私有,请参考配置标准桶策略修改为公共读/公共读写。
import moxing
moxing.file.copy_parallel(src_url="s3://share-course/dataset/MNIST/", dst_url='MNIST/')
方式三(不推荐),先关联他人私有账户,再拷贝他人账户下OBS桶内的数据集至执行容器,前提是已获得他人账户的访问密钥、私有访问密钥、OBS桶-概览-基本信息-Endpoint。
import moxing
# 设置他人账户的访问密钥, ak:Access Key Id, sk:Secret Access Key, server:endpoint of obs bucket
moxing.file.set_auth(ak='Access Key', sk='Secret Access Key', server="obs.cn-north-4.myhuaweicloud.com")
moxing.file.copy_parallel(src_url="s3://share-course/dataset/MNIST/", dst_url='MNIST/')
可以参考使用常用框架训练模型来创建并启动训练作业(下文给出了操作步骤)。
打开ModelArts控制台-训练管理-训练作业,点击“创建”按钮进入训练作业配置页面,创建训练作业的参考配置:
main.py
启动并查看训练过程:
ModelArts Notebook资源池较小,且每个运行中的Notebook会一直占用Device资源不释放,不适合大规模并发使用(不使用时需停止实例,以释放资源)。
可以参考创建并打开Notebook来创建并打开Notebook(下文给出了操作步骤)。
打开ModelArts控制台-开发环境-Notebook,点击“创建”按钮进入Notebook配置页面,创建Notebook的参考配置:
注意:
- 在Jupyter Notebook/JupyterLab文件列表里,展示的是关联的OBS桶里的文件,并不在当前Notebook工作环境(容器)中,Notebook中的代码无法直接访问这些文件。
- 打开Notebook前,选中文件列表里的所有文件/文件夹(实验脚本和数据集),并点击列表上方的“Sync OBS”按钮,使OBS桶中的所有文件同时同步到Notebook执行容器中,这样Notebook中的代码才能访问数据集。
- 使用Notebook时,可参考与OBS同步文件;
- 使用JupyterLab时,可参考与OBS同步文件。
- 同步文件的大小和数量超过限制时,请参考MoXing常用操作示例中的拷贝操作,将大文件(如数据集)拷贝到Notebook容器中。
- Notebook/JupyterLab文件列表页面的“Upload/上传”功能,会将文件上传至OBS桶中,而不是Notebook执行容器中,仍需额外同步/拷贝。
- 在Notebook里通过代码/命令(如
wget, git
、pythonurllib, requests
等)获取的文件,存在于Notebook执行容器中,但不会显示在文件列表里。- 每个Notebook实例仅被分配了1个Device,如果在一个实例中打开多个Notebook页面(即多个进程),运行其中一个页面上的MindSpore代码时,请关闭其他页面的kernel,否则会出现Device被占用的错误。
- Notebook运行中一直处于计费状态,不使用时,在Notebook控制台页面点击实例右侧的“停止”,以停止计费。停止后,Notebook里的内容不会丢失(已同步至OBS)。下次需要使用时,点击实例右侧的“启动”即可。可参考启动或停止Notebook实例。
打开Notebook后,选择MindSpore环境作为Kernel。
提示:
- 上述数据集和脚本的准备工作也可以在Notebook环境中完成,在Jupyter Notebook文件列表页面,点击右上角的"New"->"Terminal",进入Notebook环境所在终端,进入
work
目录,可以使用常用的linux shell命令,如wget, gzip, tar, mkdir, mv
等,完成数据集和脚本的下载和准备。- 可将如下每段代码拷贝到Notebook代码框/Cell中,从上至下阅读提示并执行代码框进行体验。代码框执行过程中左侧呈现[*],代码框执行完毕后左侧呈现如[1],[2]等。请等上一个代码框执行完毕后再执行下一个代码框。
若已通过“Sync OBS”功能将OBS桶中的数据集同步到Notebook执行容器中,则跳过数据拷贝环节。若大小或数量超过同步限制,可通过ModelArts自带的moxing框架,将数据集拷贝至执行容器中。
方式一,拷贝自己账户下OBS桶内的数据集至执行容器。
import moxing
# src_url形如's3://OBS/PATH',为OBS桶中数据集的路径,dst_url为执行容器中的路径
moxing.file.copy_parallel(src_url="s3://OBS/PATH/TO/MNIST/", dst_url='MNIST/')
方式二(推荐),拷贝他人共享的OBS桶内的数据集至执行容器,前提是他人账户下的OBS桶已设为公共读/公共读写。若在创建桶时桶策略为私有,请参考配置标准桶策略修改为公共读/公共读写。
import moxing
moxing.file.copy_parallel(src_url="s3://share-course/dataset/MNIST/", dst_url='MNIST/')
方式三(不推荐),先关联他人私有账户,再拷贝他人账户下OBS桶内的数据集至执行容器,前提是已获得他人账户的访问密钥、私有访问密钥、OBS桶-概览-基本信息-Endpoint。
import moxing
# 设置他人账户的访问密钥, ak:Access Key Id, sk:Secret Access Key, server:endpoint of obs bucket
moxing.file.set_auth(ak='Access Key', sk='Secret Access Key', server="obs.cn-north-4.myhuaweicloud.com")
moxing.file.copy_parallel(src_url="s3://share-course/dataset/MNIST/", dst_url='MNIST/')
导入MindSpore模块和辅助模块,设置MindSpore上下文,如执行模式、设备等。
import os
# os.environ['DEVICE_ID'] = '0'
import mindspore as ms
import mindspore.context as context
import mindspore.dataset.transforms.c_transforms as C
import mindspore.dataset.vision.c_transforms as CV
from mindspore import nn
from mindspore.train import Model
from mindspore.train.callback import LossMonitor
context.set_context(mode=context.GRAPH_MODE, device_target='Ascend') # Ascend, CPU, GPU
在使用数据集训练网络前,首先需要对数据进行预处理,如下:
def create_dataset(data_dir, training=True, batch_size=32, resize=(32, 32),
rescale=1/(255*0.3081), shift=-0.1307/0.3081, buffer_size=64):
data_train = os.path.join(data_dir, 'train') # train set
data_test = os.path.join(data_dir, 'test') # test set
ds = ms.dataset.MnistDataset(data_train if training else data_test)
ds = ds.map(input_columns=["image"], operations=[CV.Resize(resize), CV.Rescale(rescale, shift), CV.HWC2CHW()])
ds = ds.map(input_columns=["label"], operations=C.TypeCast(ms.int32))
# When `dataset_sink_mode=True` on Ascend, append `ds = ds.repeat(num_epochs) to the end
ds = ds.shuffle(buffer_size=buffer_size).batch(batch_size, drop_remainder=True)
return ds
对其中几张图片进行可视化,可以看到图片中的手写数字,图片的大小为32x32。
import matplotlib.pyplot as plt
ds = create_dataset('MNIST', training=False)
data = ds.create_dict_iterator(output_numpy=True).get_next()
images = data['image']
labels = data['label']
for i in range(1, 5):
plt.subplot(2, 2, i)
plt.imshow(images[i][0])
plt.title('Number: %s' % labels[i])
plt.xticks([])
plt.show()
定义LeNet5模型,模型结构如下图所示:
[1] 图片来源于http://yann.lecun.com/exdb/publis/pdf/lecun-01a.pdf
提示: MindSpore model_zoo中提供了多种常见的模型,可以直接使用。
class LeNet5(nn.Cell):
def __init__(self):
super(LeNet5, self).__init__()
self.conv1 = nn.Conv2d(1, 6, 5, stride=1, pad_mode='valid')
self.conv2 = nn.Conv2d(6, 16, 5, stride=1, pad_mode='valid')
self.relu = nn.ReLU()
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
self.flatten = nn.Flatten()
self.fc1 = nn.Dense(400, 120)
self.fc2 = nn.Dense(120, 84)
self.fc3 = nn.Dense(84, 10)
def construct(self, x):
x = self.relu(self.conv1(x))
x = self.pool(x)
x = self.relu(self.conv2(x))
x = self.pool(x)
x = self.flatten(x)
x = self.fc1(x)
x = self.fc2(x)
x = self.fc3(x)
return x
使用MNIST数据集对上述定义的LeNet5模型进行训练。训练策略如下表所示,可以调整训练策略并查看训练效果,要求验证精度大于95%。
batch size | number of epochs | learning rate | optimizer |
---|---|---|---|
32 | 3 | 0.01 | Momentum 0.9 |
def train(data_dir, lr=0.01, momentum=0.9, num_epochs=3):
ds_train = create_dataset(data_dir)
ds_eval = create_dataset(data_dir, training=False)
net = LeNet5()
loss = nn.loss.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')
opt = nn.Momentum(net.trainable_params(), lr, momentum)
loss_cb = LossMonitor(per_print_times=ds_train.get_dataset_size())
model = Model(net, loss, opt, metrics={'acc', 'loss'})
# dataset_sink_mode can be True when using Ascend
model.train(num_epochs, ds_train, callbacks=[loss_cb], dataset_sink_mode=False)
metrics = model.eval(ds_eval, dataset_sink_mode=False)
print('Metrics:', metrics)
train('MNIST/')
epoch: 1 step 1875, loss is 0.23394052684307098
epoch: 2 step 1875, loss is 0.4737345278263092
epoch: 3 step 1875, loss is 0.07734094560146332
Metrics: {'loss': 0.10531254443608654, 'acc': 0.9701522435897436}
MindSpore还支持在本地CPU/GPU/Ascend环境上运行,如Windows/Ubuntu x64笔记本,NVIDIA GPU服务器,以及Atlas Ascend服务器等。在本地环境运行实验前,需要先参考安装教程配置环境。
在Windows/Ubuntu x64笔记本上运行实验:
# 编辑main.py 将第15行的context设置为`device_target='CPU'`
python main.py --data_url=D:\dataset\MNIST
在Ascend服务器上运行实验:
vim main.py # 将第15行的context设置为`device_target='Ascend'`
python main.py --data_url=/PATH/TO/MNIST
本实验展示了如何使用MindSpore进行手写数字识别,以及开发和训练LeNet5模型。通过对LeNet5模型做几代的训练,然后使用训练后的LeNet5模型对手写数字进行识别,识别准确率大于95%。即LeNet5学习到了如何进行手写数字识别。
MindSpore实验,仅用于教学或培训目的。配合MindSpore官网使用。 MindSpore experiments, for teaching or training purposes only. Use it together with the MindSpore official website.
CSV Jupyter Notebook Text Python Markdown other
Dear OpenI User
Thank you for your continuous support to the Openl Qizhi Community AI Collaboration Platform. In order to protect your usage rights and ensure network security, we updated the Openl Qizhi Community AI Collaboration Platform Usage Agreement in January 2024. The updated agreement specifies that users are prohibited from using intranet penetration tools. After you click "Agree and continue", you can continue to use our services. Thank you for your cooperation and understanding.
For more agreement content, please refer to the《Openl Qizhi Community AI Collaboration Platform Usage Agreement》