(4)paddle---PCB检测的例子

1、主要参考

(1)大佬教程

基于PaddleDetection的PCB瑕疵检测_AI Studio的博客-CSDN博客

(2)blibli视频

253-14_PCB电路板缺陷检测_项目配置文件_dec_哔哩哔哩_bilibili

(3)coco数据集说明

『深度应用』目标检测coco数据集格式介绍 - 腾讯云开发者社区-腾讯云

2、模型的下载

(1)下载地址

北京大学智能机器人开放实验室

 印刷电路板(PCB)瑕疵数据集。它是一个公共合成PCB数据集,包含1386张图像,具有6种缺陷(漏孔、鼠咬、开路、短路、杂散、杂铜),用于图像检测、分类和配准任务

看了一下,上面地址下载的数据集,是voc格式的

(2)根据百度教程来的话可以通过AIstudio直接下载

3、模型的特征查看

(1)查看各个缺陷的分布情况(类别数是否均匀,如果不均匀可以考虑调整loss的计算方法

(2)查看锚框的长宽比,看看都是什么形状的

(3)看看锚框的大小(和原图大小的比值,看看是不是都是小物体

(4)文件pcb_dataset_analysis.py如下

import json
from collections import defaultdict
import matplotlib.pyplot as plt
%matplotlib inline

with open("/home/aistudio/work/PCB_DATASET/Annotations/train.json") as f:
    data = json.load(f)

imgs = {}
for img in data['images']:
    imgs[img['id']] = {
        'h': img['height'],
        'w': img['width'],
        'area': img['height'] * img['width'],
    }

hw_ratios = []
area_ratios = []
label_count = defaultdict(int)
for anno in data['annotations']:
    hw_ratios.append(anno['bbox'][3]/anno['bbox'][2])
    area_ratios.append(anno['area']/imgs[anno['image_id']]['area'])
    label_count[anno['category_id']] += 1

#查看各个缺陷的分布情况(类别数是否均匀,如果不均匀可以考虑调整loss的计算方法)
print( label_count, len(data['annotations']) / len(data['images']) )

#查看锚框的长宽比,看看都是什么形状的
plt.hist(hw_ratios, bins=100, range=[0, 2])
plt.show()

#看看锚框的大小(和原图大小的比值,看看是不是都是小物体)
plt.hist(area_ratios, bins=100, range=[0, 0.005])
plt.show()

1)各个缺陷的分布和每张图的缺陷数如下

#查看各个缺陷的分布情况(类别数是否均匀,如果不均匀可以考虑调整loss的计算方法)
print( label_count, len(data['annotations']) / len(data['images']) )

 2)长宽比的分布如下

#查看锚框的长宽比,看看都是什么形状的
plt.hist(hw_ratios, bins=100, range=[0, 2])
plt.show()

 3)锚框和图的面积比如下

#看看锚框的大小(和原图大小的比值,看看是不是都是小物体)
plt.hist(area_ratios, bins=100, range=[0, 0.005])
plt.show()

4、下载paddle的object项目

4.1 下载

(1)paddle官网

飞桨PaddlePaddle-源于产业实践的开源深度学习平台

(2)下载指定PaddleDetection

 (3)对应的github地址如下

https://github.com/PaddlePaddle/PaddleDetection

4.2安装相关环境

#(1)在对应目录下
conda activate chenpaddle_cp310

#(2)安装相关环境
pip install -r requirements.txt 

pip install pycocotools

5、基于faster-rcnn的PCB缺陷检测

(1)一下参考来自官网

基于PaddleDetection的PCB瑕疵检测-FasterRCNN - 飞桨AI Studio

(2)配置参数

在检测目录下创建chenfastrcnn 目录,然后创建文件pcb_faster_rcnn_r50_fpn_3x_coco.yml内容如下 

metric: COCO           # Label评价指标,coco IoU:0.5:0.95
num_classes: 7         # 类别数量,coco类别比实际类别(voc类别)+1

