2021.8.20
讨论了一下,之前这个结果毋庸置疑是过拟合的。
讲一下为什么之前的结果准确率如此高,我是做了数据增强,做了大量拼接之类的工作,再划分的TRAIN和TEST,但是这样其实TEST里的数据就和TRAIN里的数据在概率上不是独立分布的了,再加上本身也有一定的过拟合,所以训练结果偏好。

这个数据集最大的问题是同类间的差距过大数据量又小,如果直接按照9:1去分训练集和测试集是不行的,很可能那1/10的测试数据形状与9/10的训练数据完全不同,所以会导致结果很差。

建议考虑用西瓜书P27的自助法采集TRAIN和TEST,有空我也试验一下。

另外还是不能使用太大的模型,数据量还是太少了。

2021.7.26修改:
用公司的服务器跑了一个更大的yolov5l模型,300个epoch,只看训练集的话,检测出来的结果看着靠谱多了,虽然有些arc还是歪。只是用l跑这么少的训练集,大概率会过饱和。

他这个map是基于valid集的,想提高分数也要多增加一些valid,由于数据集比较小,每个图像之间的差异较大,实际上很难范化,建议只验证测试集准确率,或者做大量的预处理工作,才能看到效果。
在这里插入图片描述
在这里插入图片描述

1)背景介绍

之前在东大读硕士的时候接触过NEU-DET数据集,用来做钢材表面的缺陷识别,最近学习yolov5想起来了,尝试使用YOLOV5实现识别钢材表面的缺陷。

数据集:http://faculty.neu.edu.cn/yunhyan/NEU_surface_defect_database.html

2) 检测算法YOLOV5

讲算法的文章有很多,就不再复述一遍了。近期学习时主要看到比较好的文章推荐:

YOLO系列(从v1到v5)模型解读 (上、中、下):

https://zhuanlan.zhihu.com/p/183261974
https://zhuanlan.zhihu.com/p/183781646
https://zhuanlan.zhihu.com/p/186014243

Yolov3&Yolov4&Yolov5核心基础知识完整讲解(上、下):

https://zhuanlan.zhihu.com/p/143747206
https://zhuanlan.zhihu.com/p/172121380

之后有空会再整理一篇YOLOV5的学习心得。

3)数据认识

东大钢材缺陷数据中,收集了热轧钢带的六种典型表面缺陷:

rolled-in scale (RS)
patches (Pa)
crazing (Cr)
pitted surface (PS)
inclusion (In)
scratches (Sc)

可视化部分数据:
在这里插入图片描述
可以看出,数据集的类内缺陷在外观上存在很大差异。
例如划痕(Sc)可能是水平划痕,垂直划痕和倾斜划痕等。另外,由于照明和材料变化的影响,类内缺陷图像的灰度是变化的。
简而言之,NEU数据集包括两个困难的挑战,即类内缺陷在外观上存在较大差异,而类间缺陷具有相似的方面。

4)数据处理

数据集的标签为xml格式,需要转换成txt格式,并对数据进行归一化处理,以便yolo算法使用。

转换主要涉及对标定框的归一化以及对类型的归一化。

import xml. etree. ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os. path import join
import glob
classes =["crazing", "inclusion", "patches", "pitted_surface","rolled-in_scale", "scratches"]

def convert(size, box):
    dw=1./size[0]
    dh =1./size[1]
    x = (box[0] + box[1]) / 2.0
    y=(box[2]+box[3])/2.0
    w=box[1] -box[0]
    h = box[3] - box[2]
    x=x*dw
    w=w*dw
    y= y*dh
    h =h*dh
    return(x,y,w,h)

def convert_annotation(image_name):
    in_file=open('./aragnal/ANNOTATIONS/'+image_name[: -3]+'xmL')
    out_file=open( "D:/python/kaggle/yolov5-master/NEU-DET/valid/labels/"+image_name[: -3]+'txt', 'w')
    tree=ET. parse(in_file)
    root=tree. getroot()
    size=root.find('size')
    w=int(size.find('width').text)
    h=int(size. find( 'height'). text)
    for obj in root.iter('object'):
        cls=obj. find('name').text
        if cls not in classes:
            print(cls)
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text),
            float(xmlbox.find('xmax').text),
            float(xmlbox.find('xmin').text),
            float(xmlbox.find('xmax').text))
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb])+'\n')

wd = getcwd()

if __name__ == '__main__':
    for image_path in glob.glob(r"D:\python\kaggle\yolov5-master\NEU-DET\valid\images\*.jpg"):
        image_name = image_path.split('\\')[-1]
    # print (imege path)
        convert_annotation(image_name)

运行结果如下:
在这里插入图片描述

5 )调整参数

train.py配置参数如下:
–batch-size
8
–epoch
300
–data
D:\python\yolov5-master\NEU-DET\data.yaml
–cfg
D:\python\yolov5-master\yolov5-master\models\yolov5s.yaml
–weight
D:\python\yolov5-master\yolov5-master\runs\train\exp7\weights\best.pt

路径可以采用绝对路径也可以采用相对路径,这里采用了绝对路径。
batch-size与显卡显存相关,超出显存会报错。本次采用1080Ti,设置了8.
epoch设置为300次。

6)结果预测

train.py训练集运行结果:
在这里插入图片描述
PR结果很差,一方面时由于机器不太行,epoch跑的太少导致的训练不充分欠拟合,另一方面应该也和数据集类间相似度较低有关。YOLOV5针对COCO训练集最哦的我数据增强措施可能并不完全适合这个项目,需要额外的数据增强措施,在下一篇博客里再讨论优化过程。

detect.py预测参数如下:
–source
D:\python\yolov5-master\NEU-DET\train\images
–weights
D:\python\yolov5-master\yolov5-master\runs\train\exp8\weights\best.pt
–conf
0.3

detcect结果如下 :在这里插入图片描述

7)经验总结

1、如果第一次训练识别到的结果比人眼识别的差得多,那么最可能的原因是在数据图像预处理方面有问题。
2、YoloV5有多种型号(yolov5s、yolov5m、yolov5l、yolov5x),分别对应衣服码数s m l x,不要只选择最大的一个,要根据你穿的衣服码数进行选择(开玩笑),实际原因是盲目选择过大的可能会过拟合,尤其像这种数据量不大的项目。
3、由于数据集较少,考虑做迁移学习,但是YOLOV5怎么冻结部分权重还没太搞明白。

8)改进

本次数据集的难度主要体现在类间差距不够明显以及类内差距过大上,针对上述0.45的mAP做了如下改进,最后mAP增加到了0.61:
(最近有点忙,以后再开一个博客详细写)
1、有的裂缝由于钢材是细长的原因都集中在一个方向,而划痕哪个方向都有,这俩类间比较相似,所以容易特定方向划痕被识别错误为裂缝,因此增加了裂缝的数据增强(自己与自己旋转拼接等)
2、由于图像主要呈现rgb的g 所以其他两个增强增加的泛化能力并没有意义 因此删除了这方面的增强(也有增加运算速度的作用)
3、类间差距过大,数据增强需要单独考虑,比如划痕这种就是倾向于每个图出现数次,因此可以考虑将划痕多做拼接操作。
4、在做拼接操作的时候不能把数据想象成人去做,比如斑块这个训练类别,拼接时会使得斑块拼接到一起形成新的板块,这样分别按照两个斑块去做数据框就不准了(下图如果上下拼接就是这种情况)
在这里插入图片描述

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