【项目018】基于人像分割的背景替换 返回首页

作者:欧新宇(Xinyu OU)
当前版本:Release v1.0
开发平台:Paddle 2.3.2, PaddleSeg-release-2.4
运行环境:Intel Core i7-7700K CPU 4.2GHz, nVidia GeForce GTX 1080 Ti
本教案所涉及的数据集仅用于教学和交流使用,请勿用作商用。

最后更新:2022年4月10日


随着 COVID-19 大流行在全球肆虐,视频会议的需求激增。为此,实时人像分割成为代替会议参与者背景的流行功能。人像分割任务旨在识别图像中的人体轮廓,与背景进行分离,返回分割后的二值图、灰度图、前景人像图,适应多个人体、复杂背景、各类人体姿态,可应用于人像扣图、人体特效和影视后期处理等场景。背景移除是图像分割的典型应用之一,传统的背景移除通常借助于阈值分隔、边缘检测等计算机视觉技术进行实习,而基于深度学习的图像分割(Segmentation)技术常常和目标检测(Detection)共同完成。

【任务一】PaddleSeg环境的安装与调试

任务描述: 在安装有PaddlePaddle的计算机上完成PaddleSeg的安装和测试。
任务要求:

  1. 学会在安装好PaddlePaddle的Windows系统中安装PaddleSeg工具包;
  2. 能够解决PaddleSeg安装过程中遇到的各种问题;
  3. 能够通过测试判断PaddleSeg是否被正确安装。

1.1 PaddleSeg的下载

  1. 从官网下载PaddleSeg(当前最新版v2.4)https://github.com/PaddlePaddle/PaddleSeg
  2. 解压 PaddleSeg-release-2.4.zip 工具包到项目文件夹 MyProjects,建议直接使用带版本的文件夹命名方式 PaddleSeg-release-2.4(便于版本管理)。

1.2 PaddleSeg的安装

PaddleSeg的具体安装配置方法,请参考 【项目01】Python机器学习环境的安装和配置。 通常,PaddleSeg环境的安装只需要执行一次,确认服务器或本地环境已经具备相关依赖文件后,可跳过该步。

1. 将目录切换到: D:/WorkSpace/MyProjects/PaddleSeg-release-2.4 
>> pip install paddleseg
>> pip install -r requirements.txt

2. 所有安装的包都显示如下信息则表明安装成功: 
> Requirement already satisfied:...

注:安装过程中,若出现某个库安装失败,可手动进行安装,直至 requirements.txt 中的库都安装完毕。

1.3 PaddleSeg的测试

该测试实现模型的自动下载和测试图片的推理,推理结果保存在 output 文件夹中。

>> python predict.py --config configs/quick_start/bisenet_optic_disc_512x512_1k.yml --model_path https://bj.bcebos.com/paddleseg/dygraph/optic_disc/bisenet_optic_disc_512x512_1k/model.pdparams --image_path docs/images/optic_test_image.jpg --save_dir output/result

测试通过将出现如下提示:

...
  - type: Normalize
  type: OpticDiscSeg
------------------------------------------------
W0410 13:55:31.365703 20260 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 6.1, Driver API Version: 11.1, Runtime API Version: 10.2
W0410 13:55:31.366700 20260 device_context.cc:465] device: 0, cuDNN Version: 7.6.
2022-04-10 13:55:35 [INFO]      Number of predict images = 1
2022-04-10 13:55:35 [INFO]      Loading pretrained model from https://bj.bcebos.com/paddleseg/dygraph/optic_disc/bisenet_optic_disc_512x512_1k/model.pdparams
2022-04-10 13:55:35 [INFO]      There are 356/356 variables loaded into BiSeNetV2.
2022-04-10 13:55:35 [INFO]      Start to predict...
1/1 [==============================] - 0s 168ms/step

二、Windows工程环境的设置

任务描述: 在本地计算机中配置和部署好用于目标检测的相关文件夹和文件。

任务要求:

  1. 理解项目化部署的重要性;
  2. 能够根据需要完成必要文件夹的创建,并将相关文件保存到指定文件夹。

为了便于项目管理,本课程所有环境都按照统一规范进行设置,详细内容请参考 【项目002】Python机器学习环境的安装和配置。

如上图所示,我们在 PaddleDetecion-release-2.4 的根目录中可以看到多个不同功能的文件夹,其中 configs 保存了预制的多个经典模型,包括faster_rcnn, yolov3, ppyolo等;tools 文件夹中保存了PaddleDetection工具用于训练验证推理等功能的可执行文件。此外,我们需要在根目录下创建任务发布文件夹 contrib,并在该目录下创建任务文件夹 RoadSign 用于实现路标识别。在该目录下,我们再创建三个功能文件夹,分别为:

【任务三】数据准备

任务描述: 下载HumanSeg数据集,并按规范解压到指定目录,用于后续的训练、评估和预测。

任务要求:

  1. 下载HumanSeg数据集,并按规范解压到指定目录,用于后续的训练、评估和预测;
  2. 能够对图像样本和标注图像进行简单的可视化分析。

3.1 数据获取

本项目可使用两个数据集进行完成,其中HumanSeg数据集是由Supervisely发布,包含5711张高质量人像分割照片;此外,为了方便教学本项目使用PaddleSeg提供的简化版的人像分割数据集mini_supervisely,该数据集包含350副图像,其中训练、验证和测试数据分别为200, 100, 50。

3.2 数据标注生成

在图像分割任务中,最常用的图像标注文件包括两种,一种是使用json文件进行描述,另外一种是使用PNG索引图片,其中PNG索引图片对每个像素进行分类,并使用0-N的序号对像素类别进行描述。本项目所使用的数据标注方法是PNG索引图片,其中值为0表示背景,值为1表示person。下面给出一个标注内容的范例:

train.txt

Images/pexels-photo-267447.png Annotations/pexels-photo-267447.png
Images/pexels-photo-432506_0j2qo0nXL4.png Annotations/pexels-photo-432506_0j2qo0nXL4.png
Images/pexels-photo-881590.png Annotations/pexels-photo-881590.png
Images/pexels-photo-711938.png Annotations/pexels-photo-711938.png
Images/pexels-photo-192468.jpg Annotations/pexels-photo-192468.png
Images/pexels-photo-236953.jpg Annotations/pexels-photo-236953.png

3.3 数据图片及标注图片的可视化

import cv2
import matplotlib.pyplot as plt

# 设置各种路径
root_path = r'D:\Workspace\DeepLearning\WebsiteV2\Data\Projects\Project018HumanSegmentation'
img_name = 'Project1001_beauty-woman-flowered-hat-cap-53956'
img_path = os.path.join(root_path, img_name+'.jpg')
anno_path = os.path.join(root_path, img_name+'.png')

img = cv2.imread(img_path)
img_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
anno = cv2.imread(anno_path)
anno_GRAY = cv2.cvtColor(anno, cv2.COLOR_BGR2GRAY)  # 因为只有两种颜色,所以转换为二值图像

# 可视化
plt.figure(figsize=(18, 10))
ax0 = plt.subplot(1,2,1)
ax0.set_title('Images')
plt.imshow(img_RGB)
ax1 = plt.subplot(1,2,2)
ax1.set_title('Annotations')
plt.imshow(anno_GRAY)

<matplotlib.image.AxesImage at 0x1aa723967c0>

output_5_1

【任务四】人像分割模型快速体验

任务描述: 背景移除是网络中常见的应用,例如更换照片的背景色、视频聊天及视频会议中的背景替换等。任务三要求能根据不同的任务选择合适的模型,实现基本的背景移除应用。

