华为云 ModelArts 操作总结(华为云开发者青年班--AI实战营,黑客松大赛)

目录

训练作业创建:垃圾分类训练作业实验

自动学习创建:垃圾分类

自动学习创建:零代码美食分类模型开发

数据集创建:使用ResNet50预置算法基于海量数据训练美食分类模型

训练作业创建:猫狗识别(智能标注、TensorBoard)

智能标注

训练作业

Notebook使用:Yolo3物体检测

附注 : .ipynb内容


参加了华为云AI青年班及黑客松大赛,学习了如何操作华为云 ModelArts 控制台实现自己的模型管理、OBS数据存储系统管理(可下载 OBS Browser+,方便上传下载数据,但不用的时候还是要及时关掉,个人感觉比较占用CPU处理)、模型调优等。

黑客松比赛结果
标题

以下通过一些典型内容总结了 华为云 ModelArts 控制台 的主要功能。OBS 数据存储、模型调优等如果认为有必要会再写出来,其实,OBS桶就是一个有收费的存储站,用它可以很方便和 ModelArts 里面的数据文件‘通信’---比如,训练模型的输出、数据集的调用。

具体相关的文件我上传了资源,有兴趣的去我CSDN主页下载即可。

首先是注册华为云账号,注册过程不多解释,按提示走即可;然后,进入华为云 ModelArts 控制台官网进去-->产品-->EI企业智能-->EI基础平台-->AI开发平台ModelArts-->进入控制台;接着便可进行下面的系列内容。

训练作业创建:垃圾分类训练作业实验

1. 登陆华为云 ModelArts 控制台,训练管理 --> 训练作业--> 创建。

可以设置的参数有:

  • 作业名称:trainjob-name
  • 算法来源:(多种可选,华为云预置了一些经典算法,如yolo3等;也可管理自己的算法;或者自定义算法来源,本项目使用‘常用框架’)‘常用框架’ 的 tensorflow
  • 数据来源:obs桶目录下存储的的数据文件【注意,路径下直接是训练数据文件,否则可能运行失败】;
  • 代码目录:obs桶目录下存储的代码文件;
  • 启动文件:代码目录下的.py文件;
  • 训练输出位置:obs桶目录下设置的output文件(自己在OBS桶下面新建一个即可)。
  • 运行参数:新增两=类别个数、配置路径【obs桶目录下存储的代码文件下的配置文件】。
  • num_classes=8 和 8个类别
  • deploy_script_path= obs://wt.wang-garbage-trainjob/garbage_src/deploy_scripts/ 
  • 作业日志路径:obs://wt.wang-garbage-trainjob/log_wwt/

2.  训练作业任务提交后,可以在训练管理-训练作业,中查看‘配置信息’ ‘日志’ ‘资源占用情况‘。

3. 训练作业完毕,进入模型管理-->模型-->‘导入‘模型,(名称:model-name;版本号; 元模型来源:训练作业的对应版本; 部署类型:在线服务),设置完点击’立即创建‘

4. 部署上线,选择‘在线服务‘中’部署‘(名称:service-name; 公共资源池-我的模型-模型版本-计算节点规格),部署任务提交。

5. 部署成功后,进行预测。用本地测试图像进行测试,完成后关闭在线服务。

Notes : deploy_script_path 路径下包含的两个配置文件的名称不能改变,为“config.json” 和 “customize_service.py”,需要自己编写,编写方式可以参考上传资源里面的代码文件书写方式。

相关步骤的图示过程如下。

---------------训练作业创建设置----------------

此处的数据来源错误,应该再往下一层进入训练文件夹。

---------------训练作业创建完成:查看运行情况----------------

运行失败,改变训练数据文件路径,重新运行,成功。

---------------训练作业创建设置:常用框架展示例子----------------

---------------代码文件----------------

---------------数据文件----------------

---------------查看训练作业运行情况----------------

---------------成功部署后的测试例子----------------

自动学习创建:垃圾分类

