【YOLO5 项目实战】(3)PCB 缺陷检测

欢迎关注『youcans动手学模型』系列
本专栏内容和资源同步到 GitHub/youcans
【YOLO5 项目实战】(1)YOLO5 环境配置与测试
【YOLO5 项目实战】(2)使用自己的数据集训练目标检测模型
【YOLO5 项目实战】(3)PCB 缺陷检测


1. PCB 缺陷检测问题

印制电路板(简称PCB)是组装电子零件用的基板,PCB板的制造品质直接影响电子产品的可靠性。随着电子组装向更高密度、更小尺寸的PCB混合技术的纵深发展,为减少进入下步工序的缺陷电路板的数量,对PCB检测的自动光学检测(AOI)系统的需求也越来越大。

AOI系统是基于机器视觉技术应用的自动化检测系统,由图像采集单元、光源和主机组成,采用高清相机和高速图像处理软件进行实时检测,提取PCB表面图形、通过图形数字化转换、特征点逻辑判断与图形匹配、线条形态轮廓逻辑比对、缺陷点判定与提取这一技术流程来实现PCB表面图形的缺陷检测。

AOI系统作为基于机器视觉的自动化检测工具,具有高速、高效、高精度的特点,广泛应用于PCB检测。它能尽早发现并纠正缺陷,提高SMT生产工艺的成品率,并能适应高密度PCB组装的检测需求。

传统的 PCB 缺陷检测技术,通常基于数字图像处理技术进行处理。例如:首先读取图片,然后进行开运算和闭运算以预处理图像,接着使用动态阈值分割方法提取缺陷区域,最后展示原图和检测出的缺陷边缘。常用处理算法包括:

  • Blob分析+特征检测
  • Blob分析+特征检测+差分
  • 频域滤波+空间滤波
  • 光度立体法
  • 特征训练(分类器,深度学习)
  • 测量+拟合

近年来随着深度学习技术的发展,基于深度学习的PCB板缺陷检测方法取得了显著的进步。YOLO(You Only Look Once)系列算法,以其快速、准确的特点,在实时缺陷检测领域受到广泛关注。

一种基于 YOLO5 PCB板缺陷检测系统,面临的挑战包括:

  • PCB板缺陷检测的准确性和速度
  • 环境适应性和模型泛化能力
  • 用户交互界面的直观性和功能性
  • 数据处理能力和存储效率
  • 系统的可扩展性和维护性

2. PCB 缺陷数据集

2.1 下载 PCB 瑕疵数据集

北大印刷电路板(PCB)瑕疵数据集
北大智能机器人开放实验室提供的 印刷电路板(PCB)瑕疵数据集,是一个公共合成PCB数据集,包含1386张图像,具有6种缺陷(漏孔、鼠咬、开路、短路、杂散、杂铜),用于图像检测、分类和配准任务。

使用百度AI stduio下载,选择 PCB_DATASET_VOC.zip 下载。下载数据集的结构如下:

- DataSetPCB
   - Annotations
   - ImageSets

在这里插入图片描述

DeepPCB 瑕疵数据集:
一个数据集包含1500个图像对,每个图像对由一个无缺陷的模板图像和一个对齐的测试图像组成,带有注释,包括6种最常见的PCB缺陷的位置:开路、短路、鼠咬、毛刺、针孔和假铜。每张 640 x 640图像中大约有3到12个缺陷。推荐将1000张图像作为训练集,将剩余图像作为测试集。


2.2 构建 PCB 缺陷数据集

下载的 PCB 瑕疵数据集与 YOLOv5 的格式不一致,本文以北大 PCB 瑕疵数据集为例,构建 YOLOv5 数据集。

2.2.1 划分训练/测试数据集

把原始数据集划分为训练集、测试集和验证集,处理代码 split_train_val.py如下:

import os
import random
import argparse

parser = argparse.ArgumentParser()
# 数据集的标注文件夹的路径,默认 '\Annotations'
parser.add_argument('--xml_path', default='Annotations', type=str, help='input xml label path')
# 数据集的图像文件夹的路径,默认 '\ImageSets'
parser.add_argument('--txt_path', default='ImageSets', type=str, help='output txt label path')
opt = parser.parse_args()

xmlfilepath = opt.xml_path
txtsavepath = opt.txt_path
# xmlfilepath = '\Annotations'
# txtsavepath = '\Images'

