我们已经准备好了,你呢?

2023我们与您携手共赢,为您的企业形象保驾护航!


喜讯:国内、香港、海外云服务器租用特惠活动,2核/4G/10M仅需31元每月,点击抢购>>>

点击这里点击这里申请百度智能云VIP帐号,立即体验BML>>>

百度智能云全功能AI开发平台BML-基于Notebook的通用模板使用指南

本文采用物体检测模型的开发过程为例,介绍通用模板从创建 Notebook 任务到引入数据、训练模型,再到保存模型、部署模型的全流程。

创建并启动Notebook

1、在 BML 左侧导航栏中点击『Notebook』

2、在 Notebook 页面点击『新建』,在弹出框中填写公司/个人信息以及项目信息,示例如下:

填写基础信息

image.png

填写项目信息

image.png

3、对 Notebook 任务操作入口中点击『配置』进行资源配置,示例如下:

选择开发语言、AI 框架,由于本次采用 PaddleClas 进行演示,所以需要选择 python3.7、PaddlePaddle2.0.0。选择资源规格,由于深度学习所需的训练资源一般较多,需要选择GPU V100的资源规格。

image.png

完成配置后点击『确认并启动』,即可启动 Notebook,启动过程中需要完成资源的申请以及实例创建,请耐心等待。

4、等待 Notebook 启动后,点击『打开』,页面跳转到 Notebook,即完成 Notebook 的创建与启动,示例如下:

image.png

训练物体检测模型

下载 PaddleDetection 套件

打开进入 Notebook,点击进入终端,输入如下命令切换到 /home/work/ 目录。

cd /home/work/

本文以 PaddleDetection 代码库 release/2.3 分支为例,输入如下命令克隆PaddleDetection代码库并切换至release/2.3分支。整个过程需要数十秒,请耐心等待。

# gitee 国内下载比较快git clone https://gitee.com/paddlepaddle/PaddleDetection.git -b release/2.3  
# github# git clone https://github.com/PaddlePaddle/PaddleDetection.git -b release/2.3

安装环境

在终端环境中,安装该版本的 PaddleDetection 代码包依赖的 paddlepaddle-gpu,执行如下命令:

python -m pip install paddlepaddle-gpu==2.1.3.post101 -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html

安装完成后,使用 python 或 python3 进入python解释器,输入 import paddle ,再输入 paddle.utils.run_check()

如果出现 PaddlePaddle is installed successfully!,说明成功安装。

准备训练数据

训练数据是模型生产的重要条件,优质的数据集可以很大程度上的提升模型训练效果,准备数据可以参考链接。本文所用的安全帽检测数据集可前往此链接进行下载:下载链接。

1、导入用户数据。

在 Notebook 中并不能直接访问您在 BML 中创建的数据集,需要通过左边选择栏的导入数据集选项,进行数据集导入。导入的数据位于用户目录的 data/ 文件夹(当原始数据集有更新时,不会自动同步,需要手工进行同步)。

image.png

注:若在BML中未创建数据集,请先参考 数据服务 ,创建、上传、标注数据集。

2、数据转换。

PaddleDetection 训练所需要的数据格式与 BML 默认的数据格式有所不同,所以需要利用脚本将导入的数据转为 PaddleDetection 支持的数据格式,并进行3:7切分。

PaddleDetection 默认支持的标注格式为 COCO格式,转换脚本如下:

import osimport cv2import jsonimport globimport codecsimport randomfrom pycocotools.coco import COCOdef parse_bml_json(json_file):
    """
    解析BML标注文件
    :return:
    """
    annos = json.loads(codecs.open(json_file).read())
    labels = annos['labels']
    bboxes = []
    for label in labels:
        x1 = label["x1"]
        y1 = label["y1"]
        x2 = label["x2"]
        y2 = label["y2"]
        id = label["name"]
        bboxes.append([x1, y1, x2, y2, id])
    return bboxesdef bbox_transform(box):
    """
    x1, y1, x2, y2 转为 x1, y1, width, height
    :return
    """
    box = list(map(lambda x: float(x), box))
    box[2] = box[2] - box[0]
    box[3] = box[3] - box[1]
    return boxdef parse_label_list(src_data_dir, save_dir):
    """
    遍历标注文件,获取label_list
    :return:
    """
    label_list = []
    anno_files = glob.glob(src_data_dir + "*.json")
    for anno_f in anno_files:
        annos = json.loads(codecs.open(anno_f).read())
        for lb in annos["labels"]:
            label_list.append(lb["name"])
    label_list = list(set(label_list))
    with codecs.open(os.path.join(save_dir, "label_list.txt"), 'w', encoding="utf-8") as f:
        for id, label in enumerate(label_list):
            f.writelines("%s:%s
" % (id, label))
    return len(label_list), label_listdef bml2coco(src_dir, coco_json_file):
    """
    BML标注格式转为COCO标注格式
    :return:
    """
    coco_images = []
    coco_annotations = []

    image_id = 0
    anno_id = 0
    image_list = glob.glob(src_dir + "*.[jJPpBb][PpNnMm]*")
    for image_file in image_list:
        anno_f = image_file.split(".")[0] + ".json"
        if not os.path.isfile(anno_f):
            continue
        bboxes = parse_bml_json(anno_f)
        im = cv2.imread(image_file)
        h, w, _ = im.shape
        image_i = {"file_name": os.path.basename(image_file), "id": image_id, "width": w, "height": h}
        coco_images.append(image_i)
        for id, bbox in enumerate(bboxes):
            # bbox : [x1, y1, x2, y2, label_name]
            anno_i = {"image_id": image_id, "bbox": bbox_transform(bbox[:4]), 'category_id': label_list.index(bbox[4]),
                      'id': anno_id, 'area': 1.1, 'iscrowd': 0, "segmentation": None}
            anno_id += 1
            coco_annotations.append(anno_i)

        image_id += 1

    coco_categories = [{"id": id, "name": label_name} for id, label_name in enumerate(label_list)]
    coco_dict = {"info": "info", "licenses": "BMLCloud", "images": coco_images, "annotations": coco_annotations,
                 "categories": coco_categories}
    with open(coco_json_file, 'w', encoding="utf-8") as fin:
        json.dump(coco_dict, fin, ensure_ascii=False)def split_det_origin_dataset(
        origin_file_path,
        train_file_path,
        eval_file_path,
        ratio=0.7):
    """
    按比例切分物体检测原始数据集
    :return:
    """
    coco = COCO(origin_file_path)
    img_ids = coco.getImgIds()
    items_num = len(img_ids)
    train_indexes, eval_indexes = random_split_indexes(items_num, ratio)
    train_items = [img_ids[i] for i in train_indexes]
    eval_items = [img_ids[i] for i in eval_indexes]

    dump_det_dataset(coco, train_items, train_file_path)
    dump_det_dataset(coco, eval_items, eval_file_path)

    return items_num, len(train_items), len(eval_items)def random_split_indexes(items_num, ratio=0.7):
    """
    按比例分割整个list的index
    :return:分割后的两个index子列表
    """
    offset = round(items_num * ratio)
    full_indexes = list(range(items_num))
    random.shuffle(full_indexes)
    sub_indexes_1 = full_indexes[:offset]
    sub_indexes_2 = full_indexes[offset:]

    return sub_indexes_1, sub_indexes_2def dump_det_dataset(coco, img_id_list, save_file_path):
    """
    物体检测数据集保存
    :return:
    """
    imgs = coco.loadImgs(img_id_list)
    img_anno_ids = coco.getAnnIds(imgIds=img_id_list, iscrowd=0)
    instances = coco.loadAnns(img_anno_ids)
    cat_ids = coco.getCatIds()
    categories = coco.loadCats(cat_ids)
    common_dict = {
        "info": coco.dataset["info"],
        "licenses": coco.dataset["licenses"],
        "categories": categories    }
    img_dict = {
        "image_nums": len(imgs),
        "images": imgs,
        "annotations": instances    }
    img_dict.update(common_dict)

    json_file = open(save_file_path, 'w', encoding='UTF-8')
    json.dump(img_dict, json_file)class_nums, label_list = parse_label_list("/home/work/data/${dataset_id}/", "/home/work/PretrainedModel/")bml2coco("/home/work/data/${dataset_id}/", "/home/work/PretrainedModel/org_data_list.json")split_det_origin_dataset("/home/work/PretrainedModel/org_data_list.json", "/home/work/PretrainedModel/train_data_list.json", "/home/work/PretrainedModel/eval_data_list.json")

将上述脚本存放为 coversion.py 代码脚本,并将脚本最后两行的 ${dataset_id} 替换为所指定数据集的 ID(下图红框中的ID),在终端中运行即可。

image.png

运行代码。

python coversion.py

注意:如果报错 No module named 'pycocotools',需要通过如下命令安装相关依赖包,再运行 coversion.py 代码。

pip install pycocotools

运行 coversion.py 代码成功之后将在 PretrainedModel/ 文件夹下生成对应的数据文件,包括 label_list.txttrain_data_list.jsoneval_data_list.jsonorg_data_list.json

image.png

训练模型

1、在终端中打开 PaddleDetection 目录。

cd /home/work/PaddleDetection

2、修改yaml配置文件。

在PaddleDetection 2.0后续版本,采用了模块解耦设计,用户可以组合配置模块实现检测器,并可自由修改覆盖各模块配置,本文以 configs/yolov3/yolov3_darknet53_270e_coco.yml 为例:

yolov3_darknet53_270e_coco.yml 主配置入口文件
coco_detection.yml 主要说明了训练数据和验证数据的路径
runtime.yml 主要说明了公共的运行参数,比如说是否使用GPU、每多少个epoch存储checkpoint等
optimizer_270e.yml 主要说明了学习率和优化器的配置。
yolov3_darknet53.yml 主要说明模型、和主干网络的情况。
yolov3_reader.yml 主要说明数据读取器配置,如batch size,并发加载子进程数等,同时包含读取后预处理操作,如resize、数据增强等等

需要修改/覆盖的参数均可写在主配置入口文件中,主要修改点为训练、验证数据集路径、运行epoch数、学习率等,修改后的主配置文件如下(注释行即为需要修改的点):

_BASE_: [
  '../datasets/coco_detection.yml',
  '../runtime.yml',
  '_base_/optimizer_270e.yml',
  '_base_/yolov3_darknet53.yml',
  '_base_/yolov3_reader.yml',]snapshot_epoch: 5weights: output/yolov3_darknet53_270e_coco/model_final# 预训练权重地址pretrain_weights: https://paddledet.bj.bcebos.com/models/yolov3_darknet53_270e_coco.pdparams# coco_detection.ymlnum_classes: 2 #实际类别数TrainDataset:
  !COCODataSet
    image_dir: data/${dataset_id}/   # 图片地址
    anno_path: PretrainedModel/train_data_list.json # 标注文件
    dataset_dir: /home/work/ # 数据集根目录
    data_fields: ['image', 'gt_bbox', 'gt_class', 'is_crowd']EvalDataset:
  !COCODataSet
    image_dir: data/${dataset_id}/   # 图片地址
    anno_path: PretrainedModel/eval_data_list.json   # 标注文件
    dataset_dir: /home/work/   # 数据集根目录# optimizer_270e.ymlepoch: 50 # 迭代轮数LearningRate:
  base_lr: 0.0001 # 学习率
  schedulers:
  - !PiecewiseDecay
    gamma: 0.1
    milestones:
    - 30
    - 45
  - !LinearWarmup
    start_factor: 0.
    steps: 400

3、训练模型。

推荐:TOP云智能建站优惠活动,仅880元即可搭建一个后台管理五端合一的智能网站(PC网站、手机网站、百度智能小程序、微信小程序、支付宝小程序),独享百度搜索SEO优势资源,让你的网站不仅有颜值有排面,更有排名,可以实实在在为您带来效益,请点击进入TOP云智能建站>>>,或咨询在线客服了解详情。



我们已经准备好了,你呢?

2023我们与您携手共赢,为您的企业形象保驾护航!

在线客服
联系方式

热线电话

131-3501-0006

上班时间

周一到周五

公司电话

130-0743-9476

二维码
线