基于 PAI 平台的分割模型 Yolov8m-Seg 的在线训练与本地部署应用于缺陷检测

更新时间:

利用阿里云平台中 PAI 平台(原机器学习平台)对 Yolov8m-Seg 目标分割模型进行在线训练,通过制作数据集过程完成 VOC 格式数据集到 COCO 数据集转换,上传至阿里云 OSS 容器,完成在线训练,下载训练日志以及pt 模型文件,构建预测代码完成本地部署。

场景简介

利用阿里云平台中 PAI 平台(原机器学习平台)对 Yolov8m-Seg 目标分割模型进行在线训练,通过制作数据集过程完成 VOC 格式数据集到 COCO 数据集转换,上传至阿里云 OSS 容器,完成在线训练,下载训练日志以及pt 模型文件,构建预测代码完成本地部署。

背景知识

本实验需要理解 VOC 数据格式与 COCO 数据格式的异同,需要掌握 Python 语言,需要对深度学习训练过程与部署过程作一定了解。

实验室资源方式简介

进入实操前,请确保阿里云账号满足以下条件:

  • 个人账号资源

    • 使用您个人的云资源进行操作,资源归属于个人。

    • 平台仅提供手册参考,不会对资源做任何操作。

  • 确保已完成云工开物300元代金券领取。

  • 已通过实名认证且账户余额≥0元。

本场景主要涉及以下云产品和服务:人工智能平台 PAI 与对象容器 OSS

本实验,预计产生资源消耗:10.488元/小时,实验耗时预计<1小时。总计消耗<12元。

  • 算力需求资源: ecs.gn7i-c8g1.2xlarge

  • 规格:

    • GPU:1xA10

    • 显存:1x24GB

    • CPU:8vCPU

    • 内存:30GiB

如果您调整了资源规格、使用时长,或执行了本方案以外的操作,可能导致费用发生变化,请以控制台显示的实际价格和最终账单为准。

领取专属权益及开通授权

在开始实验之前,请先点击右侧屏幕的“进入实操”再进行后续操作

image

第一步:本次实验需要您通过领取阿里云云工开物学生专属300元抵扣券兑换本次实操的云资源,如未领取请先点击领取。(若已领取请跳过)

image

重要

实验产生的费用优先使用优惠券,优惠券使用完毕后需您自行承担。

学生认证

第二步:领取学生专属300元优惠券后,点击访问人工智能平台 PAI-点击“立即开通”,完成PAI平台开通与授权。

image

点击【立即开通】——【Model Gallery】——【YOLOv8m图像分割模型-中型】

image