total_xml = os.listdir(xmlfilepath)
if not os.path.exists(txtsavepath):
    os.makedirs(txtsavepath)

trainval_percent = 0.9
train_percent = 0.8
num = len(total_xml)
list_index = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list_index, tv)
train = random.sample(trainval, tr)

file_trainval = open(txtsavepath + '/trainval.txt', 'w')
file_test = open(txtsavepath + '/test.txt', 'w')
file_train = open(txtsavepath + '/train.txt', 'w')
file_val = open(txtsavepath + '/val.txt', 'w')

for i in list_index:
    name = total_xml[i][:-4] + '\n'
    print(name)

    if i in trainval:
        file_trainval.write(name)
        if i in train:
            file_train.write(name)
        else:
            file_val.write(name)
    else:
        file_test.write(name)

file_trainval.close()
file_train.close()
file_val.close()
file_test.close()

2.2.2 标签格式转换

(1)该 PCB 瑕疵数据集 采用 VOC 的标签格式,保存在 Annotations 子目录中。
以 01_missing_hole_01.xml 为例,内容如下:

<annotation>
	<folder>Missing_hole</folder>
	<filename>01_missing_hole_01.jpg</filename>
	<path>/home/weapon/Desktop/PCB_DATASET/Missing_hole/01_missing_hole_01.jpg</path>
	<source>
		<database>Unknown</database>
	</source>
	<size>
		<width>3034</width>
		<height>1586</height>
		<depth>3</depth>
	</size>
	<segmented>0</segmented>
	<object>
		<name>missing_hole</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>2459</xmin>
			<ymin>1274</ymin>
			<xmax>2530</xmax>
			<ymax>1329</ymax>
		</bndbox>
	</object>
	<object>
		<name>missing_hole</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>1613</xmin>
			<ymin>334</ymin>
			<xmax>1679</xmax>
			<ymax>396</ymax>
		</bndbox>
	</object>
	<object>
		<name>missing_hole</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>1726</xmin>
			<ymin>794</ymin>
			<xmax>1797</xmax>
			<ymax>854</ymax>
		</bndbox>
	</object>
</annotation>

(2)把 VOC 的标签格式转换为yolov5的格式,Python 代码如下:

# 将 xml 标签格式转换为 yolov5 格式
# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import os
from os import getcwd

# box [xmin,ymin,xmax,ymax]
def convert(size, box):
    dw = 1. / (size[0])
    dh = 1. / (size[1])
    x = (box[0] + box[1]) / 2.0 - 1
    y = (box[2] + box[3]) / 2.0 - 1
    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

# xml2yolo
def convert_annotation(image_id):
    in_file = open('Annotations/%s.xml' % (image_id), encoding='UTF-8')
    out_file = open('Labels/%s.txt' % (image_id), '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'):
        difficult = obj.find('difficult').text
        # difficult = obj.find('Difficult').text
        cls = obj.find('name').text
        if cls not in classes or int(difficult) == 1:
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        b1, b2, b3, b4 = b
        # 标注越界修正
        if b2 > w:
            b2 = w
        if b4 > h:
            b4 = h
        b = (b1, b2, b3, b4)
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


sets = ['train', 'val', 'test']
classes = ["missing_hole", "mouse_bite", "open_circuit", "short", "spur", "spurious_copper"]  # 修改为PCB缺陷类别
abs_path = os.getcwd()
wd = getcwd()

if not os.path.exists('Labels/'):
    os.makedirs('Labels/')
    
for image_set in sets:
    image_ids = open('ImageSets/%s.txt' % (image_set)).read().strip().split()
    list_file = open('%s.txt' % (image_set), 'w')
    print(image_set, image_ids)
    for image_id in image_ids:
        list_file.write('/Images/%s.jpg\n' % (image_id))
        convert_annotation(image_id)
    list_file.close()

(3)程序创建 Labels 子目录,生成 YOLOv5格式的标签文件。

以 01_missing_hole_01.txt 为例,内容如下:

0 0.821852340145023 0.8199873896595208 0.02340145023071852 0.03467843631778058
0 0.542188529993408 0.22950819672131148 0.02175346077785102 0.03909205548549811
0 0.5802570863546472 0.5189155107187894 0.02340145023071852 0.03783102143757881

2.3 数据集配置文件

