贾浩楠 金磊 发自 凹非寺

量子位 报道 | 公众号 QbitAI
“炼丹侠”们苦当前深度学习框架久矣。
本来,AI框架的初衷是简化、加速和优化开发流程。但是轮子这么多,有从学界走出的Caffe、有谷歌力推的TensorFlow、Facebook押注的Pytorch….真正用起来省心省力的却不多。
Caffe不支持分布式,不够灵活,文档不够用,安装也比较复杂。
而TensorFlow中的循环和分支写起来的复杂和痛苦,用过的人都有体会…
框架越发展,瓶颈越明显。
这时,却有一个“框架工具套件”站出来说:
一分钟内上手AI应用开发、一小时掌握AI模型与数据集的自由切换。
TinyMS,就是它,MindSpore社区新开源的深度学习框架开发工具套件,在技术文档中,官方明确地说出了前面的话。
那么,TinyMS到底是什么?真能在一分钟内实现一个AI应用吗?

TinyMS是什么?

高端的AI开发方法,往往只需要最简单的工具套件。
TinyMS,代表了小(Tiny)、灵(Modular)、简(Simple),当然名字还有另外一个很好理解的角度,那就是“微型”MindSpore。
这是专门为去年同期才开源的AI计算框架MindSpore定制的高级API开发套件,目的是让新手用户能够更加轻松地上手深度学习,有效地减少用户在构建、训练、验证和推理一个模型过程中的操作次数。
TinyMS工具包主要用PyThon语言编写,对于开发者来说,TinyMS“一站式”服务包括了AI应用开发前期必要的数据准备,中期的模型架构、训练、编译工具,以及后端AI模型应用服务。
当然,TinyMS仍然贴心地推出了完整在线课程教学,以AI应用中常见的深度神经网络ResNet50等等为例,一步步教你如何使用TinyMS实现自己的AI应用。在线课程将以网剧更新的新颖形式,在MindSpore官方B站进行不断更新,等不及的开发者已经可以开始“追剧”了!
课程的最后还设置了一个挑战赛,针对小白和高手分别设计了不同难度的比赛,任务是复现TinyMS的模型。每个比赛都会设一个一等奖和三个二等奖,对于参赛人员来说,只要跑通网络就有机会获得价值三千元的奖品;如果调参的精度是Top1,即可获得价值一万元的奖品。感兴趣的开发者可联系小助手微信:“mindspore0328”报名参赛。
我们接着来看看TinyMS的构成和主要功能模块。
从任务流程上看,TinyMS的基本架构分为五个部分:数据处理、模型构建、训练、验证、部署。
其中数据处理模块提供常用数据集下载、解压、加载等操作,同时,为了让模型有更好的表现,一般还针对原始数据进行数据预处理(增强)操作。
而在模型构建中,除了网络主体的构建,还包括Loss损失函数、Optimizer优化器等定义。
模型构建好后,就进入了训练的流程,TinyMS在训练中提供回调函数的定义。即回调操作可以在训练的各个阶段执行,可能是在epoch之间,在处理一个batch之后,甚至在满足某个条件的情况下完全由用户做主。
这样一来,用户可以利用许多创造性的方法来改进训练和性能,节省计算资源,并获知供有关神经网络内部发生的事情的结论。
TinyMS中的精度验证模块,负责模型精度验证的流程,其中评价指标metrics可由用户自己定义。
最后,就是模型部署,serving模块可以通过搭建服务器,来提供AI模型应用服务,为新手提供快速推理的体验。
到底好不好用?我们一试便知。

一分钟实现AI应用?试试看!

俗话说“光说不练假把式”,实践才能检验TinyMS的真本事。
Now!上手体验一下!
老规矩,在安装之前,先来介绍一下环境需求:
  • 操作系统:Ubuntu 18.04 或 Windows 10。
  • Python版本:3.7.5。

安装也是非常的方便,只要“pip一下”就好:
pip install tinyms==
0.1.0
此处温馨提示:若是下载速度太慢,可以试试下面的镜像哦:
mkdir -pv /root/.pip \

&& echo 
"[global]"
 > /root/.pip/pip.conf \

&& echo 
"trusted-host=mirrors.aliyun.com"
 >> /root/.pip/pip.conf \

&& echo 
"index-url=http://mirrors.aliyun.com/pypi/simple/"
 >> /root/.pip/pip.conf

要是想检验一下安装是否成功,可以跑一下这个小demo:
import
 tinyms 
as
 ts

from
 tinyms.primitives 
import
 tensor_add


x = ts.ones([
2
3
])

y = ts.ones([
2
3
])

print(tensor_add(x, y))

若出现如下结果,则证明安装成功。
[[
2.2.2.
]

 [
2.2.2.
]]

接下来,是时候展示TinyMS真正的实力了——只要1分钟,就可以实现图形分类应用(LeNet5模型)
先要做工作,是导入模块(TinyMS中的主要功能模块)
import
 json