实验步骤

  1. 确保完成安装 Pycharm 社区版编辑器

  2. 配置 Python 解释器路径,本实验要求的版本 Python>=3.8

  3. 确保本地已配置好 pytorch 深度学习推理框架

  4. 下载 VOC 格式的磁瓦缺陷数据集

    磁瓦数据集是中国科学院自动所一个课题组收集的数据集,是“Saliency of magnetic tile surface defects”这篇论文的数据集。收集了 6种常见磁瓦缺陷的图像,并做了语义分割的标注。

    官方地址(非VOC格式)

    image

  5. 检查 VOC格式的磁瓦缺陷数据集

    本地磁盘(E:)“中的搜索结果>VOCdevkit>VOC

    image

    • ImageSets:包含 txt 文件,用于存放数据集的划分信息,如训练集、验证集和测试集等。

    • JPEGImages:存放源图片,即用于训练和测试的图像文件。

    • SegmentationClass SegmentationObject:分别存放语义分割和实例分割相关的图片。

  6. 检查 PAI 平台中需求的数据集格式

    image

  7. 通过编写 Python 脚本代码完成数据集格式的转换

    参考代码:

    import os
    import cv2
    import numpy as np
    
    # 颜色到标签的映射(根据您提供的颜色标签)
    color_to_label = {
      (0, 0, 0): 0,
      (128, 0, 128): 1, 
      (0, 0, 128): 2, 
      (128, 0, 0): 3, 
      (0, 128, 0): 4, 
      (128, 128, 0): 5
    }
    
    def convert_to_yolo_segmentation(labels_image, height, width):
      """ 
      将分割标签图像转换为 YOLO segmentation 格式。
      """ 
      # 如果标签图像是灰度图,直接使用它作为标签图像
    if len(labels_image.shape) == 2:
      gray_image = labels_image # 如果是灰度图像
      # 将灰度图转换为 RGB 图像以便处理
      labels_image = cv2.cvtColor(labels_image, cv2.COLOR_GRAY2RGB)
    else:
    gray_image = cv2.cvtColor(labels_image, cv2.COLOR_RGB2GRAY)
    
      # 找到所有轮廓
    contours, _ = cv2.findContours(gray_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    yolo_annotations = []
    
    # 遍历每个轮廓区域
    for contour in contours:
      contour_points = contour.reshape(-1, 2) # 将轮廓点展平为二维数组
      normed_points = []
    
      # 获取每个轮廓的归一化坐标
      for point in contour_points:
      x, y = point
      normed_x = x / width
      normed_y = y / height
      normed_points.append(f"{normed_x} {normed_y}")
    
      # 使用轮廓的第一个像素点来确定标签
      first_pixel = tuple(labels_image[contour[0][0][1], contour[0][0][0]]) #获取第一个像素的 RGB 值
      label = color_to_label.get(first_pixel, -1) # 根据 RGB 颜色值获取标签
      
      # 如果找到了有效的标签(即标签不是-1),则将其添加到 annotations 中
      if label != -1:
        yolo_annotations.append(f"{label} " + " ".join(normed_points))
    
    return yolo_annotations
    
    
    def parse_segmentation_image(segmentation_image, file_name, split, output_path, height, width):
     """ 
     处理分割图像,提取 YOLO 格式标签并保存为文件。
     """ 
     # 读取标签图像
     segmentation = cv2.imread(segmentation_image)
    
     # 获取 YOLO 格式标签
    yolo_labels = convert_to_yolo_segmentation(segmentation, height, width)
    
    # 确保保存标签文件的目录存在
    label_file = os.path.join(output_path, 'labels', split, f"{file_name}.txt")
    label_dir = os.path.dirname(label_file) # 获取文件夹路径
    os.makedirs(label_dir, exist_ok=True) # 确保文件夹存在
    
     # 保存标签文件
    with open(label_file, 'w') as f:
      for label in yolo_labels:
        f.write(f"{label}\n")
    
    
    def process_data():
    """
    处理整个数据集,将每个图像和标签转换为 YOLO 格式。
    """ 
    # 假设的输入输出路径
    image_sets_dir = 'ImageSets/Segmentation'
    jpeg_images_dir = 'JPEGImages' 
    segmentation_class_dir = 'SegmentationClass'
    
    output_dir = 'output_yolo'
    os.makedirs(output_dir, exist_ok=True)
    os.makedirs(os.path.join(output_dir, 'images', 'train'), exist_ok=True)
    os.makedirs(os.path.join(output_dir, 'images', 'val'), exist_ok=True)
    os.makedirs(os.path.join(output_dir, 'labels', 'train'), exist_ok=True)
    os.makedirs(os.path.join(output_dir, 'labels', 'val'), exist_ok=True)
    
    # 设置图像的尺寸(高度和宽度)
    height, width = 512, 512 # 假设图像尺寸为 512x512
    
    # 读取 train.txt, val.txt 文件,选择训练集和验证集图像
    for split in ['train', 'val']:
      split_file = os.path.join(image_sets_dir, f'{split}.txt')
    
    with open(split_file, 'r') as f:
      image_names = f.read().splitlines()
    
      for image_name in image_names:
        # 获取对应的图像和标签文件
        image_file = os.path.join(jpeg_images_dir, f"{image_name}.jpg")
        segmentation_file = os.path.join(segmentation_class_dir, f"{image_name}.png")
      
        # 拷贝图像到新的目录
        output_image_file = os.path.join(output_dir, 'images', split, f"{image_name}.jpeg")
        # 读取图像
        image = cv2.imread(image_file)
        cv2.imwrite(output_image_file, image)
     
       # 处理分割标签并保存为 YOLO 格式
       parse_segmentation_image(segmentation_file, image_name, split, output _dir, height, width)
    
    
    if __name__ == '__main__':
    process_data()
  8. 完成格式转换后检查满足的格式,手动更改 dataset.yaml 文件,确保标签与代码段中 6-12 行中标签对齐(标签名可手动更改)

    image

    image

  9. 检查数据集无误后,开始上传数据集,在主界面中点击控制台,选择 OSS对象储存,点击 Bucket列表。

    image

  10. 点击创建 Bucket,urqwirqr为实例名称,名称不可重复,这一步代表Bucket创建成功。

    image

  11. 进入 Bucket,点击上传文件

    image

  12. yolo_output(格式转换后输出的文件夹)文件夹拖入上传区域即可,根据后续提示完成上传即可

    image

  13. 返回人工智能平台 PAI,选择数据集,在导入配置中选择上传的数据集 yolo_output,并新建 record文件夹作为后续的训练日志储存文件夹。

    image

    image

  14. 返回选择 model Gallery,选择图像分割,选择 YOLOv8M 中型,选择训练选项

    image

  15. 训练时长设定为 1 小时,训练数据集选择刚刚添加的数据集 yolo_output,模型输出选择为 record,资源配置如图所示。超参数配置如图所示。为了保证实验资源消耗在预估范围内,注意批次配置,时间配置,资源配置与图中达到一致。

    image

    image

  16. 开始训练

    image

  17. 完成训练后,在 record中找到训练日志

    image

  18. 在 weight 文件中找到 best.pt 文件作为权重文件,点击下载。需要注意,下载后的格式为 zip,请手动重命名为.pt 格式

    image

  19. 打开 Pycharm编辑器,创建项目,配置 python环境,将该 pt模型放置与 main主要预测代码同一目录下,main代码参考如下:

    from ultralytics import YOLO
    import os
    import cv2
    
    
    # 加载模型
    model = YOLO('best.pt')
    
    # 确保模型任务类型为 'segment' 
    if model.task != 'segment':
      raise ValueError("The model is not a segmentation model.")
    
    def predict_images_in_folder(model, input_folder, output_folder):
      # 获取文件夹中的所有图片文件
      for filename in os.listdir(input_folder):
        if filename.endswith(".jpg") or filename.endswith(".jpeg") or filename.endswith(".png"):
          img_path = os.path.join(input_folder, filename)
          output_path = os.path.join(output_folder, filename)
    
           # 读取图片
          img = cv2.imread(img_path)
    
           # 使用 model.predict 进行推理(分割任务)
          results = model.predict(img) # 对图像进行推理
    
           # 获取并保存带预测框的图像
          result_img = results[0].plot() # 获取带框的图像
          cv2.imwrite(output_path, result_img) # 保存带框的图像
          print(f"Processed {filename}, saved results to {output_path}")
    
          # 如果需要保存分割掩膜
    
    
    # 示例用法
    input_folder = "data/images/train"#待检测图像输入
    output_folder = "res"#检测后的输出文件夹路径
    
    predict_images_in_folder(model, input_folder, output_folder)
  20. 创建输出文件夹,运行代码,完成预测

    image

实验资源释放

在完成试验后,尤其注意释放掉训练资源,选择停止后进行删除操作,如完成训练,则直接进行删除操作,并在控制台中检查容器 OSS 是否释放以及资源配置是否释放。

image

关闭实验

  • 在完成实验后,点击 结束实操

    image

  • 点击 取消 回到实验页面,点击 确定 跳转实验评分

    image

  • 请为本次实验评分,并给出您的建议,点击 确认,结束本次实验

    image