YOLOv5 模型训练时,要调用数据集配置文件 YAML 文件( .yaml)。因此,需要在数据集所在的文件夹(例如…/DataSetYoloPCB/)创建自己的数据集配置文件 dataPCB.yaml,内容如下

train: ../DataSetYoloPCB/train/images
val: ../DataSetYoloPCB/valid/images
test: ../DataSetYoloPCB/test/images # test images (optional)

# number of classes
nc: 6

# Class names
names: ["missing_hole", "mouse_bite", "open_circuit", "short", "spur", "spurious_copper"]

其中,train 表示训练集图像文件夹的路径,val 表示验证集图像文件夹的路径,test 表示测试集图像文件夹的路径。nc:6 表示类别数为 6,names 表示 6个类别的名称。

注意,nc 是由数据集的标注内容决定的,不能自行修改。


3. 训练 PCB 缺陷模型

3.1 下载 YOLOv5 预训练模型

推荐从 YOLOv5 release下载 YOLOv5 预训练模型。

本文选择 YOLOv5s,参数约 7.2M。下载完成后,将下载的预训练模型文件 yolov5s.pt 放在 YOLOv5 项目路径下。


3.2 修改 YOLOv5 模型配置

在 yolov5/models/ 目录下,打开模型配置文件 yolov5s.yaml,把文件中的类别数改为 6 ,另存为 /models/yolov5sPCB.yaml。

# Ultralytics YOLOv5 🚀, AGPL-3.0 license

# Parameters
nc: 6 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
anchors:
  - [10, 13, 16, 30, 33, 23] # P3/8
  - [30, 61, 62, 45, 59, 119] # P4/16
  - [116, 90, 156, 198, 373, 326] # P5/32
...  

3.3 YOLOv5 模型训练

1. 运行训练程序查看帮助
从 PyCharm 命令行输入“ python train.py -h” 可以查看帮助,也可以检查程序是否有错误。

输出如下:

(torch) PS C:\Python\PythonProjects\YOLOv5_PCB> python train.py -h
usage: train.py [-h] [--weights WEIGHTS] [--cfg CFG] [--data DATA] [--hyp HYP] [--epochs EPOCHS] [--batch-size BATCH_SIZE] [--imgsz IMGSZ] [--rect] [--resume [RESUME]] [--nosave] [--noval] [--noautoanchor] [--noplots]
                [--evolve [EVOLVE]] [--evolve_population EVOLVE_POPULATION] [--resume_evolve RESUME_EVOLVE] [--bucket BUCKET] [--cache [CACHE]] [--image-weights] [--device DEVICE] [--multi-scale] [--single-cls]
                [--optimizer {SGD,Adam,AdamW}] [--sync-bn] [--workers WORKERS] [--project PROJECT] [--name NAME] [--exist-ok] [--quad] [--cos-lr] [--label-smoothing LABEL_SMOOTHING] [--patience PATIENCE]
                [--freeze FREEZE [FREEZE ...]] [--save-period SAVE_PERIOD] [--seed SEED] [--local_rank LOCAL_RANK] [--entity ENTITY] [--upload_dataset [UPLOAD_DATASET]] [--bbox_interval BBOX_INTERVAL]
                [--artifact_alias ARTIFACT_ALIAS] [--ndjson-console] [--ndjson-file]

optional arguments:
  -h, --help            show this help message and exit
  --weights WEIGHTS     initial weights path
  --cfg CFG             model.yaml path
  --data DATA           dataset.yaml path
  --hyp HYP             hyperparameters path
  --epochs EPOCHS       total training epochs
  --batch-size BATCH_SIZE
                        total batch size for all GPUs, -1 for autobatch
  --device DEVICE       cuda device, i.e. 0 or 0,1,2,3 or cpu
...

使用自己的数据集训练 YOLOv5 模型,,需要注意检查以下路径或参数值:

  • weight,预训练模型权重文件,先选择下载的官方权重文件 yolov5s.pt。
  • cfg,yolov5s 模型配置文件,选择修改的 models/yolov5sPCB.yaml。
  • data,选择自己编写的数据集配置文件 DataSetYoloPCB/data.yaml。
  • hyp HYP,超参数文件路径,可以修改模型训练参数,本文未涉及。
  • epoch,整个数据集遍历训练次数,根据计算机性能和需要确定,默认值100,新手练习时可以设为 2。
  • batch_size,每批读入的样本数量,根据计算机内存确定,默认值8,新手练习时可以设为 2。
  • device,cuda 显卡设置,默认值为 0 表示使用 CPU训练,如有 GPU 显卡可以设为 1 或相应值。