1. 登陆OBS桶,建桶,上传数据集(查看我的CSDN资源页面,对应该标题名称“自动学习创建:垃圾分类”)。

2. 登陆华为云 ModelArts 控制台,自动学习 --> 图像分类 --> 创建项目。

3. 接着,根据下面图示过程,标注数据、训练、部署、测试即可。

Note:完成后记得释放资源,避免收费。

---------------自动学习创建项目----------------

---------------创建完成后,进入运行页面,同步、标注数据----------------

---------------标注完数据后,进入模型训练,可以自己根据情况选择合适的资源,数据集切分比例---------------

---------------自动学习训练完成后,点击“模型部署”----------------

---------------自动学习部署成功,即可预测----------------

自动学习创建:零代码美食分类模型开发

和自动学习的垃圾分类项目类似。(查看我的CSDN资源页面,对应该标题名称“自动学习创建:零代码美食分类模型开发”)。

ModelArts控制台:自动学习-图像分类:exeML-proj-name

  1. 数据集输入输出位置指定【obs目录】后,完成项目创建。
  2. 进入项目exeML-proj-name,进行数据标注,标注完开始训练,(训练设置指定版本号、训练验证数据比例、预期推理硬件、最大推理时长、最大训练时长、计算规格)。
  3. 训练结束后,部署上线,部署成功后,进行服务测试,用本地测试图像进行测试,完成后关闭在线服务。

---------------自动学习,美食数据已经上传资源---------------

---------------自动学习部署成功,即可预测----------------

数据集创建:使用ResNet50预置算法基于海量数据训练美食分类模型

---------------目前为止(2020.5.13),华为预置算法截图----------------

1. 首先需要将数据集上传到OBS桶中。接着在ModelArt创建数据集。(查看我的CSDN资源页面,对应该标题名称“数据集创建:使用ResNet50预置算法基于海量数据训练美食分类模型.zip”)。

2. 登陆ModelArts控制台,数据管理-->数据集-->创建数据集,名称为 dataset-name,参数设置如下

  • 数据集输入输出位置:指定【obs目录】后,标注场景选‘图片‘,标注类型选’图像分类‘;完成数据集创建。

3. 点击进入创建的数据集,开始标注、发布数据集、并进行一键上线。

4. “开始标注” 数据。‘同步数据源‘(数据集输入输出位置的同步)后,手工标注没有标签的数据,也可以用自动标注(自动标注需要自己先标注一部分,且自动标注后会提示确认自动标注的是否正确,错了可以修改);

5.“发布”数据集,(版本号、版本格式、训练验证比例),发布后可以用版本管理查看。6. 数据集中 “一键模式上线”任务创建。参数设置如下:

  • 名称:auto-deploy-name
  • 训练预置算法:ResNet_v1_50
  • 运行参数:默认,有需要可以自己改。
  • 训练输出位置:obs路径。训练输出位置用来保存训练输得到的模型和TensorBoard日志
  • 作业路径位置:obs路径。自己建立。
  • 训练资源池:公共;类型:GPU;规格:CPU8 64GiB GPU1 * nvidia-p100 16GiB;计算节点个数:1
  • 部署资源池:公共;计算节点规格:限时免费CPU;计算节点个数:1. 如果是多个计算节点,就是多实例部署,可以提高API的并发数

7. 提交后,等待,一条龙过程有:初始化训练-生成模型-部署-完成。中途可以进入相应详情页查看训练详情、模型详情、部署/服务详情等。

  • 比如,查看训练作详情。ModelArts --> 训练管理-->训练作业 auto-deploy-name点击进入。查看配置信息、日志、资源占用情况。进行在线服务测试。用本地测试图像进行测试,完成后关闭在线服务。

API接口地址: https://bb06320f3ab241fa93e8c7b655efc909.apig.cn-north-4.huaweicloudapis.com/v1/infers/13fe4db2-382c-4525-b68f-a26bcc13a843

点击部署服务测试页面右侧的“调用接口指南” 进入如下链接:https://support.huaweicloud.com/engineers-modelarts/modelarts_23_0063.html

