20221107-20221113工作总结

目录

  • 一、本周工作计划
    • 1、标图
    • 2、完善评价指标
    • 3、深入学习U2Net、Yolov5和Faster-RCNN
  • 二、U2Net相关
    • 1、参考资料
    • 2、U2Net
      • 1)前言
      • 2)网络结构
      • 3)损失计算
      • 4)评价指标
    • 问题记录
    • 3、labelme语义分割标注流程
      • 1)安装
      • 2)使用
      • 3)处理
      • 4)批量重命名
    • 4、训练和预测
      • 东北大学缺陷检测数据集——划痕(scratches)
      • 磁瓦缺陷数据集——孔(Blowhole)、裂纹(Crack)、磨损(Fary)
    • 5、数据增强
  • 三、工作总结
    • 1、图像标注和数据增强
    • 2、代码修改——评价指标
    • 3、深入学习U2Net
  • 四、下周工作计划
    • 1、增强算法
    • 2、显著性检测精度提高

一、本周工作计划

1、标图

语义分割标志东北大学缺陷检测数据集,投入U2Net做检测;

2、完善评价指标

完善显著性检测评价指标,代码实现,比较U2Net在磁瓦缺陷检测数据集和东北大学缺陷检测数据集中的检测能力;

3、深入学习U2Net、Yolov5和Faster-RCNN

主要是网络结构,代码结构,此外包括《动手学深度学习》中的基础课程。

二、U2Net相关

1、参考资料

U2Net网络结构讲解
U2Net源码解析(Pytorch)
使用labelme制作显著性检测/分割数据集并批量转化json文件

2、U2Net

1)前言

  • U2Net专门针对SOD(salient object detection)问题设计,SOD指将图片中最吸引人的目标或区域分割出来,相当于语义分割中的二分类任务——只有前景和背景两个类别;
  • U2Net官方代码包括两个模型——标准模型(176.3MB)和轻量级模型(4.7MB),其模型大小和检测效果均优于同期显著性目标检测模型;
    20221107-20221113工作总结_第1张图片

2)网络结构

20221107-20221113工作总结_第2张图片

  • 编码-解码结构,每个block其实是UNet(深度不同),block包括En_1、En_2、En_3、En_4、En_5、En_6、De_1、De_2、De_3、De_4、De_5;
  • 每通过一个Encoder 下采样2倍(maxpool最大值池化),每通过一个Decoder 上采样2倍(bilinear);
  • En_1、De_1 ----> RSU_7,五个下采样(蓝色)和五个上采样(粉色),下采32倍;
    20221107-20221113工作总结_第3张图片
    20221107-20221113工作总结_第4张图片
  • En_2、De_2 ----> RSU_6,与RSU_7相比少一个下采样和一个上采样,下采16倍;
  • En_3、De_3 ----> RSU_5,下采8倍;
  • En_4、De_4 ----> RSU_4,下采4倍;
  • En_5、En_6、De_5 —> RSU_4F,不同于RSU_4,没有下采样和上采样,原因是En_4的输出图片宽高已经很小了,再下采样(下采再上采)的话会损失很多上下文信息,所以En_5、En_6、De_5不再使用上采样和下采样结构,而是替换成膨胀卷积,如下图,d2表示膨胀系数为2、d4表示膨胀系数为4、d8表示膨胀系数为8。
    20221107-20221113工作总结_第5张图片
  • De_1、De_2、De_3、De_4、De_5、En_6的输出分别进行3x3卷积(channe=1)以及双线性插值相应倍数上采样变换为输出图像尺寸的6张特征图;6张特征图经concat拼接以及1x1卷积得到最终输出图像。
  • 参数配置
    20221107-20221113工作总结_第6张图片

3)损失计算

20221107-20221113工作总结_第7张图片

  • 损失函数分为两部分,第一部分为中间6个特征图与GT相比的损失,其中M=6;第二部分为最终输出图像与GT相比的损失;
  • l代表二值交叉熵损失、w代表每个损失的权重,源码中每个损失的权重都为1。

4)评价指标

论文中给出六种评价指标,官方代码中没有给出评价指标的代码。

  • PR curve
  • F-measure
  • MAE
  • weighted F-measure
  • S-Measure
  • relax boundary F-measure

