0

0

【校园AI Day-AI workshop】卷积神经网络可解释缺陷检测

P粉084495128

P粉084495128

发布时间:2025-08-01 10:44:50

|

326人浏览过

|

来源于php中文网

原创

本项目针对工业工件表面缺陷检测,解决传统人工检测的主观化、低效率等问题,以及样本标签不完整等难题。方案先用百度飞桨PaddleX构建分类网络完成图像分类,再通过卷积特征图生成热力图,经阈值分割、轮廓查找实现缺陷定位,还给出了环境配置、数据准备、模型训练等代码实现过程。

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

【校园ai day-ai workshop】卷积神经网络可解释缺陷检测 - php中文网

1、项目说明

在复杂的生产过程中难以避免产出表面带有缺陷的劣质工件。工件表面存在 缺陷不仅影响其外观质量,还影响其使用寿命与稳定性,由于复杂的生产工艺以及不确定的环境因素难以避免生产出一些表面带有缺陷的劣质工件。工件表面存在缺陷直接影响工件的外观质量,工件外观质量又决定着工件的价值,且直接关系着使用过程中的安全性和稳定性。

例如: 【校园AI Day-AI workshop】卷积神经网络可解释缺陷检测 - php中文网        

传统的工件表面缺陷检测方式常常为人工检测,而传统的人工检测存在以下不足:

  1. 受技术人员的经验、认知、思维等主观因素以及光照、环境等客观因素的影响,容易导致检测结果主观化、非标准化;
  2. 经过长时间重复工作的情况下技术人员难免精神疲惫、视觉疲劳,容易导致检测结果存在漏检与误检现象;
  3. 针对微小缺陷以及颜色、纹理不清楚的缺陷工件表面检测较为困难;
  4. 当基于接触式工件表面缺陷人工检测,可能会对待检测工件造成二次损伤;
  5. 由于人本身精力有限,传统的人工检测工作方式效率低。
  6. 实际应用中很多样本集存在标签不完整、无边框标注信息等问题,如工件无人工标注的边框信息,而标注过程较为繁琐

本项目内容为工业上工件表面缺陷分类,完成工件缺乏边框标注信息的缺陷定位。

2、项目方案

2.1 图像分类

使用百度飞浆PaddleX快速构建分类网络

PaddleX 集成飞桨智能视觉领域图像分类、目标检测、语义分割、实例分割任务能力,将深度学习开发全流程从数据准备、模型训练与优化到多端部署端到端打通,并提供统一任务API接口及图形化开发界面Demo。开发者无需分别安装不同套件,以低代码的形式即可快速完成飞桨全流程开发。

2.2 缺陷定位

利用卷积特征图计算出热力图,并对热力图进行 RGB 通道分离,在 G 通道进行阈值分割获得缺陷部区域,阈值分割公式。热力图的每一个像素点的灰度值大于阈值则输出值为 255,否则为 0。最后利用二值 化图像进行轮廓查找,保留最外轮廓,最后求得轮廓的外接矩形即完成缺陷定位。