TrainDataset:
  !COCODataSet
    image_dir: images
    anno_path: Annotations/train.json
    dataset_dir: /home/chen/deep_data/pcb/PCB_DATASET_AI_STUDIO/PCB_DATASET
    data_fields: ['image', 'gt_bbox', 'gt_class']#, 'is_crowd'

EvalDataset:
  !COCODataSet
    image_dir: images
    anno_path: Annotations/val.json
    dataset_dir: /home/chen/deep_data/pcb/PCB_DATASET_AI_STUDIO/PCB_DATASET

TestDataset:
  !ImageFolder
    anno_path: Annotations/val.json


use_gpu: true                          # 根据硬件选择是否使用GPU 
log_iter: 10                           # 日志窗口的尺度
save_dir: output/     # 模型输出文件夹
snapshot_epoch: 1                      # 生成快照的频率,即每1个周期生成一次

epoch: 24                      ### 训练周期:24

LearningRate:                  ### 学习率:阶段学习率
  base_lr: 0.0025              # 起始学习率:0.0025 
  schedulers:
  - !PiecewiseDecay            ## 阶段学习率
    gamma: 0.1                 # 每次学习率变化为原来的1/10
    milestones: [16, 22]       # 总共进行两次学习率的降低
  - !LinearWarmup              ## 慢启动,共执行200次迭代,学习率为初始学习率的0.1
    start_factor: 0.1
    steps: 200

OptimizerBuilder:              ### 优化方法:基于动量的SGD
  optimizer:
    momentum: 0.9
    type: Momentum
  regularizer:
    factor: 0.0001
    type: L2

architecture: FasterRCNN                   # 总框架类型
# 预训练模型
pretrain_weights: https://paddledet.bj.bcebos.com/models/pretrained/ResNet50_cos_pretrained.pdparams

## 检测模型的体系结构,包含骨干、支路、区域建议、BBox头和BBox头后处理
FasterRCNN:
  backbone: ResNet                        # 主干网络:ResNet
  neck: FPN                               # 特征金字塔网络
  rpn_head: RPNHead                       # 区域建议头:基于FPN的RPNHead
  bbox_head: BBoxHead                     # BBox头:BBoxHead
  # post process   
  bbox_post_process: BBoxPostProcess      # BBox后处理器

ResNet:
  # index 0 stands for res2
  depth: 50                               # 深度50,即ResNet50
  norm_type: bn                           # 正则化类型BN,基本上是唯一选择
  freeze_at: 0                            # 冻结部分,ResNet的前两层
  return_idx: [0,1,2,3]                   # 提取特征的位置,即用于FPN的特征,其实index为0
  num_stages: 4

FPN:
  out_channel: 256                        # FPN通道数:256

RPNHead:
  anchor_generator:                                    ## Anchor生成器
    aspect_ratios: [0.5, 1.0, 2.0]                     # Anchor的比例1:2,1:1,2:1
    anchor_sizes: [[32], [64], [128], [256], [512]]    # Anchor的尺度
    strides: [4, 8, 16, 32, 64]                        # Anchor的步长
  rpn_target_assign:                                   ## RPN设置
    batch_size_per_im: 256                             # RPN采样数量: 256 
    fg_fraction: 0.5                                   # 正样本数量: 256*0.5=128   
    negative_overlap: 0.3                              # 负样本IoU<0.3 
    positive_overlap: 0.7                              # 正阳IoU>0.7
    use_random: True
  train_proposal:                                      ## 训练建议框设置
    min_size: 0.0                                      
    nms_thresh: 0.7                                    # 训练阶段nms阈值
    pre_nms_top_n: 2000                                # 第一阶段nms数量
    post_nms_top_n: 1000                               # 第二阶段nms数量
    topk_after_collect: True
  test_proposal:                                       ## 测试建议框设置
    min_size: 0.0
    nms_thresh: 0.7                                    # 测试阶段nms阈值     
    pre_nms_top_n: 1000                                # 第一阶段nms数量
    post_nms_top_n: 1000                               # 第二阶段nms数量