给出F-measure和MAE的公式

  • F-measure
    20221107-20221113工作总结_第8张图片

    • 对于不同概率阈值,有一系列的Precision和Recall,得到的F-measure是一个数组,取其中的最大值maxF-measure作为评价指标;
  • 准确率(Precision)

    • Precision是检测出某类特征的数量与检测出的所有特征数量之间的比率,衡量的是模型的查准率;
    • precision = 提取出的正确信息条数 / 提取出的信息条数
    • 一般来说,Precision就是检索出来的条目有多少是准确的
  • 召回率(Recall)

    • Recall是指检测出的某类特征的数量和数据集中所有的该类特征数量的比率,衡量的是检索系统的查全率
    • Recall = 提取出的正确信息条数 / 样本中的信息条数
  • 综合评价指标(F-Measure)

    • 综合评价指标(F-Measure)是准确率和召回率的调和平均值
    • 0
  • MAE
    20221107-20221113工作总结_第9张图片

    • 0

问题记录

  • 需要重新安装pytorch和torchvision,运行官方代码时报错。
conda install pytorch torchvision torchaudio pytorch-cuda=11.6 -c pytorch -c nvidia
environment variables:
                 CIO_TEST=<not set>
        CONDA_DEFAULT_ENV=yolo
                CONDA_EXE=d:\Users\JMan\anaconda3\condabin\..\Scripts\conda.exe
               CONDA_EXES="d:\Users\JMan\anaconda3\condabin\..\Scripts\conda.exe"
             CONDA_PREFIX=d:\Users\JMan\anaconda3\envs\yolo
           CONDA_PREFIX_1=d:\Users\JMan\anaconda3
           CONDA_PREFIX_2=d:\Users\JMan\anaconda3\envs\py37
    CONDA_PROMPT_MODIFIER=(yolo)
         CONDA_PYTHON_EXE=d:\Users\JMan\anaconda3\python.exe
               CONDA_ROOT=d:\Users\JMan\anaconda3
              CONDA_SHLVL=3
                CUDA_PATH=D:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6
           CURL_CA_BUNDLE=<not set>
                 HOMEPATH=\Users\JMan
          NVTOOLSEXT_PATH=C:\Program Files\NVIDIA Corporation\NvToolsExt\
                     PATH=d:\Users\JMan\anaconda3\envs\yolo;d:\Users\JMan\anaconda3\envs\yolo\Li
                          brary\mingw-w64\bin;d:\Users\JMan\anaconda3\envs\yolo\Library\usr\bin;
                          d:\Users\JMan\anaconda3\envs\yolo\Library\bin;d:\Users\JMan\anaconda3\
                          envs\yolo\Scripts;d:\Users\JMan\anaconda3\envs\yolo\bin;d:\Users\JMan\
                          anaconda3\condabin;D:\Program Files\NVIDIA GPU Computing
                          Toolkit\CUDA\v11.6\bin;D:\Program Files\NVIDIA GPU Computing Toolkit\C
                          UDA\v11.6\libnvvp;C:\WINDOWSsystem32;C:\WINDOWS;d:\Users\JMan\anaconda
                          3;C:\WINDOWSSystem32Wbem;C:\WINDOWSSystem32WindowsPowerShellv1.0;d:\Us
                          ers\JMan\anaconda3\Library\mingw-w64\bin;d:\Users\JMan\anaconda3\Libra
                          ry\usr\bin;d:\Users\JMan\anaconda3\Library\bin;d:\Users\JMan\anaconda3
                          \Scripts;C:\Users\JMan\AppData\Local\Microsoft\WindowsApps;d:\Program
                          Files\JetBrains\PyCharm 2022.2.3\bin;d:\Program
                          Files\JetBrains\PyCharm Community Edition 2022.2.3\bin;C:\Program
                          Files\NVIDIA Corporation\Nsight Compute 2022.1.0;D:\Program
                          Files\TortoiseSVN\bin;D:\Program Files\NVIDIA GPU Computing
                          Toolkit\CUDA\v11.6;D:\Program Files\NVIDIA GPU Computing
                          Toolkit\CUDA\v11.6\bin;D:\Program Files\NVIDIA GPU Computing
                          Toolkit\CUDA\v11.6\lib\x64;D:\Program Files\NVIDIA GPU Computing Toolk
                          it\CUDA\v11.6\libnvvp;d:\Users\JMan\anaconda3;d:\Users\JMan\anaconda3\
                          Library\mingw-w64\bin;d:\Users\JMan\anaconda3\Library\usr\bin;d:\Users
                          \JMan\anaconda3\Library\bin;d:\Users\JMan\anaconda3\Scripts;C:\Users\J
                          Man\AppData\Local\Microsoft\WindowsApps;d:\Program
                          Files\JetBrains\PyCharm 2022.2.3\bin;.;d:\Program
                          Files\JetBrains\PyCharm Community Edition 2022.2.3\bin;.;.
             PSMODULEPATH=C:\Program Files\WindowsPowerShell\Modules;C:\WINDOWS\system32\Windows
                          PowerShell\v1.0\Modules
       REQUESTS_CA_BUNDLE=<not set>
            SSL_CERT_FILE=<not set>

     active environment : yolo
    active env location : d:\Users\JMan\anaconda3\envs\yolo
            shell level : 3
       user config file : C:\Users\JMan\.condarc
 populated config files : C:\Users\JMan\.condarc
          conda version : 22.9.0
    conda-build version : 3.18.9
         python version : 3.7.13.final.0
       virtual packages : __cuda=11.7=0
                          __win=0=0
                          __archspec=1=x86_64
       base environment : d:\Users\JMan\anaconda3  (writable)
      conda av data dir : d:\Users\JMan\anaconda3\etc\conda
  conda av metadata url : None
           channel URLs : https://conda.anaconda.org/pytorch/win-64
                          https://conda.anaconda.org/pytorch/noarch
                          https://conda.anaconda.org/nvidia/win-64
                          https://conda.anaconda.org/nvidia/noarch
                          http://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/win-64
                          http://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/noarch
                          http://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/win-64
                          http://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/noarch
                          https://conda.anaconda.org/anaconda/win-64
                          https://conda.anaconda.org/anaconda/noarch
                          https://repo.anaconda.com/pkgs/main/win-64
                          https://repo.anaconda.com/pkgs/main/noarch
                          https://repo.anaconda.com/pkgs/r/win-64
                          https://repo.anaconda.com/pkgs/r/noarch
                          https://repo.anaconda.com/pkgs/msys2/win-64
                          https://repo.anaconda.com/pkgs/msys2/noarch
          package cache : d:\Users\JMan\anaconda3\pkgs
                          C:\Users\JMan\.conda\pkgs
                          C:\Users\JMan\AppData\Local\conda\conda\pkgs
       envs directories : d:\Users\JMan\anaconda3\envs
                          C:\Users\JMan\.conda\envs
                          C:\Users\JMan\AppData\Local\conda\conda\envs
               platform : win-64
             user-agent : conda/22.9.0 requests/2.27.1 CPython/3.7.13 Windows/10 Windows/10.0.22621
          administrator : False
             netrc file : None
           offline mode : False