import
 tinyms.optimizers 
as
 opt


from
 PIL 
import
 Image

from
 tinyms 
import
 context

from
 tinyms.data 
import
 MnistDataset, download_dataset

from
 tinyms.vision 
import
 mnist_transform, ImageViewer

from
 tinyms.model 
import
 Model, lenet5

from
 tinyms.serving 
import
 start_server, predict, list_servables, shutdown, server_started

from
 tinyms.metrics 
import
 Accuracy

from
 tinyms.losses 
import
 SoftmaxCrossEntropyWithLogits

from
 tinyms.callbacks 
import
 ModelCheckpoint, CheckpointConfig, LossMonitor

接下来是
构建模型
,但听到这个环节不要打怵,并没有你印象中的那么多代码,现在只需要短短2行。

因为TinyMS封装了MindSpore LeNet5模型中的init和construct函数,所以代码量大幅减少:
# 构建网络
net = lenet5(class_num=
10
)

model = Model(net)

构建完模型后,就是下载数据集(TinyMS自带数据集)
# 下载数据集
mnist_path = 
'/root/mnist'
ifnot
 os.path.exists(mnist_path):

    download_dataset(
'mnist'
'/root'
)

    print(
'************Download complete*************'
)

else
:

    print(
'************Dataset already exists.**************'
)

有了模型,有了数据,当然就需要开始“操练”了。
训练模型的过程当中,刚才下载的数据集,会被分为训练集和验证集。训练完成后会进行验证并输出 Accuracy 指标:
# 创建mnist路径
ckpt_folder = 
'/etc/tinyms/serving/lenet5'
ckpt_path = 
'/etc/tinyms/serving/lenet5/lenet5.ckpt'
ifnot
 os.path.exists(ckpt_folder):

    !mkdir -p  /etc/tinyms/serving/lenet5

else
:

    print(
'lenet5 ckpt folder already exists'
)


# 设置环境参数
device_target = 
"CPU"
context.set_context(mode=context.GRAPH_MODE, device_target=device_target)

dataset_sink_mode = 
False

# 创建数据集
train_dataset = MnistDataset(os.path.join(mnist_path, 
"train"
), shuffle=
True
)

train_dataset = mnist_transform.apply_ds(train_dataset)

eval_dataset = MnistDataset(os.path.join(mnist_path, 
"test"
), shuffle=
True
)

eval_dataset = mnist_transform.apply_ds(eval_dataset)


# 设置训练参数
lr = 
0.01
momentum = 
0.9
epoch_size = 
1
batch_size = 
32

# 定义loss函数
net_loss = SoftmaxCrossEntropyWithLogits(sparse=
True
, reduction=
'mean'
)


# 定义optimizer
net_opt = opt.Momentum(net.trainable_params(), lr, momentum)

net_metrics={
"Accuracy"
: Accuracy()}

model.compile(loss_fn=net_loss, optimizer=net_opt, metrics=net_metrics)


print(
'************************Start training*************************'
)

ckpoint_cb = ModelCheckpoint(prefix=
"checkpoint_lenet"
, config=CheckpointConfig(save_checkpoint_steps=
1875
, keep_checkpoint_max=
10
))

model.train(epoch_size, train_dataset, callbacks=[ckpoint_cb, LossMonitor()],dataset_sink_mode=dataset_sink_mode)

print(
'************************Finished training*************************'
)

model.save_checkpoint(ckpt_path)



model.load_checkpoint(ckpt_path)

print(
'************************Start evaluation*************************'
)

acc = model.eval(eval_dataset, dataset_sink_mode=dataset_sink_mode)

print(
"============== Accuracy:{} =============="
.format(acc))

为了后续推理过程的需要,在训练模型后,需要定义一个lenet5 servable json文件。
该文件定义了servable名称,模型名称,模型格式和分类数量:
servable_json = [{
'name'
'lenet5'
,

'description'
'This servable hosts a lenet5 model predicting numbers'
,

'model'
: {

"name"
"lenet5"
,

"format"
"ckpt"
,

"class_num"
10
}}]

os.chdir(
"/etc/tinyms/serving"
)

json_data = json.dumps(servable_json, indent=
4
)


