我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Yolov7训练自己的数据集(超详细教程)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Yolov7训练自己的数据集(超详细教程)

目录

一,准备数据集

1.1 挑选照片

1.2 做标注

二,下载YoloV7

三,划分数据集

四,模型训练

4.1 创建yaml文件

4.2 修改默认参数

4.3 开始训练

五,训练模型遇到的问题

5.1 UnicodeDecodeError: 'gbk' codec can't decode type 0xaf in position 525: illegal multibyte sequence

5.2  subprocess.Called processError: Command 'git tag' returned non-zero exit status 128

六,测试

七,解决标签中文显示问题


一,准备数据集

1.1 挑选照片

  公主做的是缺陷检测方向,没有好办法,只能靠人眼,公主试过用阈值分割法来挑选,但是!如果阈值分割法能准确分离缺陷,就不用用yolo了不是?特别是灰度相近,而且每张照片灰度都不同,背景与缺陷灰度对比度很接近,比如上图中的硌伤~特别是背景有噪声的时候如下图,阈值分割法就直接躺平了~                                      

       没办法,从4T的数据里挑出来,挑的公主眼睛都要瞎了~~~

1.2 做标注

  公主用的labelImg,大部分做yolo标注都用这个,也是很主流的标注工具,安装方法见公主另一篇博客。那篇博客标注方法没写全,在这里详细介绍一下:

  (1)修改默认标签。公主先只做了一种缺陷,缺陷名称为“硌伤”,因此只写了一种class。在labelImg的安装文件夹中的data/predefined_classes里面修改class:

  (2)创建images文件夹和labels文件夹,可以放在任意的文件夹下。将挑选出的照片放到images的文件夹中。

  (3)在cmd中cd到labelImg文件夹下,运行python labelImg命令打开labelImg主页面。或者直接在pycharm的Terminal中打开也行,公主是直接用pycharm的Terminal来运行的。

      (4)在主页面上打开待标注文件,进行标注

  labelImg如上图所示。

    • 第一步先将标注类型改为YOLO,这一步非常关键!
    • 第二部修改Save Dir到之前创建的labels的文件夹
    • 第三步Open Dir,打开之前创建的images文件夹,此时会出现4框中的所有文件
    • 双击想要标注的图像,通过Create RectBox在需要标注的位置画出框,选好标注类型就可以啦~
    • 可以选中View->Auto Save Mode,这样标注完就不用手动点Save了,直接点Next Image跳到下一张即可自动保存。
    • 此时可以看到labels文件夹中多了一个与图像同名的.txt文件,即为标注文件啦!注意,标注与图片是一一对应的!

  labels的格式如下:

二,下载YoloV7

  下载地址

  下载之后的目录结构是这样的:

三,划分数据集

  由于公主是一股脑将所有图像放到一起了,由于工业生产的特殊性,临近时间产生的缺陷相似,因此需要随机将图像拆分为训练集,验证集及测试集。

  在yolov7-main主文件夹下创建data.py, 并在datasets文件夹下创建defect文件夹,目录结构如下:红框画出的文件是下面代码运行完后自动生成的。  

  公主在这篇博客的代码基础上修改了一下,同时生成了yolov7需要的目录文件,代码如下:

# 将图片和标注数据按比例切分为 训练集和测试集import shutilimport randomimport os# 原始路径image_original_path = "./mydata/images/"label_original_path = "./mydata/label/"cur_path = os.getcwd()# 训练集路径train_image_path = os.path.join(cur_path, "datasets/defect/images/train/")train_label_path = os.path.join(cur_path, "datasets/defect/labels/train/")# 验证集路径val_image_path = os.path.join(cur_path, "datasets/defect/images/val/")val_label_path = os.path.join(cur_path, "datasets/defect/labels/val/")# 测试集路径test_image_path = os.path.join(cur_path, "datasets/defect/images/test/")test_label_path = os.path.join(cur_path, "datasets/defect/labels/test/")# 训练集目录list_train = os.path.join(cur_path, "datasets/defect/train.txt")list_val = os.path.join(cur_path, "datasets/defect/val.txt")list_test = os.path.join(cur_path, "datasets/defect/test.txt")train_percent = 0.6val_percent = 0.2test_percent = 0.2def del_file(path):    for i in os.listdir(path):        file_data = path + "\\" + i        os.remove(file_data)def mkdir():    if not os.path.exists(train_image_path):        os.makedirs(train_image_path)    else:        del_file(train_image_path)    if not os.path.exists(train_label_path):        os.makedirs(train_label_path)    else:        del_file(train_label_path)    if not os.path.exists(val_image_path):        os.makedirs(val_image_path)    else:        del_file(val_image_path)    if not os.path.exists(val_label_path):        os.makedirs(val_label_path)    else:        del_file(val_label_path)    if not os.path.exists(test_image_path):        os.makedirs(test_image_path)    else:        del_file(test_image_path)    if not os.path.exists(test_label_path):        os.makedirs(test_label_path)    else:        del_file(test_label_path)def clearfile():    if os.path.exists(list_train):        os.remove(list_train)    if os.path.exists(list_val):        os.remove(list_val)    if os.path.exists(list_test):        os.remove(list_test)def main():    mkdir()    clearfile()    file_train = open(list_train, 'w')    file_val = open(list_val, 'w')    file_test = open(list_test, 'w')    total_txt = os.listdir(label_original_path)    num_txt = len(total_txt)    list_all_txt = range(num_txt)    num_train = int(num_txt * train_percent)    num_val = int(num_txt * val_percent)    num_test = num_txt - num_train - num_val    train = random.sample(list_all_txt, num_train)    # train从list_all_txt取出num_train个元素    # 所以list_all_txt列表只剩下了这些元素    val_test = [i for i in list_all_txt if not i in train]    # 再从val_test取出num_val个元素,val_test剩下的元素就是test    val = random.sample(val_test, num_val)    print("训练集数目:{}, 验证集数目:{}, 测试集数目:{}".format(len(train), len(val), len(val_test) - len(val)))    for i in list_all_txt:        name = total_txt[i][:-4]        class="lazy" data-srcImage = image_original_path + name + '.bmp'        class="lazy" data-srcLabel = label_original_path + name + ".txt"        if i in train:            dst_train_Image = train_image_path + name + '.bmp'            dst_train_Label = train_label_path + name + '.txt'            shutil.copyfile(class="lazy" data-srcImage, dst_train_Image)            shutil.copyfile(class="lazy" data-srcLabel, dst_train_Label)            file_train.write(dst_train_Image + '\n')        elif i in val:            dst_val_Image = val_image_path + name + '.bmp'            dst_val_Label = val_label_path + name + '.txt'            shutil.copyfile(class="lazy" data-srcImage, dst_val_Image)            shutil.copyfile(class="lazy" data-srcLabel, dst_val_Label)            file_val.write(dst_val_Image + '\n')        else:            dst_test_Image = test_image_path + name + '.bmp'            dst_test_Label = test_label_path + name + '.txt'            shutil.copyfile(class="lazy" data-srcImage, dst_test_Image)            shutil.copyfile(class="lazy" data-srcLabel, dst_test_Label)            file_test.write(dst_test_Image + '\n')    file_train.close()    file_val.close()    file_test.close()if __name__ == "__main__":    main()

至此,数据集彻底准备完毕!

  CUDA的安装我是参考这篇博客

四,模型训练

4.1 创建yaml文件

   在data文件夹中创建新的yaml文件,本例中缺陷为硌痕(公主不知道硌痕怎么翻译,长得像气泡,就翻译成了bubble >_<)。把coco.yaml文件复制过来,根据自己的要求修改。

4.2 修改默认参数

  修改train.py中的默认参数,根据自己的情况修改,参数代表的意思可以参考这篇博客,讲的非常详细。

   公主只改了这三个,

    • --data:是必改的。
    • --epochs:公主的缺陷类型比较简单,好识别,因此只设了200个epochs,实际上150个左右的时候就差不多收敛了。
    • --batch-size:公主的显卡显存不太行,只设了8个。但照片数量少,只有一千张左右,因此速度也不算慢。
    • --img-size:本例训练集照片是512*512的,因此公主使用了默认的[640 640]