An unexpected error has occurred. Conda has prepared the above report.

If submitted, this report will be used by core maintainers to improve
future releases of conda.
Would you like conda to send this report to the core maintainers? [y/N]: y
Upload successful.

Thank you for helping to improve conda.
Opt-in to always sending reports (and not see this message again)
by running

解决方法

  1. 删除.condarc文件
    这个文件位置一般为C:\User\Administrator.condarc,如果设置了清华/中科大源,里面会保存这些镜像源的地址,删除了这个文件其实就是类似于恢复使用官方源。(之前有按照教程加入过清华源)
  2. 删除conda中的缓存索引,运行如下命令:
conda clean -i

3、labelme语义分割标注流程

二分类(前景和背景)

1)安装

打开Anaconda prompt
依赖包

pip install pyqt    #python2.x输入这个
pip install pyqt5    #python3.x输入这个

安装

pip install labelme==3.16.2 #由于在json转化时版本高的labelme会出问题,所以这里用3.16.2版本

2)使用

labelme

20221107-20221113工作总结_第10张图片

  • 点击左侧opendir打开需要标注的图片所在文件夹;
  • 在右侧file list中选择需要标注的图片;
  • 点击左侧create polygons进行标注,形成封闭区域后会提示让你创建或选择label的类型;
  • ctrl+s保存标注好的json文件到指定文件夹。

