【改进YOLOv8】磁瓦缺陷分类系统:改进LSKNet骨干网络的YOLOv8

1.研究背景与意义

项目参考AAAI Association for the Advancement of Artificial Intelligence

研究背景与意义

近年来,随着智能制造产业的不断发展,基于人工智能与机器视觉的自动化产品缺陷检测技术在各行各业中得到了广泛应用。磁瓦作为永磁电机的主要组成部分,其质量的好坏直接影响着永磁电机的使用寿命和工作性能。目前在大多数磁瓦生产过程中,对磁瓦质量的检测仍以人工目视检测为主,这种检测方式存在检测效率低、检测标准不统一、人工成本高等问题。此外,由于磁瓦表面缺陷种类较多,表面纹理复杂且对比度较低,传统的视觉检测与图像处理技术很难对磁瓦表面缺陷进行准确检测与分类,因此研究一种适合磁瓦的自动化缺陷检测及分类方法对于磁瓦的生产具有十分重要的意义。  机器视觉与图像处理作为人工智能领域的重要研究内容,主要通过卷积神经网络对图像数据的特征进行提取与学习,获取图像所含信息,进一步对图像进行处理。目前,将机器视觉与图像处理技术应用于磁瓦缺陷检测问题的研究,已取得了一定成果。本文针对目前磁瓦缺陷检测方法中存在的不足展开研究

2.图片演示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.视频演示

【改进YOLOv8】磁瓦缺陷分类系统:改进LSKNet骨干网络的YOLOv8_哔哩哔哩_bilibili

4.数据集的采集&标注和整理

图片的收集

首先,我们需要收集所需的图片。这可以通过不同的方式来实现,例如使用现有的公开数据集CWDatasets。
在这里插入图片描述

下面是一个简单的方法是使用Python脚本,该脚本读取分类图片文件,然后将其转换为所需的格式。

import os
import shutil
import random

# 指定输入和输出文件夹的路径
input_dir = 'train'
output_dir = 'output'

# 确保输出文件夹存在
if not os.path.exists(output_dir):
    os.makedirs(output_dir)

