英特尔oneAPI人工智能黑客松 - 机器视觉挑战案例

news2024/11/25 2:28:02

写在前面:博主是一只经过实战开发历练后投身培训事业的“小山猪”,昵称取自动画片《狮子王》中的“彭彭”,总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域,如今终有小成,愿将昔日所获与大家交流一二,希望对学习路上的你有所助益。同时,博主也想通过此次尝试打造一个完善的技术图书馆,任何与文章技术点有关的异常、错误、注意事项均会在末尾列出,欢迎大家通过各种方式提供素材。

  • 对于文章中出现的任何错误请大家批评指出,一定及时修改。
  • 有任何想要讨论和学习的问题可联系我:zhuyc@vip.163.com。
  • 发布文章的风格因专栏而异,均自成体系,不足之处请大家指正。

英特尔oneAPI人工智能黑客松 - 机器视觉挑战案例

本文关键字:英特尔、oneAPI、人工智能、机器视觉

一、活动介绍

image-20230621225441252

前一阵英特尔和C站官方联合举办了oneAPI的人工智能黑客松活动,也就是使用英特尔的官方套件去解决一些计算机视觉领域的问题,活动分为3个赛道:

  • 计算机视觉挑战:检测并清除杂草
  • 机器学习:预测淡水质量
  • oneAPI开放创新:使用oneAPI人工智能分析工具包实现任何创意

活动主办方提供了源码案例以及公开课视频教程,并且整体的实现流程也描述的十分清楚,可以方便大家快速上手。笔者虽然一直在人工智能领域工作,但是在机器视觉方面还是接触的比较少,但是查看了相关资料后也能在比较短的时间内实现自己的构想,并且感觉自己也get了新技能,不得不由衷点个赞!

二、环境准备

1. 硬件要求

因为是基于英特尔的套件进行机器视觉方面的工作,所以会用到CPU个GPU资源,需要在Intel的机器上进行开发。当然,如果没有合适的机器,也可以使用官方提供的云环境,小编也是尝试了一下,可以免费申请到半年的使用权,并且配置并不低,可以说是十分良心了。

2. 软件环境

如果想要尽快开始,只需要自行安装一些基础的python环境,能够构建官方的案例即可:https://github.com/idz-cn/2023hackathon/tree/main/computer-vision-track

image-20230621235212461

我们可以参考相关的代码,并且可以下载到需要的数据集:https://www.mvtec.com/company/research/datasets/mvtec-ad,里面包含了很多场景的训练图片,可以直接使用。

dataset_overview_large

三、方案实现

笔者使用的数据集是cable,也就是电缆切面。我们可以通过训练学习让模型知道什么样的情况是合格的,而什么样的是不合规的。以下将列出部分代码和步骤,详细的可以参考官方案例:

1. 数据集准备

首先要准备好训练集 - train测试集 - test,并且两者都需要挑选出可以被认可的 - good不被认可的 - bad,这些图片我们可以从数据集中手动跳转,也可以随机抽取几张,或者参考案例中的数据准备步骤:https://github.com/oneapi-src/visual-quality-inspection#2-data-preparation。

image-20230622000354288

2. 训练和预测

  • 对比显示两组图片

在模型训练阶段,我们先从训练集中抽取一些图片来做对比显示:

import cv2

train_dir = './data/train' # image folder

# get the list of jpegs from sub image class folders
good_imgs = [fn for fn in os.listdir(f'{train_dir}/good') if fn.endswith('.png')]
bad_imgs = [fn for fn in os.listdir(f'{train_dir}/bad') if fn.endswith('.png')]

# randomly select 3 of each
select_norm = np.random.choice(good_imgs, 3, replace = False)
select_pneu = np.random.choice(bad_imgs, 3, replace = False)

# plotting 2 x 3 image matrix
fig = plt.figure(figsize = (10,10))
for i in range(6):
    if i < 3:
        fp = f'{train_dir}/good/{select_norm[i]}'
        label = 'Acceptable Cable'
    else:
        fp = f'{train_dir}/bad/{select_pneu[i-3]}'
        label = 'Defective Cable'
    ax = fig.add_subplot(2, 3, i+1)
    
    # to plot without rescaling, remove target_size
    fn = cv2.imread(fp)
    fn_gray = cv2.cvtColor(fn, cv2.COLOR_BGR2GRAY)
    plt.imshow(fn, cmap='Greys_r')
    plt.title(label)
    plt.axis('off')