3)处理

  • 在anaconda的文件夹中找到json_to_dataset.py文件,我的在
    …\Anaconda3\Lib\site-packages\labelme\cli文件夹中。
  • 这个文件可以用来将单个json文件进行转化,为了批量转化,替换json_to_dataset.py中的代码如下:
import argparse
import json
import os
import os.path as osp
import warnings
import copy

import numpy as np
import PIL.Image
from skimage import io
import yaml

from labelme import utils

NAME_LABEL_MAP = {
    '_background_': 0,
    "mask": 255,
}

LABEL_NAME_MAP = {
    0: '_background_',
    255: "mask",

}


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('json_file')
    parser.add_argument('-o', '--out', default=None)
    args = parser.parse_args()

    json_file = args.json_file

    list = os.listdir(json_file)
    for i in range(0, len(list)):
        path = os.path.join(json_file, list[i])
        filename = list[i][:-5]  # .json
        if os.path.isfile(path):
            data = json.load(open(path))
            img = utils.image.img_b64_to_arr(data['imageData'])
            lbl, lbl_names = utils.shape.labelme_shapes_to_label(img.shape, data['shapes'])  # labelme_shapes_to_label

            # modify labels according to NAME_LABEL_MAP
            lbl_tmp = copy.copy(lbl)
            for key_name in lbl_names:
                old_lbl_val = lbl_names[key_name]
                new_lbl_val = NAME_LABEL_MAP[key_name]
                lbl_tmp[lbl == old_lbl_val] = new_lbl_val
            lbl_names_tmp = {}
            for key_name in lbl_names:
                lbl_names_tmp[key_name] = NAME_LABEL_MAP[key_name]

            # Assign the new label to lbl and lbl_names dict
            lbl = np.array(lbl_tmp, dtype=np.int8)
            lbl_names = lbl_names_tmp

            captions = ['%d: %s' % (l, name) for l, name in enumerate(lbl_names)]
            lbl_viz = utils.draw.draw_label(lbl, img, captions)
            out_dir = osp.basename(list[i]).replace('.', '_')
            out_dir = osp.join(osp.dirname(list[i]), out_dir)
            if not osp.exists(out_dir):
                os.mkdir(out_dir)

            PIL.Image.fromarray(img).save(osp.join(out_dir, '{}_img.png'.format(filename)))
            PIL.Image.fromarray(lbl.astype(np.uint8)).save(osp.join(out_dir, '{}.png'.format(filename)))
            PIL.Image.fromarray(lbl_viz).save(osp.join(out_dir, '{}_viz.png'.format(filename)))

            with open(osp.join(out_dir, 'label_names.txt'), 'w') as f:
                for lbl_name in lbl_names:
                    f.write(lbl_name + '\n')

            warnings.warn('info.yaml is being replaced by label_names.txt')
            info = dict(label_names=lbl_names)
            with open(osp.join(out_dir, 'info.yaml'), 'w') as f:
                yaml.safe_dump(info, f, default_flow_style=False)

            print('Saved to: %s' % out_dir)


if __name__ == '__main__':
    main()
  • 由于我这次只需要进行显著性检测,故将标注得到的png图设为前景255,背景0,要是有其他类可以设置不同mark类型的不同像素值。
    注:'mask’替换成自己标注时设置的label类型。
  • 替换后,在终端进入准备保存生成的json文件夹的路径,在此路径下输入:
labelme_json_to_dataset E:\SOD\dataset\results    
#后面的路径是json标注文件所在的文件夹,此文件夹中不可包含其他文件

转换后得到每个json文件对应文件夹中包含以下五个文件:
20221107-20221113工作总结_第11张图片
批量提取json文件夹中png图
GT_from_PATH为json文件夹所在路径。
GT_from_PATH为存储png图的路径。

import os
import random
import shutil
import re
 
# GT_from_PATH = "./jsons"
# GT_to_PATH = "./gts"
GT_from_PATH = "E:\\SOD\\dataset\\results\\json_dirs"
GT_to_PATH = "E:\\SOD\\dataset\\results\\pngs"
 