2. 运行训练程序 train.py

通过命令行就可以运行 YOLOv5 训练程序 train.py 。

如果计算机性能资源不足,可以设置较小的训练参数以便学习,例如:

python train1.py --weights yolov5s.pt --cfg models/yolov5sPCB.yaml --data …/DataSetYoloPCB/dataPCB.yaml --epoch 2 --batch-size 4

本文设置的遍历次数 epoch=100,批次数 batch-size=16,使用 GPU 训练。

python train1.py --weights yolov5s.pt --cfg models/yolov5sPCB.yaml --data …/DataSetYoloPCB/dataPCB.yaml --epoch 100 --batch-size 16 --img 640 --device 1

经过100 epochs的训练,结果如下:

(torch) PS C:\Python\PythonProjects\YOLOv5_PCB> python train1.py --weights yolov5s.pt  --cfg models/yolov5sPCB.yaml  --data ../DataSetYoloPCB/dataPCB.yaml --epoch 100 --batch-size 16 --img 640 --device 1
train1: weights=yolov5s.pt, cfg=models/yolov5sPCB.yaml, data=../DataSetYoloPCB/data.yaml, hyp=data\hyps\hyp.scratch-low.yaml, epochs=100, batch_size=16, imgsz=640, rect=False, resume=False, nosave=False, noval=False, noautoancho
r=False, noplots=False, evolve=None, evolve_population=data\hyps, resume_evolve=None, bucket=, cache=None, image_weights=False, device=1, multi_scale=False, single_cls=False, optimizer=SGD, sync_bn=False, workers=8, project=runs
\train, name=exp, exist_ok=False, quad=False, cos_lr=False, label_smoothing=0.0, patience=100, freeze=[0], save_period=-1, seed=0, local_rank=-1, entity=None, upload_dataset=False, bbox_interval=-1, artifact_alias=latest, ndjson_console=False, ndjson_file=False

hyperparameters: lr0=0.01, lrf=0.01, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=0.05, cls=0.5, cls_pw=1.0, obj=1.0, obj_pw=1.0, iou_t=0.2, anchor_t=4.0, fl_gamma=0.0, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.1, scale=0.5, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, mosaic=1.0, mixup=0.0, copy_paste=0.0

Transferred 342/349 items from yolov5s.pt
AMP: checks passed 
optimizer: SGD(lr=0.01) with parameter groups 57 weight(decay=0.0), 60 weight(decay=0.0005), 60 bias
train: Scanning C:\Python\PythonProjects\DataSetYoloPCB\train\labels... 554 images, 0 backgrounds, 0 corrupt: 100%|██████████| 554/554 [00:06<00:00, 83.51it/s] 
train: WARNING  Cache directory C:\Python\PythonProjects\DataSetYoloPCB\train is not writeable: [WinError 183] : 'C:\\Python\\PythonProjects\\DataSetYoloPCB\\train\\labels.cache.npy' -> 'C:\\Python\\PythonProjects\\DataSetYoloPCB\\train\\labels.cache'
val: Scanning C:\Python\PythonProjects\DataSetYoloPCB\valid\labels... 139 images, 0 backgrounds, 0 corrupt: 100%|██████████| 139/139 [00:13<00:00, 10.59it/s]
val: WARNING  Cache directory C:\Python\PythonProjects\DataSetYoloPCB\valid is not writeable: [WinError 183] : 'C:\\Python\\PythonProjects\\DataSetYoloPCB\\valid\\labels.cache.npy' -> 'C:\\Python\\PythonProjects\\DataSetYoloPCB\\valid\\labels.cache'

AutoAnchor: 3.75 anchors/target, 1.000 Best Possible Recall (BPR). Current anchors are a good fit to dataset
Plotting labels to runs\train\exp5\labels.jpg... 
Image sizes 640 train, 640 val
Using 8 dataloader workers
Logging results to runs\train\exp5
Starting training for 100 epochs...

      Epoch    GPU_mem   box_loss   obj_loss   cls_loss  Instances       Size
       0/99      3.53G     0.1255    0.02683    0.05101         67        640: 100%|██████████| 35/35 [00:20<00:00,  1.75it/s]
                 Class     Images  Instances          P          R      mAP50   mAP50-95: 100%|██████████| 5/5 [00:01<00:00,  3.04it/s]
                   all        139        598    4.3e-05    0.00149   2.18e-05   4.36e-06