BBoxHead:                                              ## BBox头
  head: TwoFCHead                                      # 两个FC头
  roi_extractor:
    resolution: 7                                      # RoIPooling特征层的尺度7×7
    sampling_ratio: 0
    aligned: True                                      # 启用RoIAlign
  bbox_assigner: BBoxAssigner

BBoxAssigner:
  batch_size_per_im: 512                               # batch数量:512
  bg_thresh: 0.5                                       # 背景阈值<0.5
  fg_thresh: 0.5                                       # 前景阈值>0.5
  fg_fraction: 0.25
  use_random: True

TwoFCHead:
  out_channel: 1024                                    # 全连接层特征维度(后面紧跟分类和回归层):1024


BBoxPostProcess:
  decode: RCNNBox
  nms:
    name: MultiClassNMS
    keep_top_k: 100
    score_threshold: 0.05
    nms_threshold: 0.5

worker_num: 2


TrainReader:
  sample_transforms:  # 数据预处理
  - Decode: {}
  - RandomResize: {target_size: [[640, 1333], [672, 1333], [704, 1333], [736, 1333], [768, 1333], [800, 1333]], interp: 2, keep_ratio: True}
  - RandomFlip: {prob: 0.5}
  - NormalizeImage: {is_scale: true, mean: [0.485,0.456,0.406], std: [0.229, 0.224,0.225]}
  - Permute: {}
  batch_transforms:   
  - PadBatch: {pad_to_stride: 32}
  batch_size: 1      # 每批大尺度
  shuffle: true      # 是否随机
  drop_last: true    # 最后一个batch不足batch_sizes时,是否将多余数据进行丢弃


EvalReader:
  sample_transforms:
  - Decode: {}
  - Resize: {interp: 2, target_size: [800, 1333], keep_ratio: True}
  - NormalizeImage: {is_scale: true, mean: [0.485,0.456,0.406], std: [0.229, 0.224,0.225]}
  - Permute: {}
  batch_transforms:
  - PadBatch: {pad_to_stride: 32}
  batch_size: 1
  shuffle: false
  drop_last: false
  drop_empty: false


TestReader:
  sample_transforms:
  - Decode: {}
  - Resize: {interp: 2, target_size: [800, 1333], keep_ratio: True}
  - NormalizeImage: {is_scale: true, mean: [0.485,0.456,0.406], std: [0.229, 0.224,0.225]}
  - Permute: {}
  batch_transforms:
  - PadBatch: {pad_to_stride: 32}
  batch_size: 1
  shuffle: false
  drop_last: false

(2)在PaddleDetection-release-2.5目录下的终端中执行如下命令

CUDA_VISIBLE_DEVICES=0


python -u tools/train.py -c /home/chen/chen_deep/02PaddleDetection/PaddleDetection-release-2.5/chenfastrcnn/pcb_faster_rcnn_r50_fpn_3x_coco.yml --eval 

或者

python -u tools/train.py -c /home/chen/chen_deep/02PaddleDetection/PaddleDetection-release-2.5/chenfastrcnn/pcb_faster_rcnn_r50_fpn_3x_coco.yml --eval -o use_gpu=True


或者

python -u tools/train.py -c /home/chen/chen_deep/02PaddleDetection/PaddleDetection-release-2.5/chenfastrcnn/pcb_faster_rcnn_r50_fpn_3x_coco.yml --eval -o use_gpu=False

(3)训练得到的模型在output下面

 (4)测试以下图片,以下命令还有问题,会报错

python -u tools/infer.py -c /home/chen/chen_deep/02PaddleDetection/PaddleDetection-release-2.5/chenfastrcnn/pcb_faster_rcnn_r50_fpn_3x_coco.yml                 --infer_img=/home/chen/deep_data/pcb/PCB_DATASET_AI_STUDIO/PCB_DATASET/images/04_missing_hole_10.jpg                 -o weights=output/pcb_faster_rcnn_r50_fpn_3x_coco/best_model.pdparams use_gpu=True

 

6、基于PP-YOLOE+的PCB缺陷检测

(1)以下引用参考来自paddle官网