plt.show()

image-20230622000743285

  • 接下来需要将图片以数据的形式读取,也就是矩阵或数组的形式
# making n X m matrix
def img2np(path, list_of_filename, size = (64, 64)):
    # iterating through each file
    for fn in list_of_filename:
        fp = path + fn
        current_image = cv2.imread(fp)
        current_image = cv2.cvtColor(current_image, cv2.COLOR_BGR2GRAY)
        
        # turn that into a vector / 1D array
        img_ts = [current_image.ravel()]
        try:
            # concatenate different images
            full_mat = np.concatenate((full_mat, img_ts))
        except UnboundLocalError: 
            # if not assigned yet, assign one
            full_mat = img_ts
    return full_mat

# run it on our folders
good_images = img2np(f'{train_dir}/good/', good_imgs)
bad_images = img2np(f'{train_dir}/bad/', bad_imgs)

def find_stat_img(full_mat, title, size = (1024, 1024)):
    # calculate the average
    mean_img = np.mean(full_mat, axis = 0)
    mean_img = mean_img.reshape(size)
    var_img = np.var(full_mat, axis = 0)
    var_img = var_img.reshape(size)
    max_img = np.amax(full_mat, axis = 0)
    max_img = max_img.reshape(size)
    min_img = np.amin(full_mat, axis = 0)
    min_img = min_img.reshape(size)
    
    figure, (ax1, ax2, ax3, ax4) = plt.subplots(1, 4, sharey=True, figsize=(15, 15))
    ax1.imshow(var_img, vmin=0, vmax=255, cmap='Greys_r')
    ax1.set_title(f'Variance {title}')
    ax2.imshow(mean_img, vmin=0, vmax=255, cmap='Greys_r')
    ax2.set_title(f'Average {title}')
    ax3.imshow(max_img, vmin=0, vmax=255, cmap='Greys_r')
    ax3.set_title(f'Max {title}')
    ax4.imshow(min_img, vmin=0, vmax=255, cmap='Greys_r')
    ax4.set_title(f'Min {title}')
    plt.show()
    return mean_img, var_img

此处的传参需要根据图片尺寸来调整,这里可以看到简单分析后的效果:

image-20230622001305267

  • 模型定义

接下来进行模型的定义,这里直接引用了官方代码:

class CustomVGG(nn.Module):

    def __init__(self, n_classes=2):
        super().__init__()
        self.feature_extractor = models.vgg16(pretrained=True).features[:-1]
        self.classification_head = nn.Sequential(
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.AvgPool2d(
                kernel_size=(INPUT_IMG_SIZE[0] // 2 ** 5, INPUT_IMG_SIZE[1] // 2 ** 5)
            ),
            nn.Flatten(),
            nn.Linear(
                in_features=self.feature_extractor[-2].out_channels,
                out_features=n_classes,
            ),
        )
        self._freeze_params()

    def _freeze_params(self):
        for param in self.feature_extractor[:23].parameters():
            param.requires_grad = False

    def forward(self, x_in):
        """
        forward
        """
        feature_maps = self.feature_extractor(x_in)
        scores = self.classification_head(feature_maps)

        if self.training:
            return scores

        probs = nn.functional.softmax(scores, dim=-1)

        weights = self.classification_head[3].weight
        weights = (
            weights.unsqueeze(-1)
            .unsqueeze(-1)
            .unsqueeze(0)
            .repeat(
                (
                    x_in.size(0),
                    1,
                    1,
                    INPUT_IMG_SIZE[0] // 2 ** 4,
                    INPUT_IMG_SIZE[0] // 2 ** 4,
                )
            )
        )
        feature_maps = feature_maps.unsqueeze(1).repeat((1, probs.size(1), 1, 1, 1))
        location = torch.mul(weights, feature_maps).sum(axis=2)
        location = F.interpolate(location, size=INPUT_IMG_SIZE, mode="bilinear")

        maxs, _ = location.max(dim=-1, keepdim=True)
        maxs, _ = maxs.max(dim=-2, keepdim=True)
        mins, _ = location.min(dim=-1, keepdim=True)
        mins, _ = mins.min(dim=-2, keepdim=True)
        norm_location = (location - mins) / (maxs - mins)

        return probs, norm_location

接下来需要不断的反复调整参数,来查看模型的表现,此处略去。

  • 模型训练

根据定义好的参数训练模型,然后使用测试集查看具体表现。

# model training starts
# Model Training
# Intitalization of DL architechture along with optimizer and loss function
model = CustomVGG()
class_weight = torch.tensor(class_weight).type(torch.FloatTensor).to(DEVICE)
criterion = nn.CrossEntropyLoss(weight=class_weight)
optimizer = optim.Adam(model.parameters(), lr=LR)

# Ipex Optimization
model, optimizer = ipex.optimize(model=model, optimizer=optimizer, dtype=torch.float32)

# Training module
start_time = time.time()
trained_model = train(train_loader, model=model, optimizer=optimizer, criterion=criterion, epochs=EPOCHS,
    device=DEVICE, target_accuracy=TARGET_TRAINING_ACCURACY)
train_time = time.time()-start_time

# Save weights
model_path = f"{subset_name}.pt"
torch.save(trained_model.state_dict(), model_path)

image-20230622001801792

3. 评估和量化

  • 模型评估

评估一个模型有多个指标,可以使用evaluate等方法查看。

y_true, y_pred = evaluate(trained_model, test_loader, DEVICE, labels=True)

image-20230622002125798

  • 模型量化

在模型训练完成后,可以将其量化导出,这样通过十分简短的代码就可以调用。

from neural_compressor.config import PostTrainingQuantConfig, AccuracyCriterion, TuningCriterion
from neural_compressor import quantization

# INC will not quantize some layers optimized by ipex, such as _IPEXConv2d, 
# so we need to create original model object and load trained weights
model = CustomVGG()
model.load_state_dict(torch.load(model_path))
model.to(DEVICE)
model.eval()

# define evaluation function used by INC
def eval_func(model):
    with torch.no_grad():
        y_true = np.empty(shape=(0,))
        y_pred = np.empty(shape=(0,))

        for inputs, labels in train_loader:
            inputs = inputs.to(DEVICE)
            labels = labels.to(DEVICE)
            preds_probs = model(inputs)[0]
            preds_class = torch.argmax(preds_probs, dim=-1)
            labels = labels.to("cpu").numpy()
            preds_class = preds_class.detach().to("cpu").numpy()
            y_true = np.concatenate((y_true, labels))
            y_pred = np.concatenate((y_pred, preds_class))

    return accuracy_score(y_true, y_pred)


# quantize model
conf = PostTrainingQuantConfig(backend='ipex',
                               accuracy_criterion = AccuracyCriterion(
                                   higher_is_better=True, 
                                   criterion='relative',  
                                   tolerable_loss=0.01))
q_model = quantization.fit(model,
                           conf,
                           calib_dataloader=train_loader,
                           eval_func=eval_func)

# save quantized model
# you can also find a json file saved with quantized model, which saved quantization information for each operator
quantized_model_path = './quantized_models'
if not os.path.exists(quantized_model_path):
    os.makedirs(quantized_model_path)
q_model.save(quantized_model_path)
  • 模型预测

从指定路径加载模型后就可以开始预测:

q_model.to(DEVICE)
q_model.eval()
q_model = ipex.optimize(q_model)

y_true, y_pred = evaluate(q_model, test_loader, DEVICE, labels=True)

扫描下方二维码,加入CSDN官方粉丝微信群,可以与我直接交流,还有更多福利哦~
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/673684.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

K8S 生态周报| Kubernetes 公布两个全版本受影响的漏洞

“ 「K8S 生态周报」内容主要包含我所接触到的 K8S 生态相关的每周值得推荐的一些信息。欢迎订阅知乎专栏「k8s生态」[1]。 ” 大家好&#xff0c;我是张晋涛。 KIND v0.20.0 正式发布 KIND 是我一直参与&#xff0c;也日常一直在使用的项目&#xff0c;用于快速的在本地或者 C…

强化学习:AI领域的下一步里程碑

第一章&#xff1a;引言 近年来&#xff0c;人工智能&#xff08;AI&#xff09;的快速发展引起了全球范围内的广泛关注。在AI的众多技术领域中&#xff0c;强化学习&#xff08;Reinforcement Learning&#xff09;作为一种类似于人类学习的方式&#xff0c;在解决复杂问题方…

VMware虚拟机中安装Ubuntu20.04小白教程

安装Ubuntu20.04 1.Ubuntu镜像下载2.配置Ubuntu 2.1创建新的虚拟机&#xff0c;进入新建虚拟机向导2.2选择自定义类型配置2.3选择硬件兼容性2.4选择稍后安装操作系统2.5选择客户机操作系统2.6命名虚拟机2.7处理器配置2.8 虚拟机内存2.9配置网络类型2.10选择I/O控制器类型2.11选…

webpakc原理之开发一个清除console.log(xxx)的loader

一、webpack中清除console的方法 当然想要清除console我们可以使用babel-loader结合babel-plugin-transform-remove-console插件来实现。 安装babel-loader和babel-plugin-transform-remove-console插件 npm install babel-loader babel-plugin-transform-remove-console -D…

TOGAF10®标准中文版--(阶段B — 业务架构)方法

4.5 方法 业务架构是能力、端到端价值交付、信息和组织结构的整体、多维业务视图的表示&#xff1b;以及这些业务视图和战略、产品、政策、计划和利益相关者之间的关系。 业务架构将业务元素与业务目标和其他领域的要素联系起来。 4.5.1 概述 业务架构知识是任何其他领域&a…

HIFUSE:用于医学图像分类的分层多尺度特征融合网络

文章目录 HIFUSE: HIERARCHICAL MULTI-SCALE FEATURE FUSION NETWORK FOR MEDICAL IMAGE CLASSIFICATION摘要本文方法实验结果 HIFUSE: HIERARCHICAL MULTI-SCALE FEATURE FUSION NETWORK FOR MEDICAL IMAGE CLASSIFICATION 摘要 在卷积神经网络&#xff08;CNN&#xff09;的…

Spring核心容器——从配置文件到注解开发 创建对象+成员变量赋值 增强方法

目录 引出Spring入门案例初识Spring入门案例1----用配置文件实现 Druid JDBCTemplate dao1.之前的方式&#xff1a;new对象2.用配置文件的方法把new对象交给Spring3.如果要用对象&#xff0c;从spring的容器中获取ac.getBean("userDao");4.实体类和dao层的代码--问…

NodeFormer:一种用于节点分类的可扩展图结构学习Transformer

文章目录 NodeFormer: A Scalable Graph Structure Learning Transformer for Node ClassificationAbstract方法General Model and Key ChallengesEfficient Learning Discrete Structures可微随机结构学习Input Structures as Relational BiasLearning Objective NodeFormer: …

网络的基础介绍

文章目录 1. 网络发展2. 认识 "协议"3. 网络协议初识3.1 协议分层 4. OSI七层模型4.1 TCP/IP五层(或四层)模型 5. 网络传输基本流程5.1 同一个网段内的主机文件传输5.2 认识MAC地址5.3 跨网段的主机文件传输 6. 数据包封装和分用 1. 网络发展 很早之前&#xff0c;计…

基于强化学习(Reinforcement learning,RL)的机器人路径规划MATLAB

一、Q-learning算法 Q-learning算法是强化学习算法中的一种&#xff0c;该算法主要包含&#xff1a;Agent、状态、动作、环境、回报和惩罚。Q-learning算法通过机器人与环境不断地交换信息&#xff0c;来实现自我学习。Q-learning算法中的Q表是机器人与环境交互后的结果&#…

[unity]Pico VR unity开发笔记(一)

Pico VR 开发笔记&#xff08;一&#xff09; XR Interaction Tooikit 版本 2.3.2 一、环境搭建 其实官方文档已经写的很详细了&#xff0c;这里只是不废话快速搭建&#xff0c;另外有一项官方说明有误的&#xff0c;补充说明一下&#xff0c;在开发工具部分说明 插件安装——…

深度学习基础——通过PyTorch构建神经网络实现1维/2维序列分类

文章目录 使用3层前馈神经网络使用循环神经网络生成pickle数据集构建RNN进行1维序列的训练、推理 使用3层前馈神经网络 通过PyTorch构建前馈神经网络&#xff0c;并对二维数据点进行分类。在该例子当中&#xff0c;所有的训练数据和测试数据都是通过高斯混合模型GMM生成的&…

网络 - 你可知 Telnet 能通但是 Ping 不通百思不得其解

问题描述 以前本人以为 telnet 通 ping 一定也是通的&#xff0c;telnet 能通&#xff0c;表示两台计算机之间建立了连接通道。理论上是能 ping 通的。 但是今天万万没想到&#xff0c;并不是这样... 原因分析 如果不能 ping 通&#xff0c;可能的原因是对方主机关闭了 ping…

MYSQL阶段_DAY01~DAY11(附笔记)

注意&#xff1a;&#xff08;数据表如下&#xff09; sort表&#xff1a; user表&#xff1a; zhangwu表&#xff1a; 1.Part1 JDBC操作数据库的步骤 1.注册驱动 告知JVM使用的是哪一个数据库的驱动, 把驱动类的对象交给DriverManager管理&#xff0c;用于…

一文理解MySQL的For Update行级锁

一文理解MySQL的For Update行级锁 引言一、MySQL的For Update简介1.1、For Update的作用1.2、For Update与其他锁定方式的区别 二、For Update的语法2.1、SELECT语句的基本语法2.2、mysql如何开启事务和提交事务&#xff1f;2.3、使用For Update进行数据锁定 三、如何使用For U…

王道计算机网络学习笔记(2)——物理层

前言 文章中的内容来自B站王道考研计算机网络课程&#xff0c;想要完整学习的可以到B站官方看完整版。 二&#xff1a;物理层 2.1.1&#xff1a;物理层基本概念 2.1.2&#xff1a;数据通信基本知识 1、数据通信模型和基本概念 通信目的是为了传递消息&#xff08;消息&…

2022 年第十二届 MathorCup 高校数学建模挑战赛D题思路(移动通信网络站址规划和区域聚类问题)

目录 一、前言 二、问题背景 三、问题 四、解题思路 &#xff08;1&#xff09;针对问题1&#xff1a; &#xff08;2&#xff09;针对问题2&#xff1a; &#xff08;3&#xff09;针对问题3&#xff1a; 五、附上几个典型代码 &#xff08;1&#xff09;K-means算法…

6月16日,企业快成长技术创新论坛厦门站大数据专场开启!

全球大数据规模增长快速&#xff0c;2020年全球新增数据规模为64ZB&#xff0c;是2016年的400%&#xff0c;2035年新增数据将高达2140ZB1&#xff0c;大数据呈现指数级增长。随着数字经济的发展和数字化转型的深入&#xff0c;愈来愈多的数据资源正以数据要素的形态独立存在并参…

STM32F4_DS18B20红外温度传感器

目录 前言 1. 单总线时序结构 2. DS18B20结构 2.1 DS18B20操作流程 2.2 DS18B20数据帧 3. 温度存储格式 4. 硬件分析 5. 实验程序详解 5.1 main.c 5.2 DS18B20.c 5.3 DS18B20.h 前言 STM32F4内部集成了温度传感器。在之前的学习中&#xff0c;我们已经学习了使用AD进…

宁波天一永安杯初赛 wp-AGCTS战队

文章目录 MISCZipSimpleDocumentBeautifulImage WebDeserializationCodeCheck CryptoSecretRsa MobilePeacock pwnwingtip REPolenta MISC Zip ARCHPR 直接数字爆破&#xff0c;得到二进制密码&#xff0c;得 flag SimpleDocument Kali binwalk 发现里面有一 pdf 文件&#…