with
 open(
'servable.json'
'w'
as
 json_file:

    json_file.write(json_data)

准备工作就绪,现在就要让“机器”运作起来(启动服务器)
start_server()

然后在命令行终端,用“scp”或者“wget”来获取一张图片作为输入(一张0~9之间的数字图片)
使用list_servables函数检查当前后端的serving模型:
list_servables()

如果输出的description字段显示这是一个lenet5的模型,那就可以顺利进入下一步——发送推理请求。
# 设置图片路径和输出策略(可以在TOP1和TOP5中选择)
image_path = 
"/root/7.png"
strategy = 
"TOP1_CLASS"

# predict(image_path, servable_name, dataset='mnist', strategy='TOP1_CLASS')
# predict方法的四个参数分别是图片路径、servable名称,数据集名称(默认MNIST)和输出策略(默认输出TOP1,可以选择TOP5)
if
 server_started() 
isTrue
:

    img_viewer = ImageViewer(Image.open(image_path), image_path)

    img_viewer.show()

    print(predict(image_path,
'lenet5'
'mnist'
, strategy))

else
:

    print(
"Server not started"
)

如果最后你能看到这样的输出:
TOP1: 
7
, score: 
0.99934917688369750977
恭喜你,一次成功的推理,就这么简单、顺利地完成了!

Keras、fastai还不够用吗?

现在有众多为深度学习框架量身定做的API,那么,TinyMS存在的独特意义是什么?
原因之一是,原生框架的API并不能满足所有用户/开发者的需求,所以需要框架拥有更加简单有效的高阶API、低运行开销、模块化开发以及敏捷部署。
之前有针对TF推出的Keras,它确实好上手,但是“大而全”的Keras层层封装,不够灵活快速。
还有基于Pytorch的Fastai,深度学习库项目较轻便,目录清晰易理解,可以说是“小而美”。但在预置数据集和推理模块上存在短板。
TinyMS在高阶API方面理念与Fastai相近,不同点在于TinyMS提供了常用的MindSpore预置数据集,方便开发者简化对数据集的调用,而且提供了Fastai尚未提供的快速部署推理模块等。
此外,对比Keras,TinyMS在高阶API方面会更为简单抽象,较keras来说复杂度更低,比如提供了只需一行代码即可完成数据集的预处理,而且在设计中重点考虑到了Keras尚未提供单独好用的工具库,以及尚未提供的快速部署推理模块等。
其二,对于全场景AI计算框架MindSpore来说,高阶和中阶Python API已经实现了Keras的大部分功能,所以即使要做一套API,也不需要类似Keras再额外封装一层。
因此TinyMS的重点不是基于底层框架的特点或不足进行进一步优化,而是着重提升开发者对MindSpore的使用体验,尤其是面向全场景的开发和部署。
比如,TinyMS主要语言是PyThon,简单易用,且所有功能都是易于扩展的模块化设计,能够覆盖多种业务场景。
开源深度学习开发工具包,包括了数据集处理工具、模型架构、训练、编译工具,以及后端AI模型应用服务,为新手提供快速推理的体验。
由此就能看出TinyMS面向的主要用户群体为深度学习初学者、其他研究领需要使用深度学习的科研人员、以及深度学习相关业务应用开发的企业人员。
直白的说TinyMS就是深度发挥MindSpore优势,以实际开发需求为导向,极致简化AI上手的复杂度。
TinyMS是一个新生的开源项目,站在Keras、fastai等巨人的肩膀上,虽然在设计理念上有所创新,但依然需要社区开发者一起持续协作,才能达到更好地服务学术界、产业界和开发者的深度和广度。
TinyMS开源社区中除了TinyMS项目外,还有如下一些项目和活动:
Specification项目:主要用来协作制定面向模型训练脚本的格式规范。由于TinyMS提供了较为高阶的API抽象,因此诞生了ModelZoo脚本规范性和标准化的需求,便于高阶封装的持续迭代;

tinyms-ai.github.io:开源实现的简单官方网站搭建,基于Github Page;

RustedAI Team:目前只有组织成员可见,RustedAI是TinyMS旨在推动利用Rust语言编写更多的低运行时开销的深度学习组件;

社区活动:不定期组织TinyMS模型拉力赛,以及多种多样的Meetup活动。

开源“开源运营”

作为TinyMS的作者,MindSpore社区运营团队除了为开发者带来这一新的开发项目外,还与开放原子开源基金会合作,即将推出0xCommOps这一新颖的开源项目,准备将本来最没有开放需求的开源社区运营也开源出来。分享MindSpore社区运营团队这一年创新的全维度运营的理念,同时也号召更多的社区运营爱好者一起分享其所特有的经验和教训。
总之,在深度学习框架这件事上,又有一个实力玩家积极入场服务开发者。
试一试TinyMS,欢迎把体验感想告诉我们~
TinyMS下载地址:

https://tinyms.readthedocs.io/zh_CN/latest/index.html
— 
 —

本文系网易新闻•网易号特色内容激励计划签约账号【量子位】原创内容,未经账号授权,禁止随意转载。
点这里👇关注我,记得标星,么么哒~
加入AI社群,拓展你的AI行业人脉
量子位「AI社群」招募中!欢迎AI从业者、关注AI行业的小伙伴们扫码加入,与50000+名好友共同关注人工智能行业发展&技术进展
一键三连「分享」、「点赞」和「在看」
科技前沿进展日日相见~
继续阅读
阅读原文