# 遍历输入文件夹中的所有子文件夹
for subdir in os.listdir(input_dir):
    input_subdir_path = os.path.join(input_dir, subdir)

    # 确保它是一个子文件夹
    if os.path.isdir(input_subdir_path):
        output_subdir_path = os.path.join(output_dir, subdir)

        # 在输出文件夹中创建同名的子文件夹
        if not os.path.exists(output_subdir_path):
            os.makedirs(output_subdir_path)

        # 获取所有文件的列表
        files = [f for f in os.listdir(input_subdir_path) if os.path.isfile(os.path.join(input_subdir_path, f))]

        # 随机选择四分之一的文件
        files_to_move = random.sample(files, len(files) // 4)

        # 移动文件
        for file_to_move in files_to_move:
            src_path = os.path.join(input_subdir_path, file_to_move)
            dest_path = os.path.join(output_subdir_path, file_to_move)
            shutil.move(src_path, dest_path)

print("任务完成!")


整理数据文件夹结构

我们需要将数据集整理为以下结构:

-----dataset
	-----dataset
           |-----train
           |   |-----class1
           |   |-----class2
           |   |-----.......
           |
           |-----valid
           |   |-----class1
           |   |-----class2
           |   |-----.......
           |
           |-----test
           |   |-----class1
           |   |-----class2
           |   |-----.......

模型训练
 Epoch   gpu_mem       box       obj       cls    labels  img_size
 1/200     20.8G   0.01576   0.01955  0.007536        22      1280: 100%|██████████| 849/849 [14:42<00:00,  1.04s/it]
           Class     Images     Labels          P          R     mAP@.5 mAP@.5:.95: 100%|██████████| 213/213 [01:14<00:00,  2.87it/s]
             all       3395      17314      0.994      0.957      0.0957      0.0843

 Epoch   gpu_mem       box       obj       cls    labels  img_size
 2/200     20.8G   0.01578   0.01923  0.007006        22      1280: 100%|██████████| 849/849 [14:44<00:00,  1.04s/it]
           Class     Images     Labels          P          R     mAP@.5 mAP@.5:.95: 100%|██████████| 213/213 [01:12<00:00,  2.95it/s]
             all       3395      17314      0.996      0.956      0.0957      0.0845

 Epoch   gpu_mem       box       obj       cls    labels  img_size
 3/200     20.8G   0.01561    0.0191  0.006895        27      1280: 100%|██████████| 849/849 [10:56<00:00,  1.29it/s]
           Class     Images     Labels          P          R     mAP@.5 mAP@.5:.95: 100%|███████   | 187/213 [00:52<00:00,  4.04it/s]
             all       3395      17314      0.996      0.957      0.0957      0.0845

5.核心代码讲解

5.1 train.py
from copy import copy
import numpy as np
from ultralytics.data import build_dataloader, build_yolo_dataset
from ultralytics.engine.trainer import BaseTrainer
from ultralytics.models import yolo
from ultralytics.nn.tasks import DetectionModel
from ultralytics.utils import LOGGER, RANK
from ultralytics.utils.torch_utils import de_parallel, torch_distributed_zero_first

class DetectionTrainer(BaseTrainer):
    def build_dataset(self, img_path, mode='train', batch=None):
        gs = max(int(de_parallel(self.model).stride.max() if self.model else 0), 32)
        return build_yolo_dataset(self.args, img_path, batch, self.data, mode=mode, rect=mode == 'val', stride=gs)

    def get_dataloader(self, dataset_path, batch_size=16, rank=0, mode='train'):
        assert mode in ['train', 'val']
        with torch_distributed_zero_first(rank):
            dataset = self.build_dataset(dataset_path, mode, batch_size)
        shuffle = mode == 'train'
        if getattr(dataset, 'rect', False) and shuffle:
            LOGGER.warning("WARNING ⚠️ 'rect=True' is incompatible with DataLoader shuffle, setting shuffle=False")
            shuffle = False
        workers = 0
        return build_dataloader(dataset, batch_size, workers, shuffle, rank)

    def preprocess_batch(self, batch):
        batch['img'] = batch['img'].to(self.device, non_blocking=True).float() / 255
        return batch

    def set_model_attributes(self):
        self.model.nc = self.data['nc']
        self.model.names = self.data['names']
        self.model.args = self.args

    def get_model(self, cfg=None, weights=None, verbose=True):
        model = DetectionModel(cfg, nc=self.data['nc'], verbose=verbose and RANK == -1)
        if weights:
            model.load(weights)
        return model

    def get_validator(self):
        self.loss_names = 'box_loss', 'cls_loss', 'dfl_loss'
        return yolo.detect.DetectionValidator(self.test_loader, save_dir=self.save_dir, args=copy(self.args))

    def label_loss_items(self, loss_items=None, prefix='train'):
        keys = [f'{prefix}/{x}' for x in self.loss_names]
        if loss_items is not None:
            loss_items = [round(float(x), 5) for x in loss_items]
            return dict(zip(keys, loss_items))
        else:
            return keys

    def progress_string(self):
        return ('\n' + '%11s' *
                (4 + len(self.loss_names))) % ('Epoch', 'GPU_mem', *self.loss_names, 'Instances', 'Size')

    def plot_training_samples(self, batch, ni):
        plot_images(images=batch['img'],
                    batch_idx=batch['batch_idx'],
                    cls=batch['cls'].squeeze(-1),
                    bboxes=batch['bboxes'],
                    paths=batch['im_file'],
                    fname=self.save_dir / f'train_batch{ni}.jpg',
                    on_plot=self.on_plot)

    def plot_metrics(self):
        plot_results(file=self.csv, on_plot=self.on_plot)

    def plot_training_labels(self):
        boxes = np.concatenate([lb['bboxes'] for lb in self.train_loader.dataset.labels], 0)
        cls = np.concatenate([lb['cls'] for lb in self.train_loader.dataset.labels], 0)
        plot_labels(boxes, cls.squeeze(), names=self.data['names'], save_dir=self.save_dir, on_plot=self.on_plot)

if __name__ == '__main__':
    args = dict(model='./yolov8-ContextGuidedDown.yaml', data='coco8.yaml', epochs=100)
    trainer = DetectionTrainer(overrides=args)
    trainer.train()

该程序文件是一个用于训练基于检测模型的程序。它使用Ultralytics YOLO库进行训练。

该文件定义了一个名为DetectionTrainer的类,它是BaseTrainer类的子类。DetectionTrainer类用于构建和训练YOLO检测模型。

该文件还定义了一些辅助函数,用于构建数据集、构建数据加载器、预处理批次数据等。

main函数中,首先定义了一些参数,然后创建了一个DetectionTrainer对象,并调用其train方法开始训练。

5.2 backbone\revcol.py
import torch
import torch.nn as nn

class RevCol(nn.Module):
    def __init__(self, kernel='C2f', channels=[32, 64, 96, 128], layers=[2, 3, 6, 3], num_subnet=5, save_memory=True) -> None:
        super().__init__()
        self.num_subnet = num_subnet
        self.channels = channels
        self.layers = layers

        self.stem = Conv(3, channels[0], k=4, s=4, p=0)

        for i in range(num_subnet):
            first_col = True if i == 0 else False
            self.add_module(f'subnet{str(i)}', SubNet(channels, layers, kernel, first_col, save_memory=save_memory))
        
        self.channel = [i.size(1) for i in self.forward(torch.randn(1, 3, 640, 640))]

    def forward(self, x):
        c0, c1, c2, c3 = 0, 0, 0, 0
        x = self.stem(x)        
        for i in range(self.num_subnet):
            c0, c1, c2, c3 = getattr(self, f'subnet{str(i)}')(x, c0, c1, c2, c3)       
        return [c0, c1, c2, c3]

该程序文件名为backbone\revcol.py,是一个用于深度学习的神经网络模型的实现。该文件包含了多个模块和函数,用于定义和操作神经网络的各个组件。

该文件中定义了以下模块和函数:

  • RevCol类:该类是整个神经网络模型的主要部分,包含了多个子网络(SubNet)和一个初始卷积层(stem)。该类的前向传播方法定义了整个神经网络的前向传播过程。
  • SubNet类:该类是神经网络的子网络,包含了多个级别(Level)和一个反向传播函数(_forward_reverse)。该类的前向传播方法定义了子网络的前向传播过程。
  • Level类:该类是神经网络的级别,包含了一个融合层(fusion)和多个卷积层(blocks)。该类的前向传播方法定义了级别的前向传播过程。
  • Fusion类:该类是级别的融合层,根据级别的不同选择不同的融合方式。该类的前向传播方法定义了融合层的前向传播过程。
  • ReverseFunction类:该类是一个自定义的反向传播函数,用于实现反向传播过程中的特殊操作。该类的前向传播方法定义了反向传播函数的前向传播过程,后向传播方法定义了反向传播函数的反向传播过程。
  • 其他辅助函数和工具函数:包括获取GPU状态、设置设备状态、分离和梯度等。

总体来说,该程序文件实现了一个具有多个级别和子网络的神经网络模型,用于进行深度学习任务。

5.3 backbone\SwinTransformer.py
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.utils.checkpoint as checkpoint
import numpy as np
from timm.models.layers import DropPath, to_2tuple, trunc_normal_

class Mlp(nn.Module):
    """ Multilayer perceptron."""

    def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):
        super().__init__()
        out_features = out_features or in_features
        hidden_features = hidden_features or in_features
        self.fc1 = nn.Linear(in_features, hidden_features)
        self.act = act_layer()
        self.fc2 = nn.Linear(hidden_features, out_features)
        self.drop = nn.Dropout(drop)

    def forward(self, x):
        x = self.fc1(x)
        x = self.act(x)
        x = self.drop(x)
        x = self.fc2(x)
        x = self.drop(x)
        return x