---------------自动学习,美食数据已经上传CSDN资源---------------

---------------创建数据集---------------

---------------对创建的数据集,进行任务创建:一键模型上线.---------------

----------------一键模型上线过程中,可以根据过程自由查看生成的模型、部署详情页面等---------------

---------------自动学习部署成功,即可预测---------------

完了后同样关闭在线服务,避免持续扣费。需要时,重新启动。

训练作业创建:猫狗识别(智能标注、TensorBoard)

1. 训练作业步骤,首先新建OBS桶,把写的代码文件、相关数据上传。

  • .py代码脚本上传到obs项目文件夹新建的codes目录
  • 下载猫狗数据集.tar.gz,无需解压上传到obs项目文件夹新建的data目录
  • 创建训练作业,步骤同本doc第一节,不过这儿不用新增运行参数。
  • 后续同第一个训练作业创建的项目。

智能标注

---------------智能标注:数据准备,上传到桶---------------

(查看我的CSDN资源页面,资源标题名称“训练作业创建:猫狗识别.zip”)

注意:OBS桶名全局唯一,如果创建桶时桶名冲突,需要选择其他桶名。

上传刚刚下载的猫狗图片,并新建一个输出文件output 一个用于数据标注输出的文件data_label_out

---------------智能标注:ModelArts 创建数据集,手工标注一些,剩余点击智能标注,后续观察校正即可---------------

Notes:智能标注这个功能个人感觉并不好用。也可能是我没用好。

智能标注作业完成后,我们需要人工仔细确认每张图片的智能标注的结果。对标注正确的图片进行接纳;对标注错误的进行纠正。修改后,再次智能标注。依据之前处理智能标注结果的流程,处理第二次的智能标注作业。依次地,处理完所有。

训练作业

(查看我的CSDN资源页面,代码"dog_and_cat_train.py"在资源标题名称“训练作业创建:猫狗识别.zip”,数据集因为太大了,CSDN有限制,没有上传,感兴趣的可以从其他来源搜索获取。)

---------------数据(无需解压)、代码上传到桶---------------

和之前步骤一样,创建训练作业

---------------训练作业创建---------------

---------------查看训练作业运行结果---------------

训练作业页面,点击作业名称,进入作业详情界面。可以查看到训练作业的详情。

---------------创建可视化作业(TensorBoard)查看训练过程---------------

查看lossaccuracy等参数的变化信息。

训练详情页面右上侧,点击创建可视化作业按钮(即,创建TensorBoard)。

 

TensorBoard可以直观地显示训练过程中lossaccuracy等评估指标的变化曲线,为开发者优化模型精度提供依据。

注意:TensorBoard使用完后需要及时关闭,否则会继续扣费。

---------------训练完成后,即可部署模型---------------

步骤1 . 需知---推理脚本customize_service.py 和模型配置文件config.json 导入模型文件model下。

customize_service.py 推理脚本中有两个方法。_preprocess 预处理方法,在推理请求前调用,用于将API接口用户原始请求数据转换为模型期望输入数据_postprocess 后处理方法,在推理请求完成后调用,用于将模型输出转换为API接口输出。

config.json 模型部署配置信息,定义了AI引擎的类别,推理脚本需要的Python依赖等。

步骤2 .开始---导入模型。

点击模型管理界面,然后点击导入”按钮。

命名模型,设置版本号,选择元数据来源:从训练中选择。

注意,其他参数会自动加载;推理代码:https://wt.wang-dogcat-recog.obs.myhwclouds.com/output/model/customize_service.py

步骤3 . 部署模型为在线服务。

模型管理页面, 找到之前导入的模型,点击部署下拉框中的在线服务”。

同样,命名部署的在线服务的名称、模型来源等参数。

-模型部署成功如下。

步骤4 . 预测发起

注意:实验完成后,为了防止继续扣费,需要把在线服务停止掉,在线服务停止后可以重新启动。点击停止按钮即可:

Notebook使用:Yolo3物体检测

(查看我的CSDN资源页面,资源标题名称“Notebook:Yolo3物体检测.zip”)

