语义分割标志东北大学缺陷检测数据集,投入U2Net做检测;
完善显著性检测评价指标,代码实现,比较U2Net在磁瓦缺陷检测数据集和东北大学缺陷检测数据集中的检测能力;
主要是网络结构,代码结构,此外包括《动手学深度学习》中的基础课程。
U2Net网络结构讲解
U2Net源码解析(Pytorch)
使用labelme制作显著性检测/分割数据集并批量转化json文件
论文中给出六种评价指标,官方代码中没有给出评价指标的代码。
给出F-measure和MAE的公式
准确率(Precision)
召回率(Recall)
综合评价指标(F-Measure)
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
解决方法
conda clean -i
二分类(前景和背景)
打开Anaconda prompt
依赖包
pip install pyqt #python2.x输入这个
pip install pyqt5 #python3.x输入这个
安装
pip install labelme==3.16.2 #由于在json转化时版本高的labelme会出问题,所以这里用3.16.2版本
labelme
…\Anaconda3\Lib\site-packages\labelme\cli
文件夹中。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()
labelme_json_to_dataset E:\SOD\dataset\results
#后面的路径是json标注文件所在的文件夹,此文件夹中不可包含其他文件
转换后得到每个json文件对应文件夹中包含以下五个文件:
批量提取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图片的名称进行修改,和原图保持一直,这样后面就不用单独再写批量重命名的代码了
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)
[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
缺陷类型 | 训练集 | 测试集 |
---|---|---|
气孔 | 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
完成了东北大学缺陷检测数据集scratches一类的标注和数据集增强。
完善了U2Net代码中的评价指标——MAE和F-measure,并实现了训练过程中评价指标的输出和通过评价指标控制训练次数的能力。
只完成了预期目标中的U2Net部分,包括网络结构,代码结构等。Yolo和Faster-RCNN会在后面进行专门学习。
在提高显著性检测精度的基础上,对图像增强算法进行学习和实现。