4.3 开始训练

  由于默认参数已经修改了,训练时直接运行命令

        即可。

      训练时:

 训练完毕会提示:

   最后一轮迭代的权重文件放在runs\train\exp6\weights\last.pt中,最好的权重文件放在runs\train\exp6\weights\bext.pt中。

五,训练模型遇到的问题

5.1 UnicodeDecodeError: 'gbk' codec can't decode type 0xaf in position 525: illegal multibyte sequence

        查了下原因是python和win10系统,打开文件时默认的编码方式冲突导致:python默认的是gbk,而win10默认的是utf-8,所以只要改一下python打开文件时,默认的编码就行。(PS:开始公主用的官网默认的 --batch-size 32,然后GPU out of memory了,改成16,还是out of memory,最后含泪改成8.截上图的时候还没到out of memory那一步,因此--batch-size还是32)

5.2  subprocess.Called processError: Command 'git tag' returned non-zero exit status 128

  主要原因是因为request请求访问github被墙,解决方案就是手动下载所需的yolov7.pt权重文件,地址为https://github.com/WongKinYiu/yolov7。下载之后放在主目录下,然后还要把train.py中的权重从yolo7.pt改为yolov7.pt,

六,测试

   在datasets\defect中新建一个文件夹testImages。运行detect.py   

 在runs\defect\exp2中打开文件查看

  哎呦,标的很准,可是,由于标签是中文,显示乱码“?????”怎么办呢?

七,解决标签中文显示问题

  为啥显示乱码呢?查了下资料,原来是opencv的cv2.putText()不支持中文。只能重写plots.py里的plot_one_box()函数,根据这篇博客的介绍。将plot_one_box重写如下:

def plot_one_box(x, img, color=None, label=None, line_thickness=3):    # Plots one bounding box on image img    tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1  # line/font thickness    color = color or [random.randint(0, 255) for _ in range(3)]    c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))    cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)    if label:        tf = max(tl - 1, 1)  # font thickness        t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]        font_size = t_size[1]        font = ImageFont.truetype(r"D:\YOLOV7\yolov7-main\Font\simsun.ttc", font_size, encoding="utf-8")        t_size = font.getsize(label)        c2 = c1[0] + t_size[0], c1[1] - t_size[1]        cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA)  # filled        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))        draw = ImageDraw.Draw(img)        draw.text((c1[0], c2[1]), label, (0, 0, 0), font=font)        # cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)                return cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)

 为了保证多个标签时能都保存下来

  detect.py文件,plot_one_box(xyxy, im0, ....) 修改为 im0 = plot_one_box(xyxy, im0, ...)

        plots.py文件,plot_one_box(box, mosaic,...) 修改为 mosaic = plot_one_box(box, mosaic,...)

最后得到结果: 

完美!!!!!

小插曲:在修改中文标签的时候,想用matplotlib.pyplot.imshow()来打印图片,无奈老是不显示。查了很久才发现是matplotlib.get_backend是agg,而agg不支持GUI画图。但在terminal里运行print(matplotlib.get_backend())明明是QtAgg.后来又在程序里打印,仍然是agg。抓狂了很久后才发现,在plots.py中作者写了这句:

 太坑了!!!手动改成matplotlib.use('Qt5Agg'),原码是matplotlib.use('Agg')。

PS:本文与Yolov7训练自己的数据集(超详细) - 玻璃公主 - 博客园一摸一样,都是公主的博客>_<

来源地址:https://blog.csdn.net/qing2019/article/details/127054577

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Yolov7训练自己的数据集(超详细教程)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

YOLOv8训练自己的数据集(详细教程)

YOLO是一种基于图像全局信息进行预测的目标检测系统,YOLOv8是ultralytics公司在2023年1月10号开源的YOLOv5的下一个重大更新版本,这篇文章主要给大家介绍了关于YOLOv8训练自己的数据集的相关资料,需要的朋友可以参考下
2023-01-17

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录