在校期间主学机器学习和算法,在一次偶然的机会接触了大数据,而后便入门大数据,至今也从事大数据平台开发工作。可是,仍然对AI技术念念不忘呀,平常也会做点机器学习相关的小东西,尝试一些demo,想着某一天还能回到曾经熟悉的领域,正如我博客名称,从大数据到人工智能。由于我的工作也是平台相关的,所以本次ModelArts的体验对我来说不仅仅是产品的使用者,更是一个产品的学习者。话不多说,接下来和大家分享一下作为产品使用者的体验。

作为一站式AI开发平台,华为云ModelArts提供了全周期AI工作流管理,让用户能够快速创建和部署模型。对于初学者,新手入门教程指引用户快速了解ModelArts产品。

新手入门指引

该新手入门指引为自动学习中的物体检测项目,将“云宝图片”数据集下载下来之后,在自动学习中创建物体检测项目,实现“云宝检测”的模型训练与模型部署。接下来分享一下该入门项目指南。

创建OBS对象存储桶

OBS是华为云的对象存储服务,由于ModelArts只上线了部分区域,所以需要确保购买的OBS资源的区域和ModelArts在同一个区域,例如我这边全部选择“北京四”。



OBS有按需计费和按量计费两种方式,新用户可以以9元体验1年40G的存储服务,详细的计费方式和购买方式可参考:

计费方式: https://support.huaweicloud.com/drawer-obs/obs_99_0016.html

购买方式:https://console.huaweicloud.com/console/?region=cn-north-4&locale=zh-cn#/obs/buy

然后在上述区域创建OBS桶,例如我这里创建了bigdatatoai桶


下载数据并上传至OBS

下载https://modelarts-cnnorth1-market-dataset.obs.cn-north-1.myhuaweicloud.com/dataset-market/Yunbao-Data-Custom/archiver/Yunbao-Data-Custom.zip

数据,按照提示将数据上传到OBS。这边有两种方式上传,一种是直接通过网页上传,另一种是通过OBS桌面工具OBS Browser+上传,下面介绍一下通过OBS Browser+上传的方式。

首先您要在此处下载并安装该工具:https://support.huaweicloud.com/browsertg-obs/obs_03_1003.html 。本处以windows为例:

首先申请访问密钥,得到密钥之后,填入OBS Browser+即可。




登录之后便可以看到我们刚刚创建的桶


在桶内创建文件夹modelArt/dataset/yunbao,将原始数据上传到此目录(可直接拖拉上传)



自动学习入门

接着便可以使用自动学习功能,对刚刚上传的云宝图像进行模型训练。


不过在实际进行使用之前还需要授权委托,本文以自动创建委托为例。


点击自动学习中的目标检测,使用我们刚刚上传的数据创建项目



项目创建完成之后,便可使用已标注的数据进行训练,原始数据中已标注的数据为20个,其余40个数据未标注,后续步骤中使用手动标注之后再进行模型训练。




模型训练


训练完成之后得到如下评估结果,


接着便可以将模型部署上线


模型使用

使用已知刚刚训练好的模型进行预测,通过页面上传eval中的图像



当然,也可以通过api调用的方式对图像进行检测。

根据https://support.huaweicloud.com/engineers-modelarts/modelarts_23_0063.html所述,使用postman获取X-Auth-Token


然后使用模型页面的api对图像进行检测


本文使用curl方式发送图片,(使用postman一直返回400)得到如下结果



手动标记数据重新训练

刚刚我们使用20张已经标记好的数据对模型进行训练,现在手动对剩余的40张图片进行标记。


使用标记后的60张图片重新训练:


重新训练的结果如下


可见其性能相较于20张图片的训练有所提高。

CodeLab - 开箱即用的在线NoteBook开发环境

总览

平台化的一个极大优势就是开箱即用。我很喜欢CodeLab这个能力。接下来我们来体验一下如何使用CodeLab开发。

首先点击立即使用,进入NoteBook开发环境。



CodeLab目前直接支持如下类型的机器学习框架,如果您觉得不满意,还可以使用conda在终端中自由安装。


使用mnist数据训练全连接网络

参考地址:https://mxnet.apache.org/versions/1.5.0/tutorials/gluon/mnist.html

下面我以mxnet框架为例,尝试运行经典的手写数字识别的例子。

首先下载训练和测试数据

import mxnet as mx# Select a fixed random seed for reproducibility
mx.random.seed(42)def data_xform(data):"""Move channel axis to the beginning, cast to float32, and normalize to [0, 1]."""return nd.moveaxis(data, 2, 0).astype('float32') / 255train_data = mx.gluon.data.vision.MNIST(train=True).transform_first(data_xform)
val_data = mx.gluon.data.vision.MNIST(train=False).transform_first(data_xform)