def copy_file(from_dir, to_dir, Name_list):
    if not os.path.isdir(to_dir):
        os.mkdir(to_dir)
 
    for name in Name_list:
        try:
      
            if not os.path.isfile(os.path.join(from_dir, name)):
                print("{} is not existed".format(os.path.join(from_dir, name)))
            shutil.copy(os.path.join(from_dir, name), os.path.join(to_dir, name))
 
        except:
                   pass
       
    print("{} has copied to {}".format(from_dir, to_dir))
 
if __name__ == '__main__':
    filepath_list = os.listdir(GT_from_PATH)
    for i, file_path in enumerate(filepath_list):
        gt_path = "{}/{}_gt.png".format(os.path.join(GT_from_PATH, filepath_list[i]), file_path[:-5])
        print("copy {} to ...".format(gt_path))
        gt_name = ["{}.png".format(file_path[:-5])]
        gt_file_path = os.path.join(GT_from_PATH, file_path)
        copy_file(gt_file_path, GT_to_PATH, gt_name)

注:对上面代码中的导出png图片的名称进行修改,和原图保持一直,这样后面就不用单独再写批量重命名的代码了

4)批量重命名

import os

def rename(path):
    imglist=os.listdir(path)
    for item in imglist :
        if item.endswith('.png'):
            name = item.split('.')[0]

            new_name = name.split('_')[0:2]
            new_name1 = new_name[0]+'_'+new_name[1]

            src = os.path.join(path,name+'.png')
            det = os.path.join(path,new_name1+'.png')
            os.rename(src,det)
            print(src,det)


if __name__ =='__main__':
    path = 'D:/Users/JMan/PycharmProjects/u2net_scratches/DATA_TE/gt/'
    rename(path)

4、训练和预测

东北大学缺陷检测数据集——划痕(scratches)

20221107-20221113工作总结_第12张图片

  • 训练集:200张
  • 测试集:56张
  • epoch=120
[epoch: 0] train_loss: 1.8022 lr: 0.000500 MAE: 0.076 maxF1: 0.741 
[epoch: 10] train_loss: 0.4672 lr: 0.000986 MAE: 0.032 maxF1: 0.870 
[epoch: 20] train_loss: 0.4094 lr: 0.000937 MAE: 0.029 maxF1: 0.855 
[epoch: 30] train_loss: 0.3600 lr: 0.000858 MAE: 0.023 maxF1: 0.881 
[epoch: 40] train_loss: 0.3128 lr: 0.000754 MAE: 0.021 maxF1: 0.897 
[epoch: 50] train_loss: 0.3004 lr: 0.000632 MAE: 0.020 maxF1: 0.902 
[epoch: 60] train_loss: 0.2927 lr: 0.000500 MAE: 0.020 maxF1: 0.900 
[epoch: 70] train_loss: 0.2603 lr: 0.000368 MAE: 0.019 maxF1: 0.900 
[epoch: 80] train_loss: 0.2550 lr: 0.000246 MAE: 0.019 maxF1: 0.900 
[epoch: 90] train_loss: 0.2400 lr: 0.000142 MAE: 0.019 maxF1: 0.903 
[epoch: 100] train_loss: 0.2269 lr: 0.000063 MAE: 0.019 maxF1: 0.902 
[epoch: 110] train_loss: 0.2226 lr: 0.000014 MAE: 0.018 maxF1: 0.901 
[epoch: 119] train_loss: 0.2196 lr: 0.000000 MAE: 0.018 maxF1: 0.902 

下图左边gt,右边预测结果
20221107-20221113工作总结_第13张图片

磁瓦缺陷数据集——孔(Blowhole)、裂纹(Crack)、磨损(Fary)

20221107-20221113工作总结_第14张图片