def window_partition(x, window_size):
    """
    Args:
        x: (B, H, W, C)
        window_size (int): window size

    Returns:
        windows: (num_windows*B, window_size, window_size, C)
    """
    B, H, W, C = x.shape
    x = x.view(B, H // window_size, window_size, W // window_size, window_size, C)
    windows = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, window_size, window_size, C)
    return windows


def window_reverse(windows, window_size, H, W):
    """
    Args:
        windows: (num_windows*B, window_size, window_size, C)
        window_size (int): Window size
        H (int): Height of image
        W (int): Width of image

    Returns:
        x: (B, H, W, C)
    """
    B = int(windows.shape[0] / (H * W / window_size / window_size))
    x = windows.view(B, H // window_size, W // window_size, window_size, window_size, -1)
    x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, H, W, -1)
    return x


class WindowAttention(nn.Module):
    """ Window based multi-head self attention (W-MSA) module with relative position bias.
    It supports both of shifted and non-shifted window.

    Args:
        dim (int): Number of input channels.
        window_size (tuple[int]): The height and width of the window.
        num_heads (int): Number of attention heads.
        qkv_bias (bool, optional):  If True, add a learnable bias to query, key, value. Default: True
        qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set
        attn_drop (float, optional): Dropout ratio of attention weight. Default: 0.0
        proj_drop (float, optional): Dropout ratio of output. Default: 0.0
    """

    def __init__(self, dim, window_size, num_heads, qkv_bias=True, qk_scale=None, attn_drop=0., proj_drop=0.):

        super().__init__()
        self.dim = dim
        self.window_size = window_size  # Wh, Ww
        self.num_heads = num_heads
        head_dim = dim // num_heads
        self.scale = qk