具体操作步骤:

1. 登陆ModelArts控制台 --> 开发环境 --> Notebook --> 创建. 

  • 名称:notebook-obj-dect-yolo;参数:python3-公共资源池-GPU-云硬盘EVS

----------------------------------Notebook创建------------------------------------------

---------------------------------Notebook 开发环境下编写代码---------------------------------------------

点击‘new’, ’tensorflow-1.13.1’【和anaconda的jupyter notebook一样操作新建】

经过上面代码解压的数据文件,如下。

观察下载内容:coco是标注的训练数据文件和一些图片文件;model_data里面是模型参数文件和coco数据的类别文件;yolo3里面是模型源代码;train.py是训练代码,test.jpg用于最后的预测。Font里面不用在意。

-----------------------------代码部分运行结果-------------------------------------------

yolo3 相关:

  1. https://mp.weixin.qq.com/s?src=11&timestamp=1587811364&ver=2300&signature=oqxbJ2QesbigUa47KfTIPiAGDvwhXjquIlY8qqP*jkjm9YNiqf9tvMTKfpgpN923utyKMPcxB6kFmCVBM0nkA8y-LcagvWxVqv22XwYKqP*Fn6CvNxXqyKi5mXxtTagf&new=1
  2. https://blog.csdn.net/qq_41375609/article/details/94737915
  3. https://blog.csdn.net/zziahgf/article/details/72819043

----------------------------------代码文件已经上传资源------------------------------------------

附注 : .ipynb内容

下面插入的代码在华为云 ModelArts平台的Notebook 下运行通过。 

# 数据和代码下载,此处可不要,见CSDN资源文件。
from modelarts.session import Session
sess = Session()

if sess.region_name == 'cn-north-1':
    bucket_path="modelarts-labs/notebook/DL_object_detection_yolo/yolov3.tar.gz"
elif sess.region_name == 'cn-north-4':
    bucket_path="modelarts-labs-bj4/notebook/DL_object_detection_yolo/yolov3.tar.gz"
else:
    print("请更换地区到北京一或北京四")

sess.download_data(bucket_path=bucket_path, path="./yolov3.tar.gz")

# 解压文件
!tar -xf ./yolov3.tar.gz

# 清理压缩包
!rm -r ./yolov3.tar.gz

# ------------------------------------------------------
# 准备数据
# ----------------------------------------------------------
from train import get_classes, get_anchors
# 数据文件路径
data_path = "./coco/coco_data"
# coco类型定义文件存储位置
classes_path = './model_data/coco_classes.txt'
# coco数据anchor值文件存储位置
anchors_path = './model_data/yolo_anchors.txt'
# coco数据标注信息文件存储位置
annotation_path = './coco/coco_train.txt'
# 预训练权重文件存储位置
weights_path = "./model_data/yolo.h5"
# 模型文件存储位置
save_path = "./result/models/"

classes = get_classes(classes_path)
anchors = get_anchors(anchors_path)
# 获取类型数量和anchor数量变量
num_classes = len(classes)
num_anchors = len(anchors)

# ----------------------------------------------------------
# 读取标注数据
import numpy as np

# 训练集与验证集划分比例
val_split = 0.1
with open(annotation_path) as f:
    lines = f.readlines()
np.random.seed(10101)
np.random.shuffle(lines)
np.random.seed(None)
num_val = int(len(lines)*val_split)
num_train = len(lines) - num_val

# 数据读取函数,构建数据生成器。每次读取一个批次的数据至内存训练,并做数据增强。
def data_generator(annotation_lines, batch_size, input_shape, data_path,anchors, num_classes):
    n = len(annotation_lines)
    i = 0
    while True:
        image_data = []
        box_data = []
        for b in range(batch_size):
            if i==0:
                np.random.shuffle(annotation_lines)
            image, box = get_random_data(annotation_lines[i], input_shape, data_path,random=True) # 随机挑选一个批次的数据
            image_data.append(image)
            box_data.append(box)
            i = (i+1) % n
        image_data = np.array(image_data)
        box_data = np.array(box_data)
        y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes) # 对标注框预处理,过滤异常标注框
        yield [image_data, *y_true], np.zeros(batch_size)