任务要求:

  1. 学会使用训练好的模型对摄像头实现实时的背景移除及背景替换;
  2. 学会使用训练好的模型对视频进行背景移除及背景替换;
  3. 学会选择合适的模型对静态图片实现背景移除及背景替换。

4.1 模型介绍

本项目使用百度PaddleSeg提供的示例项目 PP-HumanSeg 完成相关任务,该项目提供四个预训练模型,分别用于服务器端、移动端、Web端的通用人像分割和Web端的肖像分割,介绍信息如下:

类别 模型名 模型简介/文件名 Input Size FLOPS Parameters 计算耗时 模型大小
人像分割 PP-HumanSeg-Server 高精度模型,适用于服务端GPU且背景复杂的场景, 模型结构为Deeplabv3+/ResNet50, 输入大小(512, 512)。deeplabv3p_resnet50_os8_humanseg_512x512_100k 512x512 114G 26.8M 37.96ms 103Mb
人像分割 PP-HumanSeg-Mobile 轻量级模型,适用于移动端或服务端CPU的前置摄像头场景,模型结构为HRNet_w18_samll_v1,输入大小(192, 192)。fcn_hrnetw18_small_v1_humanseg_192x192 192x192 584M 1.54M 13.17ms 5.9Mb
人像分割 PP-HumanSeg-Lite_generic 超轻量级模型,适用于Web端或移动端实时分割场景,例如手机自拍、Web视频会议,输入大小(192, 192)。pphumanseg_lite_generic_human_192x192 192x192 121M 137K 10.51ms 543Kb
肖像分割 PP-HumanSeg-Lite_portrait 超轻量级模型,适用于Web端或移动端实时分割场景,例如手机自拍、Web视频会议,模型结构为,推荐输入大小(398,224)。pphumanseg_lite_portrait_398x224 398x224 266M 137K 23.49ms 543Kb

4.2 测试数据及Inference模型下载

4.2.1 下载测试数据

在Anaconda命令提示行中,将工作路径切换至 PP-HumanSeg根目录 D:\WorkSpace\MyProjects\PaddleSeg-release-2.4\contrib\PP-HumanSeg,然后直接在Anaconda中运行下列的python语句,也可以在JupyterLab环境中执行下列语句。

python data/download_data.py

import os
workspace = 'D:\\Workspace\\MyProjects\\PaddleSeg-release-2.4\\contrib\\PP-HumanSeg'
os.chdir(workspace)

!python data/download_data.py

下载好的示例数据集 mini_supervisely 将自动保存在 D:\WorkSpace\MyProjects\PaddleSeg-release-2.4\contrib\PP-HumanSeg\data\mini_supervisely 中。

4.2.2 下载Inference模型

Infernce是已经训练好的用于人像分割的推理模型,高性能DeepLabv3模型有104M,轻量级的pphumanseg_lite只有543k。下面我们先将这些模型下载到 export_model 文件夹中,以供后续处理。

>> python export_model/download_export_model.py

import os
workspace = 'D:\\Workspace\\MyProjects\\PaddleSeg-release-2.4\\contrib\\PP-HumanSeg'
os.chdir(workspace)

!python export_model/download_export_model.py

Export model download success!

4.3 使用Inference模型进行背景移除

使用Inference模型,我们可实现对图片和视频的背景移除以及背景替换等功能,也可以实现对摄像头采集的视频进行实时背景处理。不难发现以上所有的应用,归根到底都是对图像中的人像进行图像分割,然后根据分割结果进行后续处理。其中视频对象相当于多帧图像的融合。

下面我们使用PaddleSeg内置的 bg_replace.py 实现背景移除和替换,以下给出相关参数的解释:

--video_path--img_path 均没有参数,则调用摄像头进行图像采集。

下面,我们先将工作目录切换到 PP-HumanSeg

import os
workspace = 'D:\\Workspace\\MyProjects\\PaddleSeg-release-2.4\\contrib\\PP-HumanSeg'
os.chdir(workspace)

4.3.1 通过摄像头进行实时分割处理

实时系统要求模型的推理速度能够基本满足人对视频的帧数FPS(通常不低于25FPS,最好能达到60FPS)的要求,否则就会产生卡顿,因此对于实时系统需要重点权衡速度与性能之间的平衡。在本例中,我们使用超轻量级模型 pphumanseg_lite_portrait_398x224 实现基于人像的分割的背景替换应用。在融合光流信息之后,分割结果有细微的提升。(本例中的视频因分辨率较低,因此视觉上变化不大)

!python bg_replace.py \
    --config export_model/pphumanseg_lite_portrait_398x224_with_softmax/deploy.yaml
!python bg_replace.py \
    --config export_model/pphumanseg_lite_portrait_398x224_with_softmax/deploy.yaml \
    --input_shape 224 398 \
    --bg_img_path data/background.jpg
!python bg_replace.py \
    --config export_model/pphumanseg_lite_portrait_398x224_with_softmax/deploy.yaml \
    --input_shape 224 398 \
    --bg_img_path data/background.jpg \
    --use_optic_flow
原始视频 背景移除 背景替换 背景替换(光流)

从上面的实验结果不难发现,背景替换的质量由背景移除的质量决定。这说明,前景和背景融合在背景替换中影响不大,但图像分割的质量却影响较大。此外,光流特征在本例中并没有起到明显作用。

4.3.2 对人像视频进行分割

对于实时性要求不高的离线视频推理应用,我们可以考虑使用类似deeplabev3的高性能模型,以获得更好的性能。本项目中,光流特征同样对图像分割只有细微的性能提升。

Note: 使用高性能模型进行分割时,根据系统性能的不同,可能需要几分钟时间,请耐心等待。使用GPU可以有效提高解析速度。

!python bg_replace.py \
    --config export_model/deeplabv3p_resnet50_os8_humanseg_512x512_100k_with_softmax/deploy.yaml \
    --video_path data/video_test.mp4
!python bg_replace.py \
    --config export_model/deeplabv3p_resnet50_os8_humanseg_512x512_100k_with_softmax/deploy.yaml \
    --video_path data/video_test.mp4 \
    --bg_img_path data/background.jpg
!python bg_replace.py \
    --config export_model/deeplabv3p_resnet50_os8_humanseg_512x512_100k_with_softmax/deploy.yaml \
    --video_path data/video_test.mp4 \
    --bg_img_path data/background.jpg \
    --use_optic_flow
原始视频 背景移除 背景替换 背景替换(光流)

相比摄像头,基于视频的图像移除清晰度更好一些。

4.3.3 对单张图片进行分割

下面我们使用四种不同的模型对图片进行分割处理,不难发现性能更好的模型(DeepLabv3+)可以获得更好的推理结果,但同样也需要更长的推理时间。使用性能较好的模型对于提高分割精度有重要意义,适合一些离线应用;而使用效率较高的模型有利于提高推理速度,适合一些实时性要求较高的应用。

!python bg_replace.py \
    --config export_model/pphumanseg_lite_portrait_398x224_with_softmax/deploy.yaml \
    --input_shape 224 398 \
    --img_path data/IMG_20210124_110337.jpg
!python bg_replace.py \
    --config export_model/fcn_hrnetw18_small_v1_humanseg_192x192_with_softmax/deploy.yaml \
    --input_shape 224 398 \
    --img_path data/IMG_20210124_110337.jpg \
    --bg_img_path data/background.jpg

下面我们使用同一副图像实现多种不同背景的替换,该任务类似于证件照的背景替换。

!python bg_replace.py \
    --config export_model/deeplabv3p_resnet50_os8_humanseg_512x512_100k_with_softmax/deploy.yaml \
    --input_shape 413 626 \
    --img_path data/photo.png \
    --bg_img_path data/background_scene.png

【任务五】模型训练