基于PP-YOLOE+的PCB缺陷检测 - 飞桨AI Studio基于PP-YOLOE+实现的PCB缺陷检测方案全流程实战,覆盖训练、调优、部署等 - 飞桨AI Studiohttps://aistudio.baidu.com/aistudio/projectdetail/4670836

黑盒教程真有意思 :(

(2)其中ppyoloe_plus_crn_m_80e_obj365_pretrained_pcb.yml内容如下

_BASE_: [
  './_base_/pcb_detection.yml',
  '../../runtime.yml',
  '../_base_/optimizer_80e.yml',
  '../_base_/ppyoloe_plus_crn.yml',
  '../_base_/ppyoloe_plus_reader.yml',
]

log_iter: 100
snapshot_epoch: 5
weights: output/ppyoloe_plus_crn_m_80e_coco_pretrained_pcb/model_final

pretrain_weights: https://bj.bcebos.com/v1/paddledet/models/ppyoloe_plus_crn_m_80e_coco.pdparams
depth_mult: 0.67
width_mult: 0.75

(3)'./_base_/pcb_detection.yml',文件如下

metric: COCO
num_classes: 6

TrainDataset:
  !COCODataSet
    image_dir: images
    anno_path: pcb_cocoanno/train.json
    dataset_dir: dataset/PCB_coco/
    data_fields: ['image', 'gt_bbox', 'gt_class', 'is_crowd']

EvalDataset:
  !COCODataSet
    image_dir: images
    anno_path: pcb_cocoanno/val.json
    dataset_dir: dataset/PCB_coco/

TestDataset:
  !ImageFolder
    anno_path: pcb_cocoanno/val.json # also support txt (like VOC's label_list.txt)
    dataset_dir: dataset/PCB_coco/ # if set, anno_path will be 'dataset_dir/anno_path'

(4)'../../runtime.yml',文件内容如下

use_gpu: true
use_xpu: false
log_iter: 20
save_dir: output
snapshot_epoch: 1
print_flops: false

# Exporting the model
export:
  post_process: True  # Whether post-processing is included in the network when export model.
  nms: True           # Whether NMS is included in the network when export model.
  benchmark: False    # It is used to testing model performance, if set `True`, post-process and NMS will not be exported.
  fuse_conv_bn: False

(5) '../_base_/optimizer_80e.yml',内容如下

epoch: 80

LearningRate:
  base_lr: 0.001
  schedulers:
    - !CosineDecay
      max_epochs: 96
    - !LinearWarmup
      start_factor: 0.
      epochs: 5

OptimizerBuilder:
  optimizer:
    momentum: 0.9
    type: Momentum
  regularizer:
    factor: 0.0005
    type: L2

(6)ppyoloe_plus_crn.yml

architecture: YOLOv3
norm_type: sync_bn
use_ema: true
ema_decay: 0.9998
ema_black_list: ['proj_conv.weight']
custom_black_list: ['reduce_mean']

YOLOv3:
  backbone: CSPResNet
  neck: CustomCSPPAN
  yolo_head: PPYOLOEHead
  post_process: ~

CSPResNet:
  layers: [3, 6, 6, 3]
  channels: [64, 128, 256, 512, 1024]
  return_idx: [1, 2, 3]
  use_large_stem: True
  use_alpha: True

CustomCSPPAN:
  out_channels: [768, 384, 192]
  stage_num: 1
  block_num: 3
  act: 'swish'
  spp: true

PPYOLOEHead:
  fpn_strides: [32, 16, 8]
  grid_cell_scale: 5.0
  grid_cell_offset: 0.5
  static_assigner_epoch: 30
  use_varifocal_loss: True
  loss_weight: {class: 1.0, iou: 2.5, dfl: 0.5}
  static_assigner:
    name: ATSSAssigner
    topk: 9
  assigner:
    name: TaskAlignedAssigner
    topk: 13
    alpha: 1.0
    beta: 6.0
  nms:
    name: MultiClassNMS
    nms_top_k: 1000
    keep_top_k: 300
    score_threshold: 0.01
    nms_threshold: 0.7

(7)ppyoloe_plus_crn.yml

worker_num: 4
eval_height: &eval_height 640
eval_width: &eval_width 640
eval_size: &eval_size [*eval_height, *eval_width]

TrainReader:
  sample_transforms:
    - Decode: {}
    - RandomDistort: {}
    - RandomExpand: {fill_value: [123.675, 116.28, 103.53]}
    - RandomCrop: {}
    - RandomFlip: {}
  batch_transforms:
    - BatchRandomResize: {target_size: [320, 352, 384, 416, 448, 480, 512, 544, 576, 608, 640, 672, 704, 736, 768], random_size: True, random_interp: True, keep_ratio: False}
    - NormalizeImage: {mean: [0., 0., 0.], std: [1., 1., 1.], norm_type: none}
    - Permute: {}
    - PadGT: {}
  batch_size: 8
  shuffle: true
  drop_last: true
  use_shared_memory: true
  collate_batch: true

EvalReader:
  sample_transforms:
    - Decode: {}
    - Resize: {target_size: *eval_size, keep_ratio: False, interp: 2}
    - NormalizeImage: {mean: [0., 0., 0.], std: [1., 1., 1.], norm_type: none}
    - Permute: {}
  batch_size: 2

TestReader:
  inputs_def:
    image_shape: [3, *eval_height, *eval_width]
  sample_transforms:
    - Decode: {}
    - Resize: {target_size: *eval_size, keep_ratio: False, interp: 2}
    - NormalizeImage: {mean: [0., 0., 0.], std: [1., 1., 1.], norm_type: none}
    - Permute: {}
  batch_size: 1

### 加载并解析不同类型数据集的Python方法 在数据分析和机器学习领域,加载和解析不同的数据集是一项常见的任务。以下是几种常见数据集类型的加载方式及其对应的Python实现。 #### CSV文件的数据集 CSV(逗号分隔值)是一种常用的数据存储格式。可以使用`pandas`库来轻松加载和操作此类数据集。 ```python import pandas as pd def load_csv_dataset(file_path): """Load a dataset from a CSV file.""" data = pd.read_csv(file_path) return data ``` 此函数通过指定路径加载CSV文件,并返回一个Pandas DataFrame对象[^1]。 #### MAT文件的数据集 MATLAB (.mat) 文件通常用于科学计算环境中的数据交换。可以通过`scipy.io.loadmat`模块读取这些文件的内容。 ```python from scipy.io import loadmat import numpy as np def load_mat_dataset(file_path): """Load a .mat format dataset and extract landmarks.""" c_mat = loadmat(file_path) landmarks = np.array(np.transpose(c_mat['pt2d'])).astype('float').reshape(-1, 2) return landmarks ``` 上述代码片段展示了如何从.mat文件中提取特定变量(如地标位置),并将它们转换为NumPy数组以便进一步处理[^4]。 #### JSON文件的数据集 JSON 是一种轻量级的数据交换格式,在Web服务中广泛采用。利用 `json` 库可方便地对其进行序列化/反序列化操作。 ```python import json def load_json_dataset(file_path): """Reads the content of a JSON formatted text file into memory""" with open(file_path, 'r') as f: data = json.load(f) return data ``` 对于更复杂的情况比如 FJSP (Flexible Job Shop Scheduling Problem),可能还需要专门编写脚本来适应具体需求。例如下面这段伪代码演示了针对FJSP问题标准测试数据集中某些字段提取的过程[^2]: ```python def parse_fjsp_data(input_file): jobs_operations = [] # 假设输入是一个简单的文本文件... lines = input_file.readlines() num_jobs, num_machines = map(int, lines[0].split()) current_line_index = 1 while current_line_index < len(lines)-num_jobs+1 : job_info = list(map(float,lines[current_line_index ].strip().split())) operation_count=int(job_info.pop(0)) operations=[job_info[i:i +2 ]for i in range(0 ,len(job_info),2 )] jobs_operations.append((operation_count,operations)) current_line_index +=1 return {'number_of_jobs':num_jobs,'number_of_machines':num_machines,'jobs_operations':jobs_operations} ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值