该程序文件是一个用于实现Swin Transformer模型的Python文件。Swin Transformer是一种基于窗口注意力机制的Transformer模型,用于图像分类任务。

该文件定义了以下几个类:

  • Mlp:多层感知机模块,用于特征的线性变换和非线性激活。
  • window_partition:将输入特征划分为窗口。
  • window_reverse:将划分的窗口恢复为原始特征。
  • WindowAttention:基于窗口的多头自注意力模块,支持相对位置偏置。
  • SwinTransformerBlock:Swin Transformer的基本模块,包括窗口注意力和多层感知机。
  • PatchMerging:用于将特征图像素合并的模块。
  • BasicLayer:Swin Transformer的一个阶段,包含多个Swin Transformer模块和特征图像素合并。

这些类的实现组成了Swin Transformer模型的基本组件,可以通过组合这些组件来构建完整的Swin Transformer模型。

5.4 backbone\VanillaNet.py
import torch
import torch.nn as nn
from timm.layers import weight_init

class activation(nn.ReLU):
    def __init__(self, dim, act_num=3, deploy=False):
        super(activation, self).__init__()
        self.deploy = deploy
        self.weight = torch.nn.Parameter(torch.randn(dim, 1, act_num*2 + 1, act_num*2 + 1))
        self.bias = None
        self.bn = nn.BatchNorm2d(dim, eps=1e-6)
        self.dim = dim
        self.act_num = act_num
        weight_init.trunc_normal_(self.weight, std=.02)

    def forward(self, x):
        if self.deploy:
            return torch.nn.functional.conv2d(
                super(activation, self).forward(x), 
                self.weight, self.bias, padding=(self.act_num*2 + 1)//2, groups=self.dim)
        else:
            return self.bn(torch.nn.functional.conv2d(
                super(activation, self).forward(x),
                self.weight, padding=self.act_num

该程序文件名为backbone\VanillaNet.py,是一个用于构建VanillaNet模型的Python代码文件。

该文件定义了以下类和函数:

  • activation类:继承自nn.ReLU类,用于定义激活函数。
  • Block类:继承自nn.Module类,用于定义模型的基本块。
  • VanillaNet类:继承自nn.Module类,用于定义整个VanillaNet模型。
  • update_weight函数:用于更新模型的权重。
  • vanillanet_5函数:用于构建VanillaNet-5模型。
  • vanillanet_6函数:用于构建VanillaNet-6模型。
  • vanillanet_7函数:用于构建VanillaNet-7模型。
  • vanillanet_8函数:用于构建VanillaNet-8模型。
  • vanillanet_9函数:用于构建Vanilla

6.系统整体结构

下表总结了每个文件的功能:

文件名功能
train.py训练分类模型的主要脚本,包括模型定义、数据加载、训练循环等
backbone/lsknet.py实现LSKNet骨干网络的模型定义
backbone/repvit.py实现RepVIT骨干网络的模型定义
backbone/revcol.py实现RevCol骨干网络的模型定义
backbone/SwinTransformer.py实现Swin Transformer骨干网络的模型定义
backbone/VanillaNet.py实现VanillaNet骨干网络的模型定义
classify/predict.py实现分类模型的推理脚本,包括加载模型、预处理数据、进行推理和后处理等
classify/train.py实现分类模型的训练脚本,包括模型定义、数据加载、训练循环等
classify/val.py实现分类模型的验证脚本,用于评估模型在验证集上的性能
extra_modules/head.py实现模型的头部部分,用于分类任务的输出
extra_modules/kernel_warehouse.py存储模型的卷积核参数
extra_modules/orepa.py实现OREPA模块,用于增强模型的表达能力
extra_modules/rep_block.py实现REP Block模块,用于增强模型的表达能力
extra_modules/RFAConv.py实现RFAConv模块,用于增强模型的感受野
models/common.py包含一些通用的模型操作函数
models/experimental.py包含一些实验性的模型定义
models/tf.py包含一些与TensorFlow相关的模型操作函数
models/yolo.py包含YOLO模型的定义和相关操作函数
ultralytics/*包含Ultralytics库的各个模块和功能
utils/*包含一些通用的工具函数和辅助函数
utils/aws/*包含与AWS相关的工具函数
utils/flask_rest_api/*包含使用Flask构建REST API的相关工具函数
utils/loggers/*包含不同日志记录器的实现,如ClearML、Comet、WandB等
utils/segment/*包含用于图像分割任务的工具函数
utils/activations.py包含一些激活函数的实现
utils/augmentations.py包含一些数据增强的实现
utils/autoanchor.py包含自动锚框生成的实现
utils/callbacks.py包含一些回调函数的实现
utils/dataloaders.py包含数据加载器的实现
utils/downloads.py包含一些下载数据集和模型的实现
utils/loss.py包含一些损失函数的实现
utils/metrics.py包含一些评估指标的实现
utils/plots.py包含一些绘图函数的实现
utils/torch_utils.py包含一些与PyTorch相关的工具函数
utils/triton.py包含与Triton Inference Server相关的工具函数

这些文件组成了一个完整的缺陷分类系统,包括模型定义、训练、推理和评估等功能。

7.YOLOv8简介

在这里插入图片描述

由上图可以看出,C2中每个BottlNeck的输入Tensor的通道数channel都只是上一级的0.5倍,因此计算量明显降低。从另一方面讲,梯度流的增加,t也能够明显提升收敛速度和收敛效果。
C2i模块首先以输入tensor(n.c.h.w)经过Conv1层进行split拆分,分成两部分(n,0.5c,h,w),一部分直接经过n个Bottlenck,另一部分经过每一操作层后都会以(n.0.5c,h,w)的尺寸进行Shortcut,最后通过Conv2层卷积输出。也就是对应n+2的Shortcut(第一层Conv1的分支tensor和split后的tensor为2+n个bottenlenneck)。

Neck

YOLOv8的Neck采用了PANet结构,如下图所示。
在这里插入图片描述
Backbone最后SPPF模块(Layer9)之后H、W经过32倍下采样,对应地Layer4经过8倍下采样,Layer6经过16倍下采样。输入图片分辨率为640640,得到Layer4、Layer6、Layer9的分辨率分别为8080、4040和2020。
Layer4、Layer6、Layer9作为PANet结构的输入,经过上采样,通道融合,最终将PANet的三个输出分支送入到Detect head中进行Loss的计算或结果解算。
与FPN(单向,自上而下)不同的是,PANet是一个双向通路网络,引入了自下向上的路径,使得底层信息更容易传递到顶层。

Head

Head部分相比Yolov5改动较大,直接将耦合头改为类似Yolo的解耦头结构(Decoupled-Head),将回归分支和预测分支分离,并针对回归分支使用了Distribution Focal Loss策略中提出的积分形式表示法。之前的目标检测网络将回归坐标作为一个确定性单值进行预测,DFL将坐标转变成一个分布。
在这里插入图片描述

8.LSKNet的架构

该博客提出的结构层级依次为:

LSK module(大核卷积序列+空间选择机制) < LSK Block (LK Selection + FFN)<LSKNet(N个LSK Block)

在这里插入图片描述

LSK 模块

LSK Block
LSKNet 是主干网络中的一个可重复堆叠的块(Block),每个LSK Block包括两个残差子块,即大核选择子块(Large Kernel Selection,LK Selection)和前馈网络子块(Feed-forward Network ,FFN),如图8。LK Selection子块根据需要动态地调整网络的感受野,FFN子块用于通道混合和特征细化,由一个全连接层、一个深度卷积、一个 GELU 激活和第二个全连接层组成。

LSK module(LSK 模块,图4)由一个大核卷积序列(large kernel convolutions)和一个空间核选择机制(spatial kernel selection mechanism)组成,被嵌入到了LSK Block 的 LK Selection子块中。

Large Kernel Convolutions

因为不同类型的目标对背景信息的需求不同,这就需要模型能够自适应选择不同大小的背景范围。因此,作者通过解耦出一系列具有大卷积核、且不断扩张的Depth-wise 卷积,构建了一个更大感受野的网络。

具体地,假设序列中第i个Depth-wise 卷积核的大小为 ,扩张率为 d,感受野为 ,它们满足以下关系:

在这里插入图片描述

卷积核大小和扩张率的增加保证了感受野能够快速增大。此外,我们设置了扩张率的上限,以保证扩张卷积不会引入特征图之间的差距。

Table2的卷积核大小可根据公式(1)和(2)计算,详见下图:

在这里插入图片描述

这样设计的好处有两点。首先,能够产生具有多种不同大小感受野的特征,便于后续的核选择;第二,序列解耦比简单的使用一个大型卷积核效果更好。如上图表2所示,解耦操作相对于标准的大型卷积核,有效地将低了模型的参数量。

为了从输入数据 的不同区域获取丰富的背景信息特征,可采用一系列解耦的、不用感受野的Depth-wise 卷积核:

其中,是卷积核为 、扩张率为 的Depth-wise 卷积操作。假设有个解耦的卷积核,每个卷积操作后又要经过一个的卷积层进行空间特征向量的通道融合。

之后,针对不同的目标,可基于获取的多尺度特征,通过下文中的选择机制动态选择合适的卷积核大小。

这一段的意思可以简单理解为:

把一个大的卷积核拆成了几个小的卷积核,比如一个大小为5,扩张率为1的卷积核加上一个大小为7,扩张率为3的卷积核,感受野为23,与一个大小为23,扩张率为1的卷积核的感受野是一样的。因此可用两个小的卷积核替代一个大的卷积核,同理一个大小为29的卷积核也可以用三个小的卷积代替(Table 2),这样可以有效的减少参数,且更灵活。

将输入数据依次通过这些小的卷积核(公式3),并在每个小的卷积核后面接上一个1×1的卷积进行通道融合(公式4)。

Spatial Kernel Selection

为了使模型更关注目标在空间上的重点背景信息,作者使用空间选择机制从不同尺度的大卷积核中对特征图进行空间选择。

首先,将来自于不同感受野卷积核的特征进行concate拼接,然后,应用通道级的平均池化和最大池化提取空间关系,其中, 和 是平均池化和最大池化后的空间特征描述符。为了实现不同空间描述符的信息交互,作者利用卷积层将空间池化特征进行拼接,将2个通道的池化特征转换为N个空间注意力特征图,之后,将Sigmoid激活函数应用到每一个空间注意力特征图,可获得每个解耦的大卷积核所对应的独立的空间选择掩膜,又然后,将解耦后的大卷积核序列的特征与对应的空间选择掩膜进行加权处理,并通过卷积层进行融合获得注意力特征 ,最后LSK module的输出可通过输入特征 与注意力特征 的逐元素点成获得,公式对应于结构图上的操作如下:
在这里插入图片描述

9.系统整合

下图完整源码&数据集&环境部署视频教程&自定义UI界面

在这里插入图片描述

参考博客《【改进YOLOv8】磁瓦缺陷分类系统:改进LSKNet骨干网络的YOLOv8》

10.参考文献


[1]王凌云,杨剑,张赟宁,等.计及多智能体调度的冷热电联供型微网并网优化运行研究[J].可再生能源.2020,(1).DOI:10.3969/j.issn.1671-5292.2020.01.019 .

[2]程显毅,谢璐,朱建新,等.生成对抗网络GAN综述[J].计算机科学.2019,(3).DOI:10.11896/j.issn.1002-137X.2019.03.009 .

[3]刘畅,张剑,林建平.基于神经网络的磁瓦表面缺陷检测识别[J].表面技术.2019,(8).DOI:10.16490/j.cnki.issn.1001-3660.2019.08.044 .

[4]翟华伟,崔立成,张维石.一种改进灵敏度分析的在线自适应极限学习机算法[J].小型微型计算机系统.2019,(7).DOI:10.3969/j.issn.1000-1220.2019.07.005 .

[5]沈翠芝.采用生成对抗网络的金融文本情感分类方法[J].福州大学学报(自然科学版).2019,(6).DOI:10.7631/issn.1000-2243.19174 .

[6]宋春华,彭泫知.机器视觉研究与发展综述[J].装备制造技术.2019,(6).DOI:10.3969/j.issn.1672-545X.2019.06.062 .

[7]朱秀昌,唐贵进.生成对抗网络图像处理综述[J].南京邮电大学学报(自然科学版).2019,(3).DOI:10.14132/j.cnki.1673-5439.2019.03.001 .

[8]蔡增伟,张顺琦,蒋小乐,等.探索汽车制动钳支架的智能绿色制造之路[J].制造技术与机床.2019,(9).DOI:10.19287/j.cnki.1005-2402.2019.09.001 .

[9]赵树阳,李建武.基于生成对抗网络的低秩图像生成方法[J].自动化学报.2018,(5).DOI:10.16383/j.aas.2018.c170473 .

[10]崔建国,张善好,于明月,等.基于增量型极限学习机的飞机复合材料结构损伤识别[J].科学技术与工程.2018,(4).

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JVM-6-HotSpot的算法细节实现

根节点枚举 迄今为止&#xff0c;所有收集器在根节点枚举这一步骤时都是必须暂停用户线程的&#xff0c;因此毫无疑问根节点枚举与之前提及的整理内存碎片一样会面临相似的“Stop The World”的困扰。 即使是号称停顿时间可控&#xff0c;或者&#xff08;几乎&#xff09;不…

深入解析Guava范围类(Range)

第1章&#xff1a;范围类Range的重要性 大家好&#xff0c;我是小黑&#xff0c;今天咱们聊聊一个在Java编程世界里非常实用但又被低估的角色——Guava库中的Range类。你知道吗&#xff0c;在处理涉及到数值范围的问题时&#xff0c;Range类就像是咱们的救星。不论是判断某个数…

Python3中_和__的用途和区别

目录 一、_&#xff08;下划线&#xff09; 1、临时变量&#xff1a; 2、未使用的变量&#xff1a; 二、__&#xff08;双下划线&#xff09; 1、私有属性&#xff1a; 2、私有方法&#xff1a; 三、__的一些特殊用途。 总结 Python3中的_和__是两个特殊的标识符&#…

MongoDB的数据库引用

本文主要介绍MongoDB的数据库引用。 目录 MongoDB的数据库引用 MongoDB的数据库引用 MongoDB是一种面向文档的NoSQL数据库&#xff0c;它使用BSON&#xff08;Binary JSON&#xff09;格式存储和查询数据。在MongoDB中&#xff0c;数据库引用是一种特殊的数据类型&#xff0c;…

面试算法56:二叉搜索树中两个节点的值之和

题目 给定一棵二叉搜索树和一个值k&#xff0c;请判断该二叉搜索树中是否存在值之和等于k的两个节点。假设二叉搜索树中节点的值均唯一。例如&#xff0c;在如图8.12所示的二叉搜索树中&#xff0c;存在值之和等于12的两个节点&#xff08;节点5和节点7&#xff09;&#xff0…

本地缓存与多级缓存

一、前言 缓存对于一个高并发场景下的微服务应用来说具有重要的作用&#xff0c;不管是在架构选型还是设计阶段&#xff0c;缓存都是应用扛高并发提升吞吐量的有效手段。缓存对于大多数开发的同学来说并不陌生&#xff0c;一个基本的缓存使用流程如下&#xff1a; 简而言之&am…

华为配置OSPF与BFD联动示例

组网需求 如图1所示&#xff0c;SwitchA、SwitchB和SwitchC之间运行OSPF&#xff0c;SwitchA和SwitchB之间的交换机仅作透传功能。现在需要SwitchA和SwitchB能快速感应它们之间的链路状态&#xff0c;当链路SwitchA-SwitchB发生故障时&#xff0c;业务能快速切换到备份链路Swi…

【LeetCode刷题笔记(9-1)】【Python】【无重复字符的最长子串】【滑动窗口】【中等】

文章目录 引言无重复字符的最长子串题目描述提示 解决方案1&#xff1a;【滑动窗口】结束语 无重复字符的最长子串 引言 编写通过所有测试案例的代码并不简单&#xff0c;通常需要深思熟虑和理性分析。虽然这些代码能够通过所有的测试案例&#xff0c;但如果不了解代码背后的思…

七轴开源协作机械臂myArm视觉跟踪技术!

引言 ArUco标记是一种基于二维码的标记&#xff0c;可以被用于高效的场景识别和位置跟踪。这些标记的简单性和高效性使其成为机器视觉领域的理想选择&#xff0c;特别是在需要实时和高精度跟踪的场景中。结合机器学习和先进的图像处理技术&#xff0c;使用ArUco标记的机械臂系统…

爬虫国密加密案例:某医保服务

声明&#xff1a; 该文章为学习使用&#xff0c;严禁用于商业用途和非法用途&#xff0c;违者后果自负&#xff0c;由此产生的一切后果均与作者无关 一、找出需要加密的参数 js运行 atob(‘aHR0cHM6Ly9mdXd1Lm5oc2EuZ292LmNuL25hdGlvbmFsSGFsbFN0LyMvc2VhcmNoL21lZGljYWw/Y29…

HTML---CSS美化网页元素

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.div 标签&#xff1a; <div>是HTML中的一个常用标签&#xff0c;用于定义HTML文档中的一个区块&#xff08;或一个容器&#xff09;。它可以包含其他HTML元素&#xff0c;如文本、图像…

adb: error: cannot create file/directory ‘d:/1.png‘: No such file or directory

将文件从设备读取到PC 由于权限问题&#xff0c;不能直接pull到电脑磁盘根目录&#xff0c;否则会报错&#xff1a; adb pull <remote> <local> eg: C:\Users\admin>adb pull /sdcard/server.log C:\Users\admin\Desktop /sdcard/server.log: 1 file pulled.…

AI创作系统ChatGPT网站源码,支持AI绘画,支持GPT语音对话+智能思维导图生成

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Ch…

客观题测试-第7章查找

第1关&#xff1a;查找客观题测试&#xff08;一&#xff09; 1、关键字可以唯一地标识一个数据元素。 A、对 B、错 2、二叉排序树是一个动态查找表。 A、对 B、错 3、如果顺序表中各元素的查找概率相同&#xff0c;在顺序查找时&#xff0c;查找不成功的平均查找长度因…

nodejs微信小程序+python+PHP国漫推荐系统-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

TrustZone之其他设备及可信基础系统架构

一、其他设备 最后,我们将查看系统中的其他设备,如下图所示: 我们的示例TrustZone启用的系统包括一些尚未涵盖的设备,但我们需要这些设备来构建一个实际的系统。 • 一次性可编程存储器(OTP)或保险丝 这些是一旦写入就无法更改的存储器。与每个芯片上都包含相同…

【Vue2】Component template should contain exactly one root element.

问题描述 [plugin:vite:vue2] Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.原因分析 这个错误通常是由于 Vue 组件的模板中包含多个根元素导致的。Vue 要求组件模板中只…

图片速览 PoseGPT:基于量化的 3D 人体运动生成和预测(VQVAE)

papercodehttps://arxiv.org/pdf/2210.10542.pdfhttps://europe.naverlabs.com/research/computer-vision/posegpt/ 方法 将动作压缩到离散空间。使用GPT类的模型预测未来动作的离散索引。使用解码器解码动作得到输出。 效果 提出的方法在HumanAct12&#xff08;一个标准但小规…

13.FTP

FTP FTP配置 添加一个本地用户 设置个密码 服务类型是FTP 工作路径授权给用户 设置用户角色为网络管理员 开启FTP服务 R2的路径下有这些文件 在R1进行测试&#xff0c;输入刚才创建的用户密码 get 获取文件 put上传文件 也可以在PC进行访问 可以升级路由器系…

阅览窗格功能虽然便利,但有时会出错,特别是在Word和Excel文件中更为常见

当你打开预览窗格功能时&#xff0c;每次你打开Windows文件资源管理器并选择任何文件&#xff0c;你将在屏幕的右窗格上看到该文件的小预览缩略图。 由于这个新功能&#xff0c;你可以在Windows资源管理器的右窗格上以缩略图的形式看到文件的小预览。此功能在更快地识别文件方…