任务描述: 背景移除是网络中常见的应用,例如更换照片的背景色、视频聊天及视频会议中的背景替换等。任务三要求能根据不同的任务选择合适的模型,实现基本的背景移除应用。

任务要求:

  1. 学会使用训练好的模型对摄像头实现实时的背景移除及背景替换;
  2. 学会使用训练好的模型对视频进行背景移除及背景替换;
  3. 学会选择合适的模型对静态图片实现背景移除及背景替换。

模型训练一般分为两种方式,一种是使用原始图像数据直接从头开始训练,即使用随机初始化的方式初始化化权重参数,然后从随机噪声开始进行训练;另外一种是使用迁移学习的方式从一个已经训练好的预训练模型开始训练,即从预训练好的参数开始进行训练。为了简化训练过程,本项目使用后者从一个已经训练好的预训练模型开始训练。此外,本项目完全使用PaddleSeg接口进行训练、评估和预测。

模型训练可以使用大规模数据进行从头训练(train from scatch),也可以使用现有数据进行微调训练(Fine-tuning),以适配特殊场景的应用。

5.1 预训练模型下载

下列代码可以实现预训练模型的下载,下载前同样需要先将工作目录切换到 D:\WorkSpace\MyProjects\PaddleSeg-release-2.4\contrib\PP-HumanSeg

>> python pretrained_model/download_pretrained_model.py

5.2 模型训练

在本项目中,我们使用抽取的 mini_supervisely 数据集进行训练,并使用 fcn_hrnetw18_small_v1_humanseg 模型进行训练。

Note:因训练时间较长,因此建议使用Anaconda命令提示行执行下列训练代码。

python train.py \
--config configs/fcn_hrnetw18_small_v1_humanseg_192x192_mini_supervisely.yml \
--save_dir saved_model/fcn_hrnetw18_small_v1_humanseg_192x192_mini_supervisely \
--save_interval 100 
--do_eval

以上命令中,
train.py 是主程序;
--config 定义yml配置文件;
--save_dir 定义结果输出路径;
--save_interval 定义结果保存的间隔时间,此处表示100次iter保存一次,同时完成一次验证;
--do_eval 表示训练的过程中启用验证测试,测试间隔由 --save_interval 进行定义。

下面给出训练过程中的日志文件。

【训练日志】

(base) D:\WorkSpace\MyProjects\PaddleSeg-release-2.4\contrib\PP-HumanSeg>python train.py --config configs/fcn_hrnetw18_small_v1_humanseg_192x192_mini_supervisely.yml --save_dir saved_model/fcn_hrnetw18_small_v1_humanseg_192x192_mini_supervisely --save_interval 100 --do_eval
C:\Users\Administrator\anaconda3\lib\site-packages\paddleseg-2.4.0-py3.9.egg\paddleseg\models\losses\rmi_loss.py:73: DeprecationWarning: invalid escape sequence \i
C:\Users\Administrator\anaconda3\lib\site-packages\paddleseg-2.4.0-py3.9.egg\paddleseg\models\losses\rmi_loss.py:73: DeprecationWarning: invalid escape sequence \i
'C:\Program' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
2022-02-15 20:13:14 [INFO]
------------Environment Information-------------
platform: Windows-10-10.0.22000-SP0
Python: 3.9.7 (default, Sep 16 2021, 16:59:28) [MSC v.1916 64 bit (AMD64)]
Paddle compiled with cuda: True
NVCC: Not Available
cudnn: 7.6
GPUs used: 1
CUDA_VISIBLE_DEVICES: None
GPU:  Can not get GPU information. Please make sure CUDA have been installed successfully.
PaddleSeg: 2.4.0
PaddlePaddle: 2.2.1
OpenCV: 4.5.5
------------------------------------------------
2022-02-15 20:13:14 [INFO]
---------------Config Information---------------
batch_size: 64                         # batch_size,上限是GPU的显存容量决定
export:
  transforms:    
  - target_size:                       # 输入尺度192×192
    - 192
    - 192
    type: Resize                 
  - type: Normalize
iters: 500                             # 训练迭代次数 500
loss:                                  ### 损失函数设置
  coef:
  - 1
  types:
  - ignore_index: 255
    type: CrossEntropyLoss             # 损失函数为交叉熵Loss
lr_scheduler:                          #### 学习率设置
  end_lr: 0
  learning_rate: 0.05                  # 初始学习率 0.05
  power: 0.9
  type: PolynomialDecay                # 多项式衰减
model:                                 ### 网络模型的设置
  backbone:                            # 骨干网络
    align_corners: false
    type: HRNet_W18_Small_V1
  backbone_indices:
  - -1
  num_classes: 2                       # 类别数量
  pretrained: pretrained_model/fcn_hrnetw18_small_v1_humanseg_192x192/model.pdparams      # 预训练模型
  type: FCN
optimizer:                             ### 优化方法
  momentum: 0.9                        # 动量0.9
  type: sgd                            # 随机梯度下降
  weight_decay: 0.0005
train_dataset:                         ### 训练数据设置
  dataset_root: data/mini_supervisely           # 训练集路径
  mode: train                                   # 模式为训练数据
  num_classes: 2                                # 类别数
  train_path: data/mini_supervisely/train.txt   # 训练集标注文件列表
  transforms:
  - target_size:                     # 尺度压缩
    - 192
    - 192
    type: Resize
  - type: RandomHorizontalFlip       # 随机水平翻转
  - brightness_range: 0.4            # 亮度增广
    contrast_range: 0.4              # 对比度增广
    saturation_range: 0.4            # 饱和度增广
    type: RandomDistort              # 色彩整体随机扰动
  - type: Normalize                  # 标准化,包括减均值和方差归一
  type: Dataset
val_dataset:                         ### 验证数据设置
  dataset_root: data/mini_supervisely
  mode: val
  num_classes: 2
  transforms:
  - target_size:
    - 192
    - 192
    type: Resize
  - type: Normalize
  type: Dataset
  val_path: data/mini_supervisely/val.txt