加载数据

batch_size = 100
train_loader = mx.gluon.data.DataLoader(train_data, shuffle=True, batch_size=batch_size)
val_loader = mx.gluon.data.DataLoader(val_data, shuffle=False, batch_size=batch_size)

导入必要的包

from __future__ import print_function  # only relevant for Python 2
import mxnet as mx
from mxnet import nd, gluon, autograd
from mxnet.gluon import nn

构建全连接网络

net = nn.HybridSequential(prefix='MLP_')
with net.name_scope():net.add(nn.Flatten(),nn.Dense(128, activation='relu'),nn.Dense(64, activation='relu'),nn.Dense(10, activation=None)  # loss function includes softmax already, see below)

网络初始化,使用cpu进行训练

ctx = mx.cpu(0)
net.initialize(mx.init.Xavier(), ctx=ctx)

定义如何训练上述构建的全连接网络

trainer = gluon.Trainer(params=net.collect_params(),optimizer='sgd',optimizer_params={'learning_rate': 0.04},
)

定义损失函数

metric = mx.metric.Accuracy()
loss_function = gluon.loss.SoftmaxCrossEntropyLoss()

重复10次训练

num_epochs = 10for epoch in range(num_epochs):for inputs, labels in train_loader:# Possibly copy inputs and labels to the GPUinputs = inputs.as_in_context(ctx)labels = labels.as_in_context(ctx)# The forward pass and the loss computation need to be wrapped# in a `record()` scope to make sure the computational graph is# recorded in order to automatically compute the gradients# during the backward pass.with autograd.record():outputs = net(inputs)loss = loss_function(outputs, labels)# Compute gradients by backpropagation and update the evaluation# metricloss.backward()metric.update(labels, outputs)# Update the parameters by stepping the trainer; the batch size# is required to normalize the gradients by `1 / batch_size`.trainer.step(batch_size=inputs.shape[0])# Print the evaluation metric and reset it for the next epochname, acc = metric.get()print('After epoch {}: {} = {}'.format(epoch + 1, name, acc))metric.reset()

在执行10次之后的训练精度为0.9725


接下来我们用测试集验证一下效果如何

metric = mx.metric.Accuracy()
for inputs, labels in val_loader:# Possibly copy inputs and labels to the GPUinputs = inputs.as_in_context(ctx)labels = labels.as_in_context(ctx)metric.update(labels, net(inputs))
print('Validaton: {} = {}'.format(*metric.get()))
assert metric.get()[1] > 0.96

得到测试精度为:0.9679


使用mnist数据训练lenet网络

接下来我们再使用上述数据来训练lenet和测试模型精度

定义lenet

lenet = nn.HybridSequential(prefix='LeNet_')
with lenet.name_scope():lenet.add(nn.Conv2D(channels=20, kernel_size=(5, 5), activation='tanh'),nn.MaxPool2D(pool_size=(2, 2), strides=(2, 2)),nn.Conv2D(channels=50, kernel_size=(5, 5), activation='tanh'),nn.MaxPool2D(pool_size=(2, 2), strides=(2, 2)),nn.Flatten(),nn.Dense(500, activation='tanh'),nn.Dense(10, activation=None),)

训练lenet网络

trainer = gluon.Trainer(params=lenet.collect_params(),optimizer='sgd',optimizer_params={'learning_rate': 0.04},
)
metric = mx.metric.Accuracy()
num_epochs = 10for epoch in range(num_epochs):for inputs, labels in train_loader:inputs = inputs.as_in_context(ctx)labels = labels.as_in_context(ctx)with autograd.record():outputs = lenet(inputs)loss = loss_function(outputs, labels)loss.backward()metric.update(labels, outputs)trainer.step(batch_size=inputs.shape[0])name, acc = metric.get()print('After epoch {}: {} = {}'.format(epoch + 1, name, acc))metric.reset()for inputs, labels in val_loader:inputs = inputs.as_in_context(ctx)labels = labels.as_in_context(ctx)metric.update(labels, lenet(inputs))
print('Validaton: {} = {}'.format(*metric.get()))
assert metric.get()[1] > 0.985

由下图可见,lenet的训练和测试精度达到了0.9905和0.9879


lenet模型导出

接下来我们把刚刚训练好的lenet网络导出到本地。


将上述两个文件下载到本地,然后再上传到OBS中。

使用lenet模型创建AI应用

经过上述步骤,我们将lenet模型导入到OBS的下述目录。


除此之外,我们还需要两个文件才能实现模型部署,一个是推理代码,一个是配置文件。官方已经提供了手写数字识别的推理代码,我们直接用即可,代码内容:

customize_service.py

import mxnet as mx
import requests
import zipfile
import json
import shutil
import os
import numpy as npfrom mxnet.io import DataBatch
from mms.log import get_logger
from mms.model_service.mxnet_model_service import MXNetBaseService
from mms.utils.mxnet import image, ndarraylogger = get_logger()def check_input_shape(inputs, signature):'''Check input data shape consistency with signature.Parameters----------inputs : List of NDArrayInput data in NDArray format.signature : dictDictionary containing model signature.'''assert isinstance(inputs, list), 'Input data must be a list.'assert len(inputs) == len(signature['inputs']), 'Input number mismatches with ' \'signature. %d expected but got %d.' \% (len(signature['inputs']), len(inputs))for input, sig_input in zip(inputs, signature['inputs']):assert isinstance(input, mx.nd.NDArray), 'Each input must be NDArray.'assert len(input.shape) == \len(sig_input['data_shape']), 'Shape dimension of input %s mismatches with ' \'signature. %d expected but got %d.' \% (sig_input['data_name'], len(sig_input['data_shape']),len(input.shape))for idx in range(len(input.shape)):if idx != 0 and sig_input['data_shape'][idx] != 0:assert sig_input['data_shape'][idx] == \input.shape[idx], 'Input %s has different shape with ' \'signature. %s expected but got %s.' \% (sig_input['data_name'], sig_input['data_shape'],input.shape)class DLSMXNetBaseService(MXNetBaseService):'''MXNetBaseService defines the fundamental loading model and inferenceoperations when serving MXNet model. This is a base class and needs to beinherited.'''def __init__(self, model_name, model_dir, manifest, gpu=None):print ("-------------------- init classification servive -------------")self.model_name = model_nameself.ctx = mx.gpu(int(gpu)) if gpu is not None else mx.cpu()self._signature = manifest['Model']['Signature']data_names = []data_shapes = []for input in self._signature['inputs']:data_names.append(input['data_name'])# Replace 0 entry in data shape with 1 for binding executor.# Set batch size as 1data_shape = input['data_shape']data_shape[0] = 1for idx in range(len(data_shape)):if data_shape[idx] == 0:data_shape[idx] = 1data_shapes.append(('data', tuple(data_shape)))# Load MXNet moduleepoch = 0try:param_filename = manifest['Model']['Parameters']epoch = int(param_filename[len(model_name) + 1: -len('.params')])except Exception as e:logger.warning('Failed to parse epoch from param file, setting epoch to 0')sym, arg_params, aux_params = mx.model.load_checkpoint('%s/%s' % (model_dir, manifest['Model']['Symbol'][:-12]), epoch)self.mx_model = mx.mod.Module(symbol=sym, context=self.ctx,data_names=['data'], label_names=None)self.mx_model.bind(for_training=False, data_shapes=data_shapes)self.mx_model.set_params(arg_params, aux_params, allow_missing=True)def _preprocess(self, data):img_list = []for idx, img in enumerate(data):input_shape = self.signature['inputs'][idx]['data_shape']# We are assuming input shape is NCHW[h, w] = input_shape[2:]if input_shape[1] == 1:img_arr = image.read(img, 0)else:img_arr = image.read(img)img_arr = image.resize(img_arr, w, h)img_arr = image.transform_shape(img_arr)img_list.append(img_arr)return img_listdef _postprocess(self, data):dim = len(data[0].shape)if dim > 2:data = mx.nd.array(np.squeeze(data.asnumpy(), axis=tuple(range(dim)[2:])))sorted_prob = mx.nd.argsort(data[0], is_ascend=False)top_prob = map(lambda x: int(x.asscalar()), sorted_prob[0:5])return [{'probability': float(data[0, i].asscalar()), 'class': i}for i in top_prob]def _inference(self, data):'''Internal inference methods for MXNet. Run forward computation andreturn output.Parameters----------data : list of NDArrayPreprocessed inputs in NDArray format.Returns-------list of NDArrayInference output.'''# Check input shapecheck_input_shape(data, self.signature)data = [item.as_in_context(self.ctx) for item in data]self.mx_model.forward(DataBatch(data))return self.mx_model.get_outputs()[0]def ping(self):'''Ping to get system's health.Returns-------StringMXNet version to show system is healthy.'''return mx.__version__@propertydef signature(self):'''Signiture for model service.Returns-------DictModel service signiture.'''return self._signature

接下来就是配置文件,其内容如下所示,我们可根据自己模型的精度修改metrics中的内容

config.json

{"model_type": "MXNet", "metrics": {"f1": 0.39542, "accuracy": 0.987426, "precision": 0.395875, "recall": 0.394966}, "dependencies": [], "model_algorithm": "image_classification", "apis": [{"procotol": "http", "url": "/", "request": {"Content-type": "multipart/form-data", "data": {"type": "object", "properties": {"images": {"type": "file"}}}}, "method": "post", "response": {"Content-type": "multipart/form-data", "data": {"required": ["predicted_label", "scores"], "type": "object", "properties": {"scores": {"items": {"minItems": 2, "items": [{"type": "string"}, {"type": "number"}], "type": "array", "maxItems": 2}, "type": "array"}}}}}]}

将上述两个文件也拷贝到OBS中


接下来我们便可以基于上述模型构建AI应用。



应用创建完成之后,接着便可以将该应用部署上线。


添加环境变量

input_data_name:images

input_data_shape:0,1,28,28

output_data_shape:0,10



等待部署完成之后便可执行预测操作。由于我们在模型中定义图片大小为28x28,所以我们输入的图像为28x28的黑白数字图像。

该图像可以通过下述方法获得:

通过搜索引擎搜索得到mnist图片,然后进行截图:


接着使用在线图片尺寸调整工具,将图片调整为28x28,

在线图片调整工具网址:https://www.iloveimg.com/zh-cn/resize-image#resize-options,pixels

那么经过上述操作,我们得到了一张28x28黑白手写7图像

在预测中上传此图像



接着点击预测,得到如下预测结果


lenet-mnist 28x28手写数字识别模型发布

点击下述链接进入模型发布页面

https://developer.huaweicloud.com/develop/aigallery/model/list



最终发布页面

https://developer.huaweicloud.com/develop/aigallery/model/detail?id=d6fcb13b-adc8-448e-a523-5d7f5d44b7a2


从AI Gallery订阅模型

AI Gallery是基于ModelArts发布的AI应用市场,该功能极大降低了AI模型的开发门槛,基于AI Gallery的AI模型市场,即使用户不了解AI知识,通过订阅模型服务,也可以直接使用该模型。我觉得随着技术的进步和社会的发展,AI肯定是要趋于平民化的,而AI Gallery此项功能正是该方向的极大开拓者。

接下来,和大家分享一下如何订阅我刚刚发布的模型,然后快速部署。

首先进入模型订阅页面,点击订阅:https://developer.huaweicloud.com/develop/aigallery/model/detail?id=d6fcb13b-adc8-448e-a523-5d7f5d44b7a2


订阅完成之后,前往控制台,选择ModelArts所在的云服务区域,我这边还是选择北京四。进入控制台后,便可以直接在线部署该模型


同样,模型部署时候,添加如下环境变量

input_data_name:images

input_data_shape:0,1,28,28

output_data_shape:0,10


模型部署成功之后便可进行手写数字识别


总结

华为云modelArts和AI Gallery给AI平民化铺了一条非常宽广的道路,各个层次的人都可以在上面走。有能力的AI开发者可以更专注于模型和算法开发,而不需要关注底层硬件侧面细节;普通使用者可以使用自动学习模块进行模型开发与部署;而对于没有任何ai先验知识的同学来说,有了AI Gallery,只需要几步便可以轻松部署AI应用。

从平台的角度来说,我对于这个产品是非常喜欢的,高级功能,轻松入手,高大上的能力直接通过平台化的方式平民化,或许也是我们工作中平台开发的方向。

本文参与 AI创想秀,邂逅“华为云ModelArts”征文大赛

参赛链接:https://blog.csdn.net/csdnstudent/article/details/122456112

AI平民化之路 - 华为云ModelArts和AI Gallery体验指南相关推荐

  1. ATN开源社区基于华为云ModelArts进行AI开发的实践

    ATN 公有链和智能矩阵 Atmatrix,采用区块链智能合约技术建立分布式账本,构建去中心化的 AI 交易市场,可以交易 AIaaS 的 AI API. AI 数据.AI 算力.AI 训练模型等.在 ...

  2. 人工智能之华为云ModelArts的深度使用体验与AI Gallery应用开发实践

    一.ModelArts 简介 ① 什么是 ModelArts? ModelArts 是面向 AI 开发者的一站式开发平台,提供海量数据预处理及半自动化标注.大规模分布式训练.自动化模型生成及端-边-云 ...

  3. 【华为云技术分享】使用CloudIDE快速体验基于华为云ModelArts SDK的AI开发

    华为云ModelArts一站式AI开发与管理平台,能够支撑开发者从数据到AI应用的全流程开发过程,包含数据处理.算法开发.模型训练.模型管理.部署等,支持图像分类.图像检测.视频分析.语音识别.产品推 ...

  4. 跑道防侵入,华为云ModelArts平台助力航空器识别AI模型开发

    上海麦图信息科技有限公司,借助华为云ModelArts一站式AI开发与管理平台,开发出跑道防侵入场景中的航空器识别AI模型. 近年来,"AI的应用和落地"逐渐成了具化的关键词,它和 ...

  5. 华为云ModelArts获得中国信通院首批AI开发平台全能力域领先级证书

    近日,由中国人工智能产业发展联盟(AIIA)指导.中国信息通信研究院云计算与大数据研究所主办的2021可信AI成果发布会在线上举行.会上,主办方公布了人工智能开发平台功能评测结果,在产品能力赛道,华为 ...

  6. AI创想秀,邂逅“华为云ModelArts”征文大赛

    AI创想秀,邂逅"华为云ModelArts"征文大赛第一季 一.大赛简介 华为云ModelArts是面向开发者的一站式AI开发平台,为机器学习与深度学习提供海量数据预处理及半自动化 ...

  7. 斯坦福DAWNBench:华为云ModelArts深度学习训练全球最快

    斯坦福DAWNBench:华为云ModelArts深度学习训练全球最快 近日,斯坦福大学发布了DAWNBenchmark最新成绩,在图像识别(ResNet50-on-ImageNet,93%以上精度) ...

  8. 对话实录 | 看华为云如何使能AI计算行业创新

    在LiveVideoStackCon2019深圳音视频技术大会前夕,我们邀请到了华为云异构计算产品总监赵刚接受采访,从职业生涯聊到华为云昇腾云服务器生态,更是首次独家曝光华为云昇腾AI计算解决方案.华 ...

  9. HDC.Cloud2021|华为云ModelArts Pro,让行业AI开发不再难

    去年,在华为开发者大会2020(Cloud)期间, 华为云发布了ModelArts Pro AI 应用开发套件,包括了视觉套件,文字识别套件,自然语言处理套件等. 经过一年的发展,华为云通过Model ...

最新文章

  1. hello是c语言中的变量吗,C语言hello world详解
  2. 执行力的问题--系统的无奈
  3. 自组织神经网络的实现
  4. Flutter之Center
  5. Java面向对象(1)--对象的创建使用类的实例化
  6. 疑问:当流量被封禁之后(论资本之力):防流量被恶意盗挖(抛砖篇)
  7. CSS 布局 - 水平 amp;amp; 垂直对齐,全面的水平垂直居中方案
  8. EM算法——解释 转载
  9. 按键精灵手机助手之以图找图
  10. Linux之查看物理主机的CPU温度
  11. lenovo L480 进入bios_rx5700刷bios秒变rx5700xt!rx5700刷rx5700xt bios图文教程
  12. k8s学习-深入理解Pod对象
  13. 在html里ff3d3d是什么颜色,HTML颜色参考
  14. npm install WARN package.json not exists: E:\SpringBoot\workplace\D4_pc_ui\.idea\package.json
  15. 面试题(2020)微信小程序常见面试题
  16. 1. Java基础语法
  17. java.net.SocketException: Too many open files解决方法
  18. java 24字母_java 时间格式化中的模式字母
  19. 软件测试多次点击按钮叫什么方法,常见控件的测试点 - 爱昵容儿 的个人空间 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
  20. 2021上岸东南大学网络空间安全学院916学硕心得分享——初试篇

热门文章

  1. JAVA龟兔赛跑案例
  2. 蓝牙 协议 包 java_蓝牙核心技术概述(五):蓝牙协议规范(irOBEX、BNEP、AVDTP、AVCTP)...
  3. Python可视化数据分析09、MySQL读写
  4. python画爱心原理_七夕倒计时,程序员式优雅表白,教你用python代码画爱心
  5. 关于css设置Comic Sans Ms字体
  6. 拼助理/拼管家小程序无法查砍价记录了怎么办?
  7. 人声合成效果器 – iZotope VocalSynth 2 v2.1.0 WiN-MAC
  8. mac c语言 转win,C ++跨平台开发(Windows和Mac OS)
  9. python递归函数的用法
  10. 京东数据挖掘工程师常用的 10多个 pandas 函数