缺陷类型 训练集 测试集
气孔 92 23
裂纹 44 13
磨损 24 8
累计 160 44
[epoch: 0] train_loss: 2.5052 lr: 0.000500 MAE: 0.052 maxF1: 0.048 
[epoch: 10] train_loss: 0.7343 lr: 0.000998 MAE: 0.068 maxF1: 0.102 
[epoch: 20] train_loss: 0.5360 lr: 0.000990 MAE: 0.035 maxF1: 0.283 
[epoch: 30] train_loss: 0.4003 lr: 0.000977 MAE: 0.053 maxF1: 0.272 
[epoch: 40] train_loss: 0.3379 lr: 0.000958 MAE: 0.027 maxF1: 0.271 
[epoch: 50] train_loss: 0.4130 lr: 0.000935 MAE: 0.037 maxF1: 0.230 
[epoch: 60] train_loss: 0.3250 lr: 0.000906 MAE: 0.043 maxF1: 0.230 
[epoch: 70] train_loss: 0.2352 lr: 0.000873 MAE: 0.020 maxF1: 0.355 
[epoch: 80] train_loss: 0.3227 lr: 0.000836 MAE: 0.031 maxF1: 0.309 
[epoch: 90] train_loss: 0.2545 lr: 0.000796 MAE: 0.024 maxF1: 0.416 
[epoch: 100] train_loss: 0.1332 lr: 0.000752 MAE: 0.037 maxF1: 0.443 
[epoch: 110] train_loss: 0.0957 lr: 0.000705 MAE: 0.016 maxF1: 0.554 
[epoch: 120] train_loss: 0.1291 lr: 0.000656 MAE: 0.034 maxF1: 0.409 
[epoch: 130] train_loss: 0.0963 lr: 0.000605 MAE: 0.013 maxF1: 0.558 
[epoch: 140] train_loss: 0.0756 lr: 0.000553 MAE: 0.014 maxF1: 0.559 
[epoch: 150] train_loss: 0.0774 lr: 0.000500 MAE: 0.010 maxF1: 0.630 
[epoch: 160] train_loss: 0.0693 lr: 0.000447 MAE: 0.009 maxF1: 0.636 
[epoch: 170] train_loss: 0.0664 lr: 0.000395 MAE: 0.008 maxF1: 0.635 
[epoch: 180] train_loss: 0.0914 lr: 0.000344 MAE: 0.011 maxF1: 0.647 
[epoch: 190] train_loss: 0.0679 lr: 0.000295 MAE: 0.009 maxF1: 0.667 
[epoch: 200] train_loss: 0.0719 lr: 0.000248 MAE: 0.009 maxF1: 0.663 
[epoch: 210] train_loss: 0.0644 lr: 0.000204 MAE: 0.007 maxF1: 0.690 
[epoch: 220] train_loss: 0.0579 lr: 0.000164 MAE: 0.009 maxF1: 0.644 
[epoch: 230] train_loss: 0.0599 lr: 0.000127 MAE: 0.007 maxF1: 0.706 
[epoch: 240] train_loss: 0.0553 lr: 0.000094 MAE: 0.007 maxF1: 0.719 
[epoch: 250] train_loss: 0.0540 lr: 0.000065 MAE: 0.007 maxF1: 0.682 
[epoch: 260] train_loss: 0.0544 lr: 0.000042 MAE: 0.007 maxF1: 0.706 
[epoch: 270] train_loss: 0.0563 lr: 0.000023 MAE: 0.007 maxF1: 0.699 
[epoch: 280] train_loss: 0.0532 lr: 0.000010 MAE: 0.007 maxF1: 0.713 
[epoch: 290] train_loss: 0.0551 lr: 0.000002 MAE: 0.006 maxF1: 0.712 
[epoch: 299] train_loss: 0.0554 lr: 0.000000 MAE: 0.007 maxF1: 0.713 

20221107-20221113工作总结_第15张图片

5、数据增强

三、工作总结

1、图像标注和数据增强

完成了东北大学缺陷检测数据集scratches一类的标注和数据集增强。

2、代码修改——评价指标

完善了U2Net代码中的评价指标——MAE和F-measure,并实现了训练过程中评价指标的输出和通过评价指标控制训练次数的能力。

3、深入学习U2Net

只完成了预期目标中的U2Net部分,包括网络结构,代码结构等。Yolo和Faster-RCNN会在后面进行专门学习。

四、下周工作计划

1、增强算法

2、显著性检测精度提高

在提高显著性检测精度的基础上,对图像增强算法进行学习和实现。

你可能感兴趣的:(深度学习,人工智能)