------------------------------------------------
W0215 20:13:14.612237 10728 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 6.1, Driver API Version: 11.1, Runtime API Version: 10.2
W0215 20:13:14.612237 10728 device_context.cc:465] device: 0, cuDNN Version: 7.6.
2022-02-15 20:13:16 [INFO]      Loading pretrained model from pretrained_model/fcn_hrnetw18_small_v1_humanseg_192x192/model.pdparams
2022-02-15 20:13:16 [INFO]      There are 363/363 variables loaded into FCN.
C:\Users\Administrator\anaconda3\lib\site-packages\paddle\nn\layer\norm.py:652: UserWarning: When training, we now always track global mean and variance.
  warnings.warn(
C:\Users\Administrator\anaconda3\lib\site-packages\paddle\fluid\dygraph\math_op_patch.py:251: UserWarning: The dtype of left and right variables are not the same, left dtype is paddle.float32, but right dtype is paddle.int64, the right dtype will convert to paddle.float32
  warnings.warn(
2022-02-15 20:13:35 [INFO]      [TRAIN] epoch: 4, iter: 10/500, loss: 0.5623, lr: 0.049189, batch_cost: 1.8988, reader_cost: 1.72034, ips: 33.7052 samples/sec | ETA 00:15:30
2022-02-15 20:13:54 [INFO]      [TRAIN] epoch: 7, iter: 20/500, loss: 0.4708, lr: 0.048287, batch_cost: 1.8953, reader_cost: 1.73715, ips: 33.7673 samples/sec | ETA 00:15:09
2022-02-15 20:14:13 [INFO]      [TRAIN] epoch: 10, iter: 30/500, loss: 0.4386, lr: 0.047382, batch_cost: 1.9179, reader_cost: 1.75450, ips: 33.3696 samples/sec | ETA 00:15:01
2022-02-15 20:14:32 [INFO]      [TRAIN] epoch: 14, iter: 40/500, loss: 0.4230, lr: 0.046476, batch_cost: 1.8923, reader_cost: 1.73546, ips: 33.8206 samples/sec | ETA 00:14:30
2022-02-15 20:14:51 [INFO]      [TRAIN] epoch: 17, iter: 50/500, loss: 0.4060, lr: 0.045568, batch_cost: 1.9085, reader_cost: 1.75086, ips: 33.5334 samples/sec | ETA 00:14:18
2022-02-15 20:15:10 [INFO]      [TRAIN] epoch: 20, iter: 60/500, loss: 0.4004, lr: 0.044657, batch_cost: 1.8745, reader_cost: 1.71810, ips: 34.1419 samples/sec | ETA 00:13:44
2022-02-15 20:15:28 [INFO]      [TRAIN] epoch: 24, iter: 70/500, loss: 0.3876, lr: 0.043745, batch_cost: 1.8318, reader_cost: 1.68425, ips: 34.9391 samples/sec | ETA 00:13:07
2022-02-15 20:15:46 [INFO]      [TRAIN] epoch: 27, iter: 80/500, loss: 0.3683, lr: 0.042830, batch_cost: 1.8033, reader_cost: 1.65953, ips: 35.4906 samples/sec | ETA 00:12:37
2022-02-15 20:16:04 [INFO]      [TRAIN] epoch: 30, iter: 90/500, loss: 0.3538, lr: 0.041914, batch_cost: 1.7758, reader_cost: 1.63214, ips: 36.0410 samples/sec | ETA 00:12:08
2022-02-15 20:16:22 [INFO]      [TRAIN] epoch: 34, iter: 100/500, loss: 0.3401, lr: 0.040995, batch_cost: 1.8177, reader_cost: 1.67334, ips: 35.2093 samples/sec | ETA 00:12:07
2022-02-15 20:16:22 [INFO]      Start evaluating (total_samples: 100, total_iters: 100)...
100/100 [==============================] - 4s 41ms/step - batch_cost: 0.0406 - reader cost: 3.3913e-04
2022-02-15 20:16:26 [INFO]      [EVAL] #Images: 100 mIoU: 0.6023 Acc: 0.8110 Kappa: 0.4765 Dice: 0.7361
2022-02-15 20:16:26 [INFO]      [EVAL] Class IoU:
[0.7805 0.4241]
2022-02-15 20:16:26 [INFO]      [EVAL] Class Acc:
[0.8354 0.711 ]
2022-02-15 20:16:26 [INFO]      [EVAL] The model with the best validation mIoU (0.6023) was saved at iter 100.
2022-02-15 20:16:41 [INFO]      [TRAIN] epoch: 37, iter: 110/500, loss: 0.3458, lr: 0.040073, batch_cost: 1.4977, reader_cost: 1.34890, ips: 42.7322 samples/sec | ETA 00:09:44
2022-02-15 20:17:00 [INFO]      [TRAIN] epoch: 40, iter: 120/500, loss: 0.3169, lr: 0.039150, batch_cost: 1.8215, reader_cost: 1.67773, ips: 35.1361 samples/sec | ETA 00:11:32
2022-02-15 20:17:18 [INFO]      [TRAIN] epoch: 44, iter: 130/500, loss: 0.3198, lr: 0.038224, batch_cost: 1.7905, reader_cost: 1.64580, ips: 35.7439 samples/sec | ETA 00:11:02
2022-02-15 20:17:36 [INFO]      [TRAIN] epoch: 47, iter: 140/500, loss: 0.2933, lr: 0.037295, batch_cost: 1.8131, reader_cost: 1.67005, ips: 35.2984 samples/sec | ETA 00:10:52
2022-02-15 20:17:53 [INFO]      [TRAIN] epoch: 50, iter: 150/500, loss: 0.2815, lr: 0.036364, batch_cost: 1.7673, reader_cost: 1.62326, ips: 36.2139 samples/sec | ETA 00:10:18
2022-02-15 20:18:11 [INFO]      [TRAIN] epoch: 54, iter: 160/500, loss: 0.2669, lr: 0.035430, batch_cost: 1.7860, reader_cost: 1.63987, ips: 35.8346 samples/sec | ETA 00:10:07
2022-02-15 20:18:30 [INFO]      [TRAIN] epoch: 57, iter: 170/500, loss: 0.2656, lr: 0.034494, batch_cost: 1.8550, reader_cost: 1.71074, ips: 34.5005 samples/sec | ETA 00:10:12
2022-02-15 20:18:48 [INFO]      [TRAIN] epoch: 60, iter: 180/500, loss: 0.2601, lr: 0.033555, batch_cost: 1.7844, reader_cost: 1.64102, ips: 35.8658 samples/sec | ETA 00:09:31
2022-02-15 20:19:06 [INFO]      [TRAIN] epoch: 64, iter: 190/500, loss: 0.2570, lr: 0.032612, batch_cost: 1.8160, reader_cost: 1.67125, ips: 35.2431 samples/sec | ETA 00:09:22
2022-02-15 20:19:24 [INFO]      [TRAIN] epoch: 67, iter: 200/500, loss: 0.2318, lr: 0.031667, batch_cost: 1.7819, reader_cost: 1.63583, ips: 35.9159 samples/sec | ETA 00:08:54
2022-02-15 20:19:24 [INFO]      Start evaluating (total_samples: 100, total_iters: 100)...
100/100 [==============================] - 4s 38ms/step - batch_cost: 0.0378 - reader cost: 3.8898e-04
2022-02-15 20:19:27 [INFO]      [EVAL] #Images: 100 mIoU: 0.6241 Acc: 0.8192 Kappa: 0.5141 Dice: 0.7562
2022-02-15 20:19:27 [INFO]      [EVAL] Class IoU:
[0.786  0.4621]
2022-02-15 20:19:27 [INFO]      [EVAL] Class Acc:
[0.851  0.7065]
2022-02-15 20:19:27 [INFO]      [EVAL] The model with the best validation mIoU (0.6241) was saved at iter 200.
2022-02-15 20:19:44 [INFO]      [TRAIN] epoch: 70, iter: 210/500, loss: 0.2099, lr: 0.030719, batch_cost: 1.6874, reader_cost: 1.53885, ips: 37.9271 samples/sec | ETA 00:08:09
2022-02-15 20:20:02 [INFO]      [TRAIN] epoch: 74, iter: 220/500, loss: 0.2085, lr: 0.029767, batch_cost: 1.8058, reader_cost: 1.65917, ips: 35.4418 samples/sec | ETA 00:08:25
2022-02-15 20:20:20 [INFO]      [TRAIN] epoch: 77, iter: 230/500, loss: 0.2031, lr: 0.028812, batch_cost: 1.7921, reader_cost: 1.64761, ips: 35.7118 samples/sec | ETA 00:08:03
2022-02-15 20:20:38 [INFO]      [TRAIN] epoch: 80, iter: 240/500, loss: 0.1844, lr: 0.027853, batch_cost: 1.8083, reader_cost: 1.66515, ips: 35.3930 samples/sec | ETA 00:07:50
2022-02-15 20:20:57 [INFO]      [TRAIN] epoch: 84, iter: 250/500, loss: 0.1755, lr: 0.026891, batch_cost: 1.8231, reader_cost: 1.67713, ips: 35.1052 samples/sec | ETA 00:07:35
2022-02-15 20:21:15 [INFO]      [TRAIN] epoch: 87, iter: 260/500, loss: 0.1712, lr: 0.025925, batch_cost: 1.8124, reader_cost: 1.66894, ips: 35.3131 samples/sec | ETA 00:07:14
2022-02-15 20:21:33 [INFO]      [TRAIN] epoch: 90, iter: 270/500, loss: 0.1666, lr: 0.024954, batch_cost: 1.7871, reader_cost: 1.64311, ips: 35.8117 samples/sec | ETA 00:06:51
2022-02-15 20:21:51 [INFO]      [TRAIN] epoch: 94, iter: 280/500, loss: 0.1655, lr: 0.023980, batch_cost: 1.7951, reader_cost: 1.65169, ips: 35.6524 samples/sec | ETA 00:06:34
2022-02-15 20:22:09 [INFO]      [TRAIN] epoch: 97, iter: 290/500, loss: 0.1455, lr: 0.023001, batch_cost: 1.8132, reader_cost: 1.67104, ips: 35.2976 samples/sec | ETA 00:06:20
2022-02-15 20:22:27 [INFO]      [TRAIN] epoch: 100, iter: 300/500, loss: 0.1427, lr: 0.022018, batch_cost: 1.7934, reader_cost: 1.64881, ips: 35.6860 samples/sec | ETA 00:05:58
2022-02-15 20:22:27 [INFO]      Start evaluating (total_samples: 100, total_iters: 100)...
100/100 [==============================] - 3s 35ms/step - batch_cost: 0.0344 - reader cost: 2.7925e-04
2022-02-15 20:22:30 [INFO]      [EVAL] #Images: 100 mIoU: 0.6589 Acc: 0.8311 Kappa: 0.5730 Dice: 0.7865
2022-02-15 20:22:30 [INFO]      [EVAL] Class IoU:
[0.7923 0.5254]
2022-02-15 20:22:30 [INFO]      [EVAL] Class Acc:
[0.8839 0.6893]
2022-02-15 20:22:30 [INFO]      [EVAL] The model with the best validation mIoU (0.6589) was saved at iter 300.
2022-02-15 20:22:49 [INFO]      [TRAIN] epoch: 104, iter: 310/500, loss: 0.1407, lr: 0.021029, batch_cost: 1.8537, reader_cost: 1.70215, ips: 34.5247 samples/sec | ETA 00:05:52
2022-02-15 20:23:07 [INFO]      [TRAIN] epoch: 107, iter: 320/500, loss: 0.1364, lr: 0.020036, batch_cost: 1.7917, reader_cost: 1.64646, ips: 35.7208 samples/sec | ETA 00:05:22
2022-02-15 20:23:25 [INFO]      [TRAIN] epoch: 110, iter: 330/500, loss: 0.1319, lr: 0.019037, batch_cost: 1.8111, reader_cost: 1.66874, ips: 35.3384 samples/sec | ETA 00:05:07
2022-02-15 20:23:43 [INFO]      [TRAIN] epoch: 114, iter: 340/500, loss: 0.1317, lr: 0.018032, batch_cost: 1.7873, reader_cost: 1.64232, ips: 35.8085 samples/sec | ETA 00:04:45
2022-02-15 20:24:00 [INFO]      [TRAIN] epoch: 117, iter: 350/500, loss: 0.1246, lr: 0.017021, batch_cost: 1.7792, reader_cost: 1.63533, ips: 35.9703 samples/sec | ETA 00:04:26
2022-02-15 20:24:19 [INFO]      [TRAIN] epoch: 120, iter: 360/500, loss: 0.1176, lr: 0.016003, batch_cost: 1.8203, reader_cost: 1.67713, ips: 35.1582 samples/sec | ETA 00:04:14
2022-02-15 20:24:37 [INFO]      [TRAIN] epoch: 124, iter: 370/500, loss: 0.1135, lr: 0.014978, batch_cost: 1.8279, reader_cost: 1.68460, ips: 35.0126 samples/sec | ETA 00:03:57
2022-02-15 20:24:55 [INFO]      [TRAIN] epoch: 127, iter: 380/500, loss: 0.1120, lr: 0.013945, batch_cost: 1.8056, reader_cost: 1.65937, ips: 35.4456 samples/sec | ETA 00:03:36
2022-02-15 20:25:13 [INFO]      [TRAIN] epoch: 130, iter: 390/500, loss: 0.1069, lr: 0.012903, batch_cost: 1.7879, reader_cost: 1.64336, ips: 35.7967 samples/sec | ETA 00:03:16
2022-02-15 20:25:31 [INFO]      [TRAIN] epoch: 134, iter: 400/500, loss: 0.1040, lr: 0.011852, batch_cost: 1.7871, reader_cost: 1.64281, ips: 35.8117 samples/sec | ETA 00:02:58
2022-02-15 20:25:31 [INFO]      Start evaluating (total_samples: 100, total_iters: 100)...
100/100 [==============================] - 4s 42ms/step - batch_cost: 0.0421 - reader cost: 2.8919e-04
2022-02-15 20:25:35 [INFO]      [EVAL] #Images: 100 mIoU: 0.6543 Acc: 0.8364 Kappa: 0.5634 Dice: 0.7811
2022-02-15 20:25:35 [INFO]      [EVAL] Class IoU:
[0.8036 0.5049]
2022-02-15 20:25:35 [INFO]      [EVAL] Class Acc:
[0.8648 0.739 ]
2022-02-15 20:25:35 [INFO]      [EVAL] The model with the best validation mIoU (0.6589) was saved at iter 300.
2022-02-15 20:25:50 [INFO]      [TRAIN] epoch: 137, iter: 410/500, loss: 0.0988, lr: 0.010790, batch_cost: 1.5133, reader_cost: 1.36436, ips: 42.2913 samples/sec | ETA 00:02:16
2022-02-15 20:26:08 [INFO]      [TRAIN] epoch: 140, iter: 420/500, loss: 0.0994, lr: 0.009717, batch_cost: 1.8063, reader_cost: 1.66226, ips: 35.4321 samples/sec | ETA 00:02:24
2022-02-15 20:26:26 [INFO]      [TRAIN] epoch: 144, iter: 430/500, loss: 0.0985, lr: 0.008630, batch_cost: 1.8223, reader_cost: 1.67618, ips: 35.1206 samples/sec | ETA 00:02:07
2022-02-15 20:26:44 [INFO]      [TRAIN] epoch: 147, iter: 440/500, loss: 0.0978, lr: 0.007528, batch_cost: 1.7958, reader_cost: 1.65318, ips: 35.6387 samples/sec | ETA 00:01:47
2022-02-15 20:27:02 [INFO]      [TRAIN] epoch: 150, iter: 450/500, loss: 0.0932, lr: 0.006408, batch_cost: 1.7956, reader_cost: 1.65125, ips: 35.6424 samples/sec | ETA 00:01:29
2022-02-15 20:27:20 [INFO]      [TRAIN] epoch: 154, iter: 460/500, loss: 0.0913, lr: 0.005265, batch_cost: 1.8022, reader_cost: 1.65927, ips: 35.5125 samples/sec | ETA 00:01:12
2022-02-15 20:27:38 [INFO]      [TRAIN] epoch: 157, iter: 470/500, loss: 0.0920, lr: 0.004094, batch_cost: 1.7864, reader_cost: 1.64123, ips: 35.8255 samples/sec | ETA 00:00:53
2022-02-15 20:27:56 [INFO]      [TRAIN] epoch: 160, iter: 480/500, loss: 0.0916, lr: 0.002883, batch_cost: 1.8071, reader_cost: 1.66296, ips: 35.4164 samples/sec | ETA 00:00:36
2022-02-15 20:28:14 [INFO]      [TRAIN] epoch: 164, iter: 490/500, loss: 0.0885, lr: 0.001611, batch_cost: 1.7796, reader_cost: 1.63733, ips: 35.9622 samples/sec | ETA 00:00:17
2022-02-15 20:28:32 [INFO]      [TRAIN] epoch: 167, iter: 500/500, loss: 0.0896, lr: 0.000186, batch_cost: 1.7976, reader_cost: 1.65374, ips: 35.6039 samples/sec | ETA 00:00:00
2022-02-15 20:28:32 [INFO]      Start evaluating (total_samples: 100, total_iters: 100)...
100/100 [==============================] - 4s 38ms/step - batch_cost: 0.0379 - reader cost: 3.4906e-04
2022-02-15 20:28:36 [INFO]      [EVAL] #Images: 100 mIoU: 0.6576 Acc: 0.8318 Kappa: 0.5705 Dice: 0.7852
2022-02-15 20:28:36 [INFO]      [EVAL] Class IoU:
[0.794  0.5212]
2022-02-15 20:28:36 [INFO]      [EVAL] Class Acc:
[0.8801 0.6963]
2022-02-15 20:28:36 [INFO]      [EVAL] The model with the best validation mIoU (0.6589) was saved at iter 300.
<class 'paddle.nn.layer.conv.Conv2D'>'s flops has been counted
<class 'paddle.nn.layer.norm.BatchNorm2D'>'s flops has been counted
<class 'paddle.nn.layer.activation.ReLU'>'s flops has been counted
Cannot find suitable count function for <class 'paddleseg.models.layers.wrap_functions.Add'>. Treat it as zero FLOPs.
Total Flops: 584182656     Total Params: 1543954

【任务六】模型评估

任务描述: 使用PaddleSeg在验证集上对已经训练好的模型进行评估。

任务要求:

  1. 能够在命令行中完成对图像分割模型的评估;
  2. 能够使用Notebook完成对图像分割模型的评估;
  3. 能够根据评估结果分析模型的性能。

模型评估需要在项目文件夹中执行 val.py 文件,同时需要指定好 --config 配置文件和 --model_path 训练好的模型文件。配置文件需要指定前向传输相关的超参数。在项目中,为了便于查看程序执行的反馈信息,建议使用命令提示行执行验证,命令如下:

python val.py --config configs/fcn_hrnetw18_small_v1_humanseg_192x192_mini_supervisely.yml --model_path saved_model/fcn_hrnetw18_small_v1_humanseg_192x192_mini_supervisely/best_model/model.pdparams

若要在Notebook中执行,需要在 python 命令前增加 !,同时将工作目录切换到项目文件夹。

import os
workspace = 'D:\\Workspace\\MyProjects\\PaddleSeg-release-2.4\\contrib\\PP-HumanSeg'
os.chdir(workspace)

!python val.py \
--config configs/fcn_hrnetw18_small_v1_humanseg_192x192_mini_supervisely.yml \
--model_path saved_model/fcn_hrnetw18_small_v1_humanseg_192x192_mini_supervisely/best_model/model.pdparams
    2022-02-18 12:09:33 [INFO]

    C:\Users\Administrator\anaconda3\lib\site-packages\paddleseg-2.4.0-py3.9.egg\paddleseg\models\losses\rmi_loss.py:73: DeprecationWarning: invalid escape sequence \i
    C:\Users\Administrator\anaconda3\lib\site-packages\paddleseg-2.4.0-py3.9.egg\paddleseg\models\losses\rmi_loss.py:73: DeprecationWarning: invalid escape sequence \i
    'C:\Program' �����ڲ����ⲿ���Ҳ���ǿ����еij���
    ���������ļ���
    W0218 12:09:33.029774 19452 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 6.1, Driver API Version: 11.1, Runtime API Version: 10.2
    W0218 12:09:33.029774 19452 device_context.cc:465] device: 0, cuDNN Version: 7.6.
    
      1/100 [..............................] - ETA: 18s - batch_cost: 0.1915 - reader cost: 0.1476
      2/100 [..............................] - ETA: 12s - batch_cost: 0.1321 - reader cost: 0.0942
      3/100 [..............................] - ETA: 10s - batch_cost: 0.1090 - reader cost: 0.0738
      4/100 [>.............................] - ETA: 10s - batch_cost: 0.1050 - reader cost: 0.0706
      5/100 [>.............................] - ETA: 9s - batch_cost: 0.1007 - reader cost: 0.0668 
      6/100 [>.............................] - ETA: 9s - batch_cost: 0.1021 - reader cost: 0.0685
      7/100 [=>............................] - ETA: 10s - batch_cost: 0.1081 - reader cost: 0.0744
      9/100 [=>............................] - ETA: 8s - batch_cost: 0.0949 - reader cost: 0.0608 
     11/100 [==>...........................] - ETA: 7s - batch_cost: 0.0845 - reader cost: 0.0502
     13/100 [==>...........................] - ETA: 7s - batch_cost: 0.0855 - reader cost: 0.0515
     15/100 [===>..........................] - ETA: 6s - batch_cost: 0.0815 - reader cost: 0.0478
     17/100 [====>.........................] - ETA: 6s - batch_cost: 0.0790 - reader cost: 0.0456
     18/100 [====>.........................] - ETA: 6s - batch_cost: 0.0787 - reader cost: 0.0451
     20/100 [=====>........................] - ETA: 5s - batch_cost: 0.0748 - reader cost: 0.0409
     21/100 [=====>........................] - ETA: 5s - batch_cost: 0.0758 - reader cost: 0.0421
     23/100 [=====>........................] - ETA: 5s - batch_cost: 0.0745 - reader cost: 0.0404
     25/100 [======>.......................] - ETA: 5s - batch_cost: 0.0740 - reader cost: 0.0400
     27/100 [=======>......................] - ETA: 5s - batch_cost: 0.0719 - reader cost: 0.0382
     28/100 [=======>......................] - ETA: 5s - batch_cost: 0.0721 - reader cost: 0.0386
     29/100 [=======>......................] - ETA: 5s - batch_cost: 0.0714 - reader cost: 0.0380
     30/100 [========>.....................] - ETA: 4s - batch_cost: 0.0710 - reader cost: 0.0376
     32/100 [========>.....................] - ETA: 4s - batch_cost: 0.0692 - reader cost: 0.0357
     34/100 [=========>....................] - ETA: 4s - batch_cost: 0.0671 - reader cost: 0.0336
     35/100 [=========>....................] - ETA: 4s - batch_cost: 0.0671 - reader cost: 0.0338
     36/100 [=========>....................] - ETA: 4s - batch_cost: 0.0682 - reader cost: 0.0345
     37/100 [==========>...................] - ETA: 4s - batch_cost: 0.0682 - reader cost: 0.0344
     39/100 [==========>...................] - ETA: 4s - batch_cost: 0.0668 - reader cost: 0.0332
     40/100 [===========>..................] - ETA: 4s - batch_cost: 0.0676 - reader cost: 0.0339
     41/100 [===========>..................] - ETA: 4s - batch_cost: 0.0679 - reader cost: 0.0342
     43/100 [===========>..................] - ETA: 3s - batch_cost: 0.0679 - reader cost: 0.0344
     45/100 [============>.................] - ETA: 3s - batch_cost: 0.0665 - reader cost: 0.0329
     47/100 [=============>................] - ETA: 3s - batch_cost: 0.0655 - reader cost: 0.0318
     48/100 [=============>................] - ETA: 3s - batch_cost: 0.0658 - reader cost: 0.0321
     50/100 [==============>...............] - ETA: 3s - batch_cost: 0.0646 - reader cost: 0.0309
     51/100 [==============>...............] - ETA: 3s - batch_cost: 0.0646 - reader cost: 0.0309
     52/100 [==============>...............] - ETA: 3s - batch_cost: 0.0650 - reader cost: 0.0314
     53/100 [==============>...............] - ETA: 3s - batch_cost: 0.0661 - reader cost: 0.0321
     54/100 [===============>..............] - ETA: 3s - batch_cost: 0.0687 - reader cost: 0.0348
     55/100 [===============>..............] - ETA: 3s - batch_cost: 0.0689 - reader cost: 0.0350
     56/100 [===============>..............] - ETA: 3s - batch_cost: 0.0694 - reader cost: 0.0354
     58/100 [================>.............] - ETA: 2s - batch_cost: 0.0682 - reader cost: 0.0342
     60/100 [=================>............] - ETA: 2s - batch_cost: 0.0681 - reader cost: 0.0342
     62/100 [=================>............] - ETA: 2s - batch_cost: 0.0675 - reader cost: 0.0335
     63/100 [=================>............] - ETA: 2s - batch_cost: 0.0686 - reader cost: 0.0346
     64/100 [==================>...........] - ETA: 2s - batch_cost: 0.0690 - reader cost: 0.0350
     65/100 [==================>...........] - ETA: 2s - batch_cost: 0.0691 - reader cost: 0.0350
     66/100 [==================>...........] - ETA: 2s - batch_cost: 0.0690 - reader cost: 0.0349
     67/100 [===================>..........] - ETA: 2s - batch_cost: 0.0697 - reader cost: 0.0346
     68/100 [===================>..........] - ETA: 2s - batch_cost: 0.0695 - reader cost: 0.0341
     69/100 [===================>..........] - ETA: 2s - batch_cost: 0.0712 - reader cost: 0.0359
     70/100 [====================>.........] - ETA: 2s - batch_cost: 0.0724 - reader cost: 0.0372
     71/100 [====================>.........] - ETA: 2s - batch_cost: 0.0730 - reader cost: 0.0376
     72/100 [====================>.........] - ETA: 2s - batch_cost: 0.0751 - reader cost: 0.0396
     73/100 [====================>.........] - ETA: 2s - batch_cost: 0.0755 - reader cost: 0.0400
     75/100 [=====================>........] - ETA: 1s - batch_cost: 0.0755 - reader cost: 0.0401
     77/100 [======================>.......] - ETA: 1s - batch_cost: 0.0746 - reader cost: 0.0392
     78/100 [======================>.......] - ETA: 1s - batch_cost: 0.0751 - reader cost: 0.0396
     79/100 [======================>.......] - ETA: 1s - batch_cost: 0.0763 - reader cost: 0.0408
     80/100 [=======================>......] - ETA: 1s - batch_cost: 0.0764 - reader cost: 0.0408
     82/100 [=======================>......] - ETA: 1s - batch_cost: 0.0757 - reader cost: 0.0402
     83/100 [=======================>......] - ETA: 1s - batch_cost: 0.0756 - reader cost: 0.0401
     84/100 [========================>.....] - ETA: 1s - batch_cost: 0.0756 - reader cost: 0.0401
     86/100 [========================>.....] - ETA: 1s - batch_cost: 0.0748 - reader cost: 0.0395
     87/100 [=========================>....] - ETA: 0s - batch_cost: 0.0746 - reader cost: 0.0393
     88/100 [=========================>....] - ETA: 0s - batch_cost: 0.0748 - reader cost: 0.0395
     89/100 [=========================>....] - ETA: 0s - batch_cost: 0.0754 - reader cost: 0.0401
     90/100 [==========================>...] - ETA: 0s - batch_cost: 0.0753 - reader cost: 0.0400
     91/100 [==========================>...] - ETA: 0s - batch_cost: 0.0755 - reader cost: 0.0402
     92/100 [==========================>...] - ETA: 0s - batch_cost: 0.0764 - reader cost: 0.0407
     93/100 [==========================>...] - ETA: 0s - batch_cost: 0.0763 - reader cost: 0.0406
     94/100 [===========================>..] - ETA: 0s - batch_cost: 0.0763 - reader cost: 0.0407
     95/100 [===========================>..] - ETA: 0s - batch_cost: 0.0764 - reader cost: 0.0408
     96/100 [===========================>..] - ETA: 0s - batch_cost: 0.0763 - reader cost: 0.0407
     97/100 [============================>.] - ETA: 0s - batch_cost: 0.0762 - reader cost: 0.0406
     99/100 [============================>.] - ETA: 0s - batch_cost: 0.0754 - reader cost: 0.0398
    100/100 [==============================] - 8s 75ms/step - batch_cost: 0.0750 - reader cost: 0.0394
    

    
    ---------------Config Information---------------
    batch_size: 64
    export:
      transforms:
      - target_size:
        - 192
        - 192
        type: Resize
      - type: Normalize
    iters: 500
    loss:
      coef:
      - 1
      types:
      - type: CrossEntropyLoss
    lr_scheduler:
      end_lr: 0
      learning_rate: 0.05
      power: 0.9
      type: PolynomialDecay
    model:
      backbone:
        align_corners: false
        type: HRNet_W18_Small_V1
      backbone_indices:
      - -1
      num_classes: 2
      pretrained: pretrained_model/fcn_hrnetw18_small_v1_humanseg_192x192/model.pdparams
      type: FCN
    optimizer:
      momentum: 0.9
      type: sgd
      weight_decay: 0.0005
    train_dataset:
      dataset_root: data/mini_supervisely
      mode: train
      num_classes: 2
      train_path: data/mini_supervisely/train.txt
      transforms:
      - target_size:
        - 192
        - 192
        type: Resize
      - type: RandomHorizontalFlip
      - brightness_range: 0.4
        contrast_range: 0.4
        saturation_range: 0.4
        type: RandomDistort
      - type: Normalize
      type: Dataset
    val_dataset:
      dataset_root: data/mini_supervisely
      mode: val
      num_classes: 2
      transforms:
      - target_size:
        - 192
        - 192
        type: Resize
      - type: Normalize
      type: Dataset
      val_path: data/mini_supervisely/val.txt
    ------------------------------------------------
    2022-02-18 12:09:35 [INFO] Loading pretrained model from pretrained_model/fcn_hrnetw18_small_v1_humanseg_192x192/model.pdparams
    2022-02-18 12:09:35 [INFO] There are 363/363 variables loaded into FCN.
    2022-02-18 12:09:35 [INFO] Loading pretrained model from saved_model/fcn_hrnetw18_small_v1_humanseg_192x192_mini_supervisely/best_model/model.pdparams
    2022-02-18 12:09:35 [INFO] There are 363/363 variables loaded into FCN.
    2022-02-18 12:09:35 [INFO] Loaded trained params of model successfully
    2022-02-18 12:09:35 [INFO] Start evaluating (total_samples: 100, total_iters: 100)...
    2022-02-18 12:09:42 [INFO] [EVAL] #Images: 100 mIoU: 0.6589 Acc: 0.8311 Kappa: 0.5730 Dice: 0.7865
    2022-02-18 12:09:42 [INFO] [EVAL] Class IoU: 
    [0.7923 0.5254]
    2022-02-18 12:09:42 [INFO] [EVAL] Class Acc: 
    [0.8839 0.6893]

PaddleSeg 默认会打印出配置文件信息 ----Config Information----,验证过程,以及验证结果(注意Notebook中结果打印顺序略有瑕疵,默认配置文件信息在最前面)。其中验证的结果包括,在整个验证集上的平均IoU和精度ACC,以及每个类别的IoU和ACC。

在图像分割领域中,评估模型质量主要是通过三个指标进行判断,准确率(acc)、平均交并比(Mean Intersection over Union,简称mIoU)、Kappa系数。

【任务七】模型预测(推理)

任务描述: 在PaddleSeg中,使用给定的图片在训练好的模型上进行推理和预测。

任务要求:

  1. 能够在命令行中使用训练好的模型对给定图片进行推理和预测;
  2. 能够Notebook中使用训练好的模型对给定图片进行推理和预测;
  3. 能够将推理生成的图片进行可视化。

模型预测(推理)同样需要在项目文件夹中执行,执行程序为 predict.py;同样需要指定好 --config 配置文件和 --model_path 训练好的模型文件。此外,待推理文件由 --image_path 进行指定,可以是一个图片,例如 data\test.jpg;也可以是一个目录例如 data/predict,当指定路径为目录时,会自动预测路径下的所有图片文件,包括子目录中的图片文件。参数 --save_dir (可省略) 用于设置输出目录,默认值为 ./output/result。在项目中,为了便于查看程序执行的反馈信息,建议使用命令提示行执行验证,命令如下:

python predict.py --config configs/fcn_hrnetw18_small_v1_humanseg_192x192_mini_supervisely.yml --model_path saved_model/fcn_hrnetw18_small_v1_humanseg_192x192_mini_supervisely/best_model/model.pdparams --image_path data/test.jpg --save_dir output/result

在输出路径 ./output/result/ 路径下,会生成两个文件夹 added_predictionpseudo_color_prediction。前者用于保存分割结果和原始图片的叠加,便于对分割结果进行理解,数据格式和原始图片一致;后者为单纯的分割结果,数据格式为 .png,和标注文件一致。若要在Notebook中执行,需要在 python 命令前增加 !,同时将工作目录切换到项目文件夹。

import os
workspace = 'D:\\Workspace\\MyProjects\\PaddleSeg-release-2.4\\contrib\\PP-HumanSeg'
os.chdir(workspace)

!python predict.py \
--config configs/fcn_hrnetw18_small_v1_humanseg_192x192_mini_supervisely.yml \
--model_path saved_model/fcn_hrnetw18_small_v1_humanseg_192x192_mini_supervisely/best_model/model.pdparams \
--image_path data/predict \
--save_dir output/result
    2022-02-18 20:00:32 [INFO]

    C:\Users\Administrator\anaconda3\lib\site-packages\paddleseg-2.4.0-py3.9.egg\paddleseg\models\losses\rmi_loss.py:73: DeprecationWarning: invalid escape sequence \i
    C:\Users\Administrator\anaconda3\lib\site-packages\paddleseg-2.4.0-py3.9.egg\paddleseg\models\losses\rmi_loss.py:73: DeprecationWarning: invalid escape sequence \i
    'C:\Program'
    W0218 20:00:32.915268 19964 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 6.1, Driver API Version: 11.1, Runtime API Version: 10.2
    W0218 20:00:32.915268 19964 device_context.cc:465] device: 0, cuDNN Version: 7.6.
    
    1/6 [====>.........................] - ETA: 0s
    2/6 [=========>....................] - ETA: 0s
    3/6 [==============>...............] - ETA: 0s
    4/6 [===================>..........] - ETA: 0s
    5/6 [========================>.....] - ETA: 0s
    6/6 [==============================] - 2s 293ms/step
    

    
    ---------------Config Information---------------
    batch_size: 64
    export:
      transforms:
      - target_size:
        - 192
        - 192
        type: Resize
      - type: Normalize
    iters: 2000
    loss:
      coef:
      - 1
      types:
      - type: CrossEntropyLoss
    lr_scheduler:
      end_lr: 0
      learning_rate: 0.05
      power: 0.9
      type: PolynomialDecay
    model:
      backbone:
        align_corners: false
        type: HRNet_W18_Small_V1
      backbone_indices:
      - -1
      num_classes: 2
      pretrained: pretrained_model/fcn_hrnetw18_small_v1_humanseg_192x192/model.pdparams
      type: FCN
    optimizer:
      momentum: 0.9
      type: sgd
      weight_decay: 0.0005
    train_dataset:
      dataset_root: data/mini_supervisely
      mode: train
      num_classes: 2
      train_path: data/mini_supervisely/train.txt
      transforms:
      - target_size:
        - 192
        - 192
        type: Resize
      - type: RandomHorizontalFlip
      - brightness_range: 0.4
        contrast_range: 0.4
        saturation_range: 0.4
        type: RandomDistort
      - type: Normalize
      type: Dataset
    val_dataset:
      dataset_root: data/mini_supervisely
      mode: val
      num_classes: 2
      transforms:
      - target_size:
        - 192
        - 192
        type: Resize
      - type: Normalize
      type: Dataset
      val_path: data/mini_supervisely/val.txt
    ------------------------------------------------
    2022-02-18 20:00:34 [INFO] Loading pretrained model from pretrained_model/fcn_hrnetw18_small_v1_humanseg_192x192/model.pdparams
    2022-02-18 20:00:34 [INFO] There are 363/363 variables loaded into FCN.
    2022-02-18 20:00:34 [INFO] Number of predict images = 6
    2022-02-18 20:00:34 [INFO] Loading pretrained model from saved_model/fcn_hrnetw18_small_v1_humanseg_192x192_mini_supervisely/best_model/model.pdparams
    2022-02-18 20:00:34 [INFO] There are 363/363 variables loaded into FCN.
    2022-02-18 20:00:34 [INFO] Start to predict...