Sij={255,  heatmapij>th0,  otherwiseSij={255,  heatmapij>th0,  otherwise

Sora
Sora

Sora是OpenAI发布的一种文生视频AI大模型,可以根据文本指令创建现实和富有想象力的场景。

下载

3、代码实现

3.0 环境配置

In [ ]
#安装paddlex!pip install paddlex==2.1.0
   

3.1 数据集准备

本项目使用,mvtec_ad工业质检著名数据集 ,一共有15个类别,这里以carpet和grid为例已将数据集划分好保存在mydata和grid目录下

In [1]
#解压数据集!unzip -o -q -d  /home/aistudio/work /home/aistudio/data/data116256/mvtec_anomaly_detection.zip
   
In [9]
#批量修改文件名import os#设定文件路径path='work/grid/test/broken'i=1#对目录下的文件进行遍历for file in os.listdir(path):#判断是否是文件
    if os.path.isfile(os.path.join(path,file))==True:#设置新文件名
        new_name=file.replace(file,"broken_%d.png"%i)#重命名
        os.rename(os.path.join(path,file),os.path.join(path,new_name))
        i+=1#结束print ("End")
       
End
       
In [ ]
#移动图片到mydata目录import shutil#这个库复制文件比较省事import osfrom PIL import Image

dirname_read="work/grid/test/thread/"  # 注意后面的斜杠dirname_write="grid/notgood/"names_all=os.listdir(dirname_read)def file_filter(f):
    if f[-4:] in ['.jpg', '.png', '.bmp']:        return True
    else:        return Falsepicture_nmmes = list(filter(file_filter, names_all))print(picture_nmmes)print(len(picture_nmmes))print(dirname_read)for i in picture_nmmes:
    new_obj_name = i    print(new_obj_name)
    shutil.copy(dirname_read + '/' + new_obj_name, dirname_write + '/' + new_obj_name)
   
In [ ]
#划分carpet数据集!paddlex --split_dataset --format ImageNet --dataset_dir mydata --val_value 0.2 --test_value 0.1
   
In [ ]
#划分grid数据集!paddlex --split_dataset --format ImageNet --dataset_dir grid --val_value 0.2 --test_value 0.1
   

3.2 训练分类模型

训练模型

train训练参数

        Args:
            num_epochs (int): 训练迭代轮数。
            train_dataset (paddlex.datasets): 训练数据读取器。
            train_batch_size (int): 训练数据batch大小。同时作为验证数据batch大小。默认值为64。
            eval_dataset (paddlex.datasets: 验证数据读取器。
            save_interval_epochs (int): 模型保存间隔(单位:迭代轮数)。默认为1。
            log_interval_steps (int): 训练日志输出间隔(单位:迭代步数)。默认为2。
            save_dir (str): 模型保存路径。
            pretrain_weights (str): 若指定为路径时,则加载路径下预训练模型;若为字符串'IMAGENET',
                则自动下载在ImageNet图片数据上预训练的模型权重;若为None,则不使用预训练模型。若为'BAIDU10W',则自动下载百度自研10万类预训练。默认为'BAIDU10W'。
            optimizer (paddle.fluid.optimizer): 优化器。当该参数为None时,使用默认优化器:
                fluid.layers.piecewise_decay衰减策略,fluid.optimizer.Momentum优化方法。
            learning_rate (float): 默认优化器的初始学习率。默认为0.025。
            warmup_steps(int): 学习率从warmup_start_lr上升至设定的learning_rate,所需的步数,默认为0
            warmup_start_lr(float): 学习率在warmup阶段时的起始值,默认为0.0
            lr_decay_epochs (list): 默认优化器的学习率衰减轮数。默认为[30, 60, 90]。
            lr_decay_gamma (float): 默认优化器的学习率衰减率。默认为0.1。
            use_vdl (bool): 是否使用VisualDL进行可视化。默认值为False。
            sensitivities_file (str): 若指定为路径时,则加载路径下敏感度信息进行裁剪;若为字符串'DEFAULT',
                则自动下载在ImageNet图片数据上获得的敏感度信息进行裁剪;若为None,则不进行裁剪。默认为None。
            eval_metric_loss (float): 可容忍的精度损失。默认为0.05。
            early_stop (bool): 是否使用提前终止训练策略。默认值为False。
            early_stop_patience (int): 当使用提前终止训练策略时,如果验证集精度在`early_stop_patience`个epoch内
                连续下降或持平,则终止训练。默认值为5。
            resume_checkpoint (str): 恢复训练时指定上次训练保存的模型路径。若为None,则不会恢复训练。默认值为None。
        Raises:
            ValueError: 模型从inference model进行加载。
   
In [ ]
# 设置使用0号GPU卡(如无GPU,执行此代码后仍然会使用CPU训练模型)import matplotlib
matplotlib.use('Agg') 
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'import paddlex as pdximport paddlex as pdxfrom paddlex import transforms as T

train_transforms = T.Compose(
    [T.RandomCrop(crop_size=224), T.RandomHorizontalFlip(), T.Normalize()])

eval_transforms = T.Compose([
    T.ResizeByShort(short_size=256), T.CenterCrop(crop_size=224), T.Normalize()
])# 定义训练和验证所用的数据集# API说明:https://github.com/PaddlePaddle/PaddleX/blob/develop/docs/apis/datasets.mdtrain_dataset = pdx.datasets.ImageNet(
    data_dir='grid',
    file_list='grid/train_list.txt',
    label_list='grid/labels.txt',
    transforms=train_transforms,
    shuffle=True)

eval_dataset = pdx.datasets.ImageNet(
    data_dir='grid',
    file_list='grid/val_list.txt',
    label_list='grid/labels.txt',
    transforms=eval_transforms)# 初始化模型,并进行训练# 可使用VisualDL查看训练指标,参考https://github.com/PaddlePaddle/PaddleX/blob/develop/docs/visualdl.mdnum_classes = len(train_dataset.labels)
model = pdx.cls.ResNet50_vd(num_classes=num_classes)

model.train(
    num_epochs=80,
    train_dataset=train_dataset,
    train_batch_size=8,
    eval_dataset=eval_dataset,
    lr_decay_epochs=[4, 6, 8],
    learning_rate=0.01,
    save_dir='output/grid',
    use_vdl=True)
   

3.3 模型预测

In [30]
import paddlex as pdx


model = pdx.load_model('output/ResNet50_vd/best_model')
image_name = 'mydata/notgood/000.png'result = model.predict(image_name)str=result[0]print("Predict Result:", result)if str['category_id'] :    print("有缺陷")else:    print("无缺陷")
       
2022-05-27 16:56:52 [INFO]	Model[ResNet50_vd] loaded.
Predict Result: [{'category_id': 1, 'category': 'notgood', 'score': 0.737099}]
有缺陷
       

3.4 输出结果

进行模型预测,并输出神经网络热力图,完成缺陷定位。

输出结果保存在Heatmap/result.png

In [1]
%matplotlib inlineimport osfrom PIL import Imageimport paddleimport numpy as npimport cv2import matplotlib.pyplot as pltfrom draw_features import Res2Net_vdimport draw_featuresimport paddle.nn.functional as Fimport paddleimport warnings
warnings.filterwarnings('ignore')def draw_CAM(model, img_path, save_path, transform=None, visual_heatmap=False):
    '''
    绘制 Class Activation Map
    :param model: 加载好权重的Pytorch model
    :param img_path: 测试图片路径
    :param save_path: CAM结果保存路径
    :param transform: 输入图像预处理方法
    :param visual_heatmap: 是否可视化原始heatmap(调用matplotlib)
    :return:
    '''
    # 图像加载&预处理
    img = Image.open(img_path).convert('RGB')
    img = img.resize((224, 224), Image.BILINEAR) #Image.BILINEAR双线性插值
    if transform:
        img = transform(img)    # img = img.unsqueeze(0)
    img = np.array(img).astype('float32')
    img = img.transpose((2, 0, 1))
    img = paddle.to_tensor(img)
    img = paddle.unsqueeze(img, axis=0)    # print(img.shape)
    # 获取模型输出的feature/score

    output,features = model(img)    print('outputshape:',output.shape)    print('featureshape:',features.shape)    # lab = np.argmax(out.numpy())
    # 为了能读取到中间梯度定义的辅助函数
    def extract(g):
        global features_grad
        features_grad = g    # 预测得分最高的那一类对应的输出score
    pred = np.argmax(output.numpy())    # print('***********pred:',pred)
    pred_class = output[:, pred]    # print(pred_class)

    features.register_hook(extract)
    pred_class.backward() # 计算梯度

    grads = features_grad   # 获取梯度
    # print(grads.shape)
    # pooled_grads = paddle.nn.functional.adaptive_avg_pool2d( x = grads, output_size=[1, 1])
    pooled_grads = grads    # 此处batch size默认为1,所以去掉了第0维(batch size维)
    pooled_grads = pooled_grads[0]    # print('pooled_grads:', pooled_grads.shape)
    # print(pooled_grads.shape)
    features = features[0]    # print(features.shape)
    # 最后一层feature的通道数
    for i in range(2048):
        features[i, ...] *= pooled_grads[i, ...]

    heatmap = features.detach().numpy()

    heatmap = np.mean(heatmap, axis=0)    # print(heatmap)
    heatmap = np.maximum(heatmap, 0)    # print('+++++++++',heatmap)
    heatmap /= np.max(heatmap)    # print('+++++++++',heatmap)
    # 可视化原始热力图
    if visual_heatmap:
        plt.matshow(heatmap)
        plt.show()

    img = cv2.imread(img_path)  # 用cv2加载原始图像
    heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))  # 将热力图的大小调整为与原始图像相同
    heatmap = np.uint8(255 * heatmap)  # 将热力图转换为RGB格式
    cv2.imwrite('Heatmap/heatmap.png',heatmap);#将热力图保存到硬盘
    heatmap1 =heatmap    # print(heatmap.shape)
    heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)  # 将热力图应用于原始图像
    superimposed_img = heatmap * 0.4 + img  # 这里的0.4是热力图强度因子
    cv2.imwrite(save_path, superimposed_img)  # 将图像保存到硬盘

    the =220   # 设置阈值
    maxval = 255
    dst, heatmap1 = cv2.threshold(heatmap1, the, maxval, cv2.THRESH_BINARY)
    cnts = cv2.findContours(heatmap1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]    #画出轮廓
    for c in cnts:
        x,y,w,h = cv2.boundingRect(c)
        cv2.rectangle(img, (x, y), (x + w, y + h), (36,255,12), 2)
    cv2.imwrite('Heatmap/result.png',img);# 将图像保存到硬盘model_re2 = Res2Net_vd(layers=50, scales=4, width=26, class_dim=4)# model_re2 = Res2Net50_vd_26w_4s(class_dim=4)modelre2_state_dict = paddle.load("output/ResNet50_vd/best_model/model.pdparams")