def data_generator_wrapper(annotation_lines, batch_size, input_shape, data_path,anchors, num_classes):
    n = len(annotation_lines)
    if n==0 or batch_size<=0: return None
    return data_generator(annotation_lines, batch_size, input_shape, data_path,anchors, num_classes)


# ----------------------------------------------------------
# 模型训练:本案例使用Keras深度学习框架搭建YOLOv3神经网络。
import keras.backend as K
from yolo3.model import preprocess_true_boxes, yolo_body, yolo_loss
from keras.layers import Input, Lambda
from keras.models import Model
# 初始化session
K.clear_session()


# ----------------------------------------------------------
# 构建神经网络,可以在./yolo3/model.py文件中查看细节
#
# 图像输入尺寸
input_shape = (416, 416)
image_input = Input(shape=(None, None, 3))
h, w = input_shape
# 设置多尺度检测的下采样尺寸
y_true = [Input(shape=(h//{0:32, 1:16, 2:8}[l], w//{0:32, 1:16, 2:8}[l], num_anchors//3, num_classes+5)) 
          for l in range(3)]

# ----------------------------------------------------------
# 构建YOLO模型结构
# ----------------------------------------------------------
model_body = yolo_body(image_input, num_anchors//3, num_classes)

# 将YOLO权重文件加载进来,如果希望不加载预训练权重,从头开始训练的话,可以删除这句代码
model_body.load_weights(weights_path, by_name=True, skip_mismatch=True)

# 定义YOLO损失函数
model_loss = Lambda(yolo_loss, output_shape=(1,), name='yolo_loss',
    arguments={'anchors': anchors, 'num_classes': num_classes, 'ignore_thresh': 0.5})([*model_body.output, *y_true])

# 构建Model,为训练做准备
model = Model([model_body.input, *y_true], model_loss)

# 
# 打印模型各层结构
#
model.summary()

# -----------------------------------------------------------------
# 训练回调函数定义
# ----------------------------------------------------------
from keras.callbacks import ReduceLROnPlateau, EarlyStopping

# 定义回调方法
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, verbose=1) # 学习率衰减策略
early_stopping = EarlyStopping(monitor='val_loss', min_delta=0, patience=10, verbose=1) # 早停策略

# -----------------------------------------------------------------
# 开始训练
# ----------------------------------------------------------
from keras.optimizers import Adam
from yolo3.utils import get_random_data 

# 设置所有的层可训练
for i in range(len(model.layers)):
    model.layers[i].trainable = True
    
# 选择Adam优化器,设置学习率
learning_rate = 1e-4
model.compile(optimizer=Adam(lr=learning_rate), loss={'yolo_loss': lambda y_true, y_pred: y_pred}) 

# 设置批大小和训练轮数
batch_size = 16
max_epochs = 2
print('Train on {} samples, val on {} samples, with batch size {}.'.format(num_train, num_val, batch_size))
# 开始训练
model.fit_generator(data_generator_wrapper(lines[:num_train], batch_size, input_shape, data_path,anchors, num_classes),
    steps_per_epoch=max(1, num_train//batch_size),
    validation_data=data_generator_wrapper(lines[num_train:], batch_size, input_shape, data_path,anchors, num_classes),
    validation_steps=max(1, num_val//batch_size),
    epochs=max_epochs,
    initial_epoch=0,
    callbacks=[reduce_lr, early_stopping])

# ---------------------------------------------------------------
import os
os.makedirs(save_path)
# 保存模型
model.save_weights(os.path.join(save_path, 'trained_weights_final.h5'))

# ------------------------------------------------------------------
# 模型测试
# ------------------------------------------------------------------
from PIL import Image
import numpy as np
# 测试文件路径
test_file_path = './test.jpg'
# 打开测试文件
image = Image.open(test_file_path)
image_ori = np.array(image)
image_ori.shape

# -图片预处理-
from yolo3.utils import letterbox_image

new_image_size = (image.width - (image.width % 32), image.height - (image.height % 32))
boxed_image = letterbox_image(image, new_image_size)
image_data = np.array(boxed_image, dtype='float32')
image_data /= 255.
image_data = np.expand_dims(image_data, 0)
image_data.shape


import keras.backend as K
sess = K.get_session()

# ----------------------------------------------------------
# 构建模型
# ----------------------------------------------------------
from yolo3.model import yolo_body
from keras.layers import Input
# coco数据anchor值文件存储位置
anchor_path = "./model_data/yolo_anchors.txt"
with open(anchor_path) as f:
    anchors = f.readline()
anchors = [float(x) for x in anchors.split(',')]
anchors = np.array(anchors).reshape(-1, 2)
yolo_model = yolo_body(Input(shape=(None,None,3)), len(anchors)//3, num_classes)


# 模型权重存储路径,加载权重
weights_path = "./model_data/yolo.h5"
yolo_model.load_weights(weights_path)

# 定义IOU以及score:
# IOU: 将交并比大于IOU的边界框作为冗余框去除
# score:将预测分数大于score的边界框筛选出来
iou = 0.45
score = 0.8

# ----------------------------------------------------------
# 构建输出 [boxes, scores, classes]
# ----------------------------------------------------------
from yolo3.model import yolo_eval
input_image_shape = K.placeholder(shape=(2, ))
boxes, scores, classes = yolo_eval(
    yolo_model.output, 
    anchors,
    num_classes,
    input_image_shape,
    score_threshold=score, 
    iou_threshold=iou)

# ----------------------------------------------------------
# 进行预测
# ----------------------------------------------------------
out_boxes, out_scores, out_classes = sess.run(
    [boxes, scores, classes],
    feed_dict={
        yolo_model.input: image_data,
        input_image_shape: [image.size[1], image.size[0]],
        K.learning_phase(): 0
    })


class_coco = get_classes(classes_path)
out_coco = []
for i in out_classes:
    out_coco.append(class_coco[i])


print(out_boxes)
print(out_scores)
print(out_coco)

# ----------------------------------------------------------
# 将预测结果绘制在图片上
# ----------------------------------------------------------
from PIL import Image, ImageFont, ImageDraw

font = ImageFont.truetype(font='font/FiraMono-Medium.otf',
                    size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32'))

thickness = (image.size[0] + image.size[1]) // 300

for i, c in reversed(list(enumerate(out_coco))):
    predicted_class = c
    box = out_boxes[i]
    score = out_scores[i]

    label = '{} {:.2f}'.format(predicted_class, score)
    draw = ImageDraw.Draw(image)
    label_size = draw.textsize(label, font)

    top, left, bottom, right = box
    top = max(0, np.floor(top + 0.5).astype('int32'))
    left = max(0, np.floor(left + 0.5).astype('int32'))
    bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32'))
    right = min(image.size[0], np.floor(right + 0.5).astype('int32'))
    print(label, (left, top), (right, bottom))

    if top - label_size[1] >= 0:
        text_origin = np.array([left, top - label_size[1]])
    else:
        text_origin = np.array([left, top + 1])

    for i in range(thickness):
        draw.rectangle(
            [left + i, top + i, right - i, bottom - i],
            outline=225)
    draw.rectangle(
        [tuple(text_origin), tuple(text_origin + label_size)],
        fill=225)
    draw.text(text_origin, label, fill=(0, 0, 0), font=font)
    del draw

image
  • 备注1:本文相关数据在CSDN资源,欢迎查看。
  • 备注2:本次华为云AI项目赛事相关项目没有完全在本文写完,因为笔者认为,基本流程都是相似的,具体还是要用项目练手,练手资源华为云官方都准备好了,见:https://github.com/IamWWT/ModelArts-Lab
原创文章 6 获赞 2 访问量 485

猜你喜欢

转载自blog.csdn.net/wwt72/article/details/106101707