从上述推理过程可以看到,predict.py 对 参数 --image_path 所指定的图片源文件夹 data/predict 中的6幅图片进行以此预测,并保存在参数 --save_dir 所指定的路径 output/result 中。

############ 可视化结果 ##########
import os
import cv2
import matplotlib.pyplot as plt

# 设置各种路径
root_path = 'D:\\WorkSpace\\MyProjects\\PaddleSeg-release-2.4\\contrib\\PP-HumanSeg\\output\\result\\added_prediction'
img_list = os.listdir(root_path)

plt.figure(figsize=(18,10))
n = len(img_list)
for i in range(1, n+1):
    file_name = os.path.join(root_path, img_list[i-1])
    img = cv2.imread(file_name)
    img = cv2.resize(img, (400, 250), interpolation=cv2.INTER_AREA)  
    img_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)    
    plt.subplot(2,3,i)
    plt.title('Image {}'.format(i))
    plt.imshow(img_RGB)

output_51_0

【实验结果分析】
从上面的实验结果可以得出以下结论,1). 在图1中,只存在背景而不存在行人,但是分割结果仍然有一部分像素被错分成Human类;2). 图2,5,6主要部分落在了人体部分,但是包裹性并不是特别好,一部分像素没有被容纳,而一部分属于背景的像素却被包裹在内。从上面对实验过程的描述,不难发现,分割结果不理想的原因主要有3个,一是训练数据比较少,只有350副图片,使用完整版的HumanSeg数据可以获得更好的性能;二是 fcn_hrnetw18_small_v1 模型比较简单,主要关注的是速度,因此性能并不是特别好,其结果与 3.3.3 的结论基本一致;三是该模型主要针对的是肖像分割。尽管如此,在图3,4中,我们依然可以获得较好的性能。说明简单的背景下,超轻量级的效率模型也能够获得不错的性能。

在实际应用中,我们可以根据应用场景的不同选择不同的模型。对于背景单一,且简单的模型,可以使用高效率的轻量级模型,甚至超轻量级模型;而对于要求精度比较高的任务,则可以使用DeepLabv3同级别的高精度模型,对于这类模型的使用,通常需要GPU的支持,但是由于参数数量较为庞大,因此也需要更多的推理时间,这类模型并不是很适合实时推理的应用。