model_re2.set_state_dict(modelre2_state_dict, use_structured_name=True)
use_gpu = Truepaddle.set_device('gpu:0') if use_gpu else paddle.set_device('cpu')
model_re2.eval()import paddlex as pdx

model = pdx.load_model('output/ResNet50_vd/best_model')#模型路径image_name = 'mydata/notgood/000.png'#输入图片路径result = model.predict(image_name)print("Predict Result:", result)str=result[0]if str['category_id'] :    print("有缺陷")
    draw_CAM(model_re2, image_name, 'Heatmap/Heatmap.png', transform=None, visual_heatmap=True)else:    print("无缺陷")
       
W0602 00:36:36.333329 20180 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.2, Runtime API Version: 10.1
W0602 00:36:36.338220 20180 device_context.cc:465] device: 0, cuDNN Version: 7.6.
       
[06-02 00:36:39 MainThread @utils.py:79] WRN paddlepaddle version: 2.2.2. The dynamic graph version of PARL is under development, not fully tested and supported
2022-06-02 00:36:40 [INFO]	Model[ResNet50_vd] loaded.
Predict Result: [{'category_id': 1, 'category': 'notgood', 'score': 0.737099}]
有缺陷
outputshape: [1, 4]
featureshape: [1, 2048, 7, 7]
       
<Figure size 288x288 with 1 Axes>
               

3.5 效果展示

【校园AI Day-AI workshop】卷积神经网络可解释缺陷检测 - php中文网        

grid效果!【校园AI Day-AI workshop】卷积神经网络可解释缺陷检测 - php中文网        

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

38

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

83

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

97

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

223

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

458

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

169

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

246

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

34

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 4.2万人学习

Git版本控制工具
Git版本控制工具

共8课时 | 1.6万人学习

Git中文开发手册
Git中文开发手册

共0课时 | 94人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号