...

      Epoch    GPU_mem   box_loss   obj_loss   cls_loss  Instances       Size
      99/99      4.69G    0.03025    0.01333   0.003239         46        640: 100%|██████████| 35/35 [00:22<00:00,  1.56it/s]
                 Class     Images  Instances          P          R      mAP50   mAP50-95: 100%|██████████| 5/5 [00:01<00:00,  3.25it/s]
                   all        139        598      0.959      0.941      0.957      0.486


100 epochs completed in 0.637 hours.
Optimizer stripped from runs\train\exp5\weights\last.pt, 14.5MB
Optimizer stripped from runs\train\exp5\weights\best.pt, 14.5MB

Validating runs\train\exp5\weights\best.pt...
Fusing layers... 
YOLOv5sPCB summary: 157 layers, 7026307 parameters, 0 gradients, 15.8 GFLOPs
                 Class     Images  Instances          P          R      mAP50   mAP50-95: 100%|██████████| 5/5 [00:03<00:00,  1.26it/s]
                   all        139        598      0.956      0.943      0.958      0.487
          missing_hole        139        112      0.981      0.991      0.987      0.594
            mouse_bite        139         83      0.924      0.916      0.937       0.46
          open_circuit        139         85      0.965      0.967      0.971      0.451
                 short        139        116       0.97      0.983      0.989      0.483
                  spur        139         97      0.947      0.876      0.918      0.445
       spurious_copper        139        105      0.946      0.924      0.946      0.491
Results saved to runs\train\exp5

其中,Epoch 为遍历次数,GPU_mem 为占用的显卡内存,box_loss 为边界框损失值,obj_loss为置信度损失值,cls_loss 为分类损失值,Instances 为实例个数(矩形框个数),Size 为输入图像大小。Class 为类别名称,Images 为训练图像数量,Instances 为实例个数,P 为准确率,R为召回率,mAP50为IoU阈值0.5的平均精度均值,maP50-95表示在不同IoU阈值(0.5~0.95)的平均精度均值。

训练好的模型,保存在路径:“runs/exp/weights”,best.pt 是最好结果,last.pt 是最后结果。


3.4 模型训练结果

经过 100 轮遍历训练,训练过程及结果文件保存在目录 “runs”,如下图所示:

在这里插入图片描述

(1)损失函数下降曲线
YOLOv5 中定义的损失函数包括:

  • 边界框定位损失(box_loss):计算预测边界框与标注边界框之间的误差(GIoU)
  • 分类损失(cls_loss):计算预测类别与对应的标注类别是否正确
  • 动态特征损失(dfl_loss):计算回归预测框与目标框之间距离的损失函数

请添加图片描述

(2)置信度曲线

  • F1 置信曲线,F1得分随着置信度阈值的变化。F1得分是精确度和召回率的调和平均值,曲线的峰值表示给定置信度阈值下精确度和召回率的最佳平衡点。
  • 精确度置信曲线,模型预测的精确度随着置信度阈值的变化。精确度是模型预测正确正例与预测为正例总数的比值。
  • 精确度召回曲线(PR曲线),模型的精确度与召回率之间的关系。理想情况下,模型应在精确度和召回率之间保持良好的平衡。
  • 召回置信度曲线,模型的召回率随置信度阈值的变化。召回率是模型正确预测的正例与实际正例总数的比值。

在这里插入图片描述
训练好的模型,保存在路径:“runs/exp/weights”,best.pt 是最好结果,last.pt 是最后结果。可以使用该文件进行模型推理,检测PCB缺陷。


4. 模型推理

4.1 修改推理程序 detect.py

detect.py 程序使用PyTorch加载预训练的YOLOv5模型。程序解析从命令行传入的参数,这些参数包括输入文件的路径(可以是图像、视频或目录)、预训练模型的路径、输出文件的路径、置信度阈值等。具体用法如下:

Usage - sources:
    $ python detect.py --weights yolov5s.pt --source 0                               # webcam
                                                     img.jpg                         # image
                                                     vid.mp4                         # video
                                                     screen                          # screenshot
                                                     path/                           # directory
                                                     list.txt                        # list of images
                                                     list.streams                    # list of streams
                                                     'path/*.jpg'                    # glob
                                                     'https://youtu.be/LNwODJXcvt4'  # YouTube
                                                     'rtsp://example.com/media.mp4'  # RTSP, RTMP, HTTP stream

detect.py 程序默认读取 data\images 路径的图片,结果默认保存到 runs/detect 文件夹中。

我们根据项目的配置,要对推理程序 detect.py 进行如下修改(也可以直接通过命令行参数设置):

def parse_opt():
    parser = argparse.ArgumentParser()
    parser.add_argument("--weights", nargs="+", type=str, default=ROOT / "weights/yolov5PCBbest.pt", help="model path or triton URL")
    parser.add_argument("--source", type=str, default=ROOT / "data/images", help="file/dir/URL/glob/screen/0(webcam)")
    parser.add_argument("--data", type=str, default=ROOT / "data/dataPCB.yaml", help="(optional) dataset.yaml path")
...

其中:yolov5PCBbest.pt 是前面训练的 PCB 缺陷检测模型的权重文件,已另存为 “weights/yolov5PCBbest.pt”;“data/images” 是保存 PCB 测试图片的路径;dataPCB.yaml 是前面修改的数据集配置文件,已另存为 “data/dataPCB.yaml”。


4.2 运行推理程序检测 PCB 缺陷

打开并运行 YOLOv5 项目中的 detect.py 程序,使用训练的PCB 缺陷检测模型 “weights/yolov5PCBbest.pt” 进行 PCB 缺陷。

python detect.py

运行输出如下:

(torch) PS C:\Python\PythonProjects\YOLOv5_PCB> python detect.py
detect: weights=weights\yolov5PCBbest.pt, source=data\images, data=data\dataPCB.yaml, imgsz=[640, 640], conf_thres=0.25, iou_thres=0.45, max_det=1000, device=, view_img=False, save_txt=False, save_csv=False, save_conf=False, save_crop=False, nosave=False, classes=None, agnostic_nms=False, augment=False, visualize=False, update=False, project=runs\detect, name=exp, exist_ok=False, line_thickness=3, hide_labels=False, hide_conf=False, half=False, dnn=False, vid_stride=1
YOLOv5  2024-7-29 Python-3.8.19 torch-2.3.1+cu121 CUDA:0 (NVIDIA GeForce RTX 3060, 12288MiB)


Fusing layers... 
YOLOv5sPCB summary: 157 layers, 7026307 parameters, 0 gradients, 15.8 GFLOPs
image 1/3 C:\Python\PythonProjects\YOLOv5_PCB\data\images\01_missing_hole_14.jpg: 352x640 3 missing_holes, 48.0ms
image 2/3 C:\Python\PythonProjects\YOLOv5_PCB\data\images\01_short_17.jpg: 352x640 4 shorts, 4.0ms
image 3/3 C:\Python\PythonProjects\YOLOv5_PCB\data\images\06_mouse_bite_10.jpg: 544x640 5 mouse_bites, 50.0ms
Speed: 0.3ms pre-process, 34.0ms inference, 4.0ms NMS per image at shape (1, 3, 640, 640)
Results saved to runs\detect\exp

请添加图片描述


5. 报错处理

(1)Pytorch没有下载成功:
报错内容:Module Not Found Error: No module named ‘torch’
解决方法:通过 Anaconda 或 miniconda 重新下载安装 Pytorch。

(2)PyYaml 版本错误:
报错内容:AttributeError: ‘yaml’ has no attribute ‘FullLoader’
解决方法:卸载高版本 PyYaml,安装 PyYaml 5.3 版本:

pip install pyyaml==5.3

(3)Git 执行发生错误
报错内容:ImportError: Bad git executable.
解决方法:按照报错信息找到git下的cmd文件,添加下方代码:

import os
os.environ["GIT_PYTHON_REFRESH"] = "quiet"

(4)Numpy 版本问题
报错内容:AttributeError: module ‘numpy’ has no attribute ‘float’.
解决方法:不再使用 np.float ,需要将其修改为 np.float64 。

【本节完】


版权声明:
欢迎关注『youcans动手学模型』系列
转发请注明原文链接:
【YOLO5 项目实战】(3)PCB 缺陷检测
Copyright 2024 youcans, XUPT
Crated:2024-08-12


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

youcans_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值