【改进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_size1/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.0843Epoch gpu_mem box obj cls labels img_size2/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.0845Epoch gpu_mem box obj cls labels img_size3/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_firstclass 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 = Falseworkers = 0return build_dataloader(dataset, batch_size, workers, shuffle, rank)def preprocess_batch(self, batch):batch['img'] = batch['img'].to(self.device, non_blocking=True).float() / 255return batchdef set_model_attributes(self):self.model.nc = self.data['nc']self.model.names = self.data['names']self.model.args = self.argsdef 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 modeldef 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 keysdef 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 nnclass 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_subnetself.channels = channelsself.layers = layersself.stem = Conv(3, channels[0], k=4, s=4, p=0)for i in range(num_subnet):first_col = True if i == 0 else Falseself.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, 0x = 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_featureshidden_features = hidden_features or in_featuresself.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 xdef window_partition(x, window_size):"""Args:x: (B, H, W, C)window_size (int): window sizeReturns:windows: (num_windows*B, window_size, window_size, C)"""B, H, W, C = x.shapex = 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 windowsdef window_reverse(windows, window_size, H, W):"""Args:windows: (num_windows*B, window_size, window_size, C)window_size (int): Window sizeH (int): Height of imageW (int): Width of imageReturns: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 xclass 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: Trueqk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if setattn_drop (float, optional): Dropout ratio of attention weight. Default: 0.0proj_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 = dimself.window_size = window_size # Wh, Wwself.num_heads = num_headshead_dim = dim // num_headsself.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_initclass activation(nn.ReLU):def __init__(self, dim, act_num=3, deploy=False):super(activation, self).__init__()self.deploy = deployself.weight = torch.nn.Parameter(torch.randn(dim, 1, act_num*2 + 1, act_num*2 + 1))self.bias = Noneself.bn = nn.BatchNorm2d(dim, eps=1e-6)self.dim = dimself.act_num = act_numweight_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).
相关文章:

【改进YOLOv8】磁瓦缺陷分类系统:改进LSKNet骨干网络的YOLOv8
1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义 近年来,随着智能制造产业的不断发展,基于人工智能与机器视觉的自动化产品缺陷检测技术在各行各业中得到了广泛应用。磁瓦作为永磁电机的主…...

Linux-VRRP
这里写自定义目录标题 一、VRRP简介1.1 什么是VRRP?1.2 keepalived是什么? 二、配置过程2.1 试验模型2.2. Keepalived监控和维护VRRP集群的步骤 一、VRRP简介 1.1 什么是VRRP? VRRP(Virtual Router Redundancy Protocolÿ…...

使用Axure的中继器的交互动作解决增删改查h
🎬 艳艳耶✌️:个人主页 🔥 个人专栏 :《产品经理如何画泳道图&流程图》 ⛺️ 越努力 ,越幸运 目录 一、中继器的交互 1、什么是中继器的交互 2、Axure中继器的交互 3、如何使用中继器? 二…...
华为云Stack 8.X 流量模型分析(一)
一、基础知识 1.tap与tun tap与tun都是操作系统(Linux)内核中的虚拟网络设备,等同于一个以太网设备,可以收发数据报文包。 tap与tun的定义相同,两者仅仅是通过一个Flag来区分。但二者所承担的功能差别较大&am…...

SpringBoot已经禁掉了循环依赖!
还在问循环依赖嘛?SpringBoot已经禁掉了循环依赖! 首发2023-12-18 11:26yuan人生 如果现在面试时还有人问你循环依赖,你就这样怼他:循环依赖是一种代码质量低下的表现,springboot2.6之后的版本已经默认禁用了。 Spr…...
【.NET Core】反射(Reflection)详解(一)
【.NET Core】反射(Reflection)详解(一) 文章目录 【.NET Core】反射(Reflection)详解(一)一、什么是反射二、Assembly类2.1 LoadFile2.2 Load2.3 LoadFrom(String)2.4 GetName()2.5…...

jenkins入门
文章目录 前言一、 jenkins的安装二、新建简单任务总结 前言 本篇文章是 jenkins 的入门级别案例,包括安装、基础概念介绍、新建简单任务 一、 jenkins的安装 下载 jenkins https://www.jenkins.io/download/ 当前案例下载的是 2.426.2 LTS 版本 下载安装jdk11 …...

HarmonyOS --- 首页(新新新手版,高手误入)
一、前言 每一个App都应该有一个首页,在Android中一般由MainActivity Navigation Fragment * N (随便你怎么组合,用别的也一样),鸿蒙呢?瞅瞅吧。阿弥陀佛,苦逼Android学完Java学Dart、学完Da…...

springboot升级到3.2导致mybatis-plus启动报错
在springboot升级到3.2时,服务启动报错 java.lang.IllegalArgumentException: Invalid value type for attribute ‘factoryBeanObjectType’: java.lang.String: java.lang.IllegalArgumentException: Invalid value type for attribute factoryBeanOb…...

浏览器原理篇—渲染原理
目录导航 为什么要学习浏览器的渲染原理浏览器的渲染流程浏览器的渲染阻塞浏览器的渲染优化 为什么要学习浏览器的渲染原理? 知识深度挖掘: 帮助更好地理解前端性能优化。从而对实现效果进行针对性优化。如:**回流和重绘 **渲染机制。帮助…...
idea安装
mac安装路径 /Users/xxx/Library/Application Support/JetBrains/IntelliJIdeaxxx版本 将路径内文件直接复制到新版本即可, 注意如果为破解版idea.vmoptions配置中的内容是否添加或删除 maven配置如果使用idea, 需要在应用程序IntelliJ IDEA.app中显示包内容, /Applications/I…...

用Flask搭建简单的web模型部署服务
目录结构如下: 分类模型web部署 classification.py import os import cv2 import numpy as np import onnxruntime from flask import Flask, render_template, request, jsonifyapp Flask(__name__)onnx_session onnxruntime.InferenceSession("mobilen…...
PCL 点云匹配 3 之 (非线性迭代点云匹配)lM-ICP
一、IM迭代法 PCL IterativeClosestPointNonLinear 非线性L-M迭代法-CSDN博客 Matlab 非线性迭代法(3)阻尼牛顿法 L-M-CSDN博客 MATLAB实现最小二乘法_matlab最小二乘法-CSDN博客...

【C语言】SCU安全项目2-BufBomb
目录 关键代码解读: getxs() getbuf() test() 核心思路 具体操作1 具体操作2 前段时间忙于强网杯、英语4级和一些其他支线,有点摸不清头绪了,特别是qwb只有一个输出,太过坐牢,决定这个安全项目做完后就继续投身…...

C++第一讲之初入C++
注:本文是对于学完C语言再学C同学的讲解,主要补充C与C语言不同之处,如果你没学过C语言,不建议观看本文。 一.C简介 我们都知道C语言是过程性语言(强调的是实现过程),即对计算机语言要处理的两…...

如何实现公网访问本地内网搭建的WBO白板远程协作办公【内网穿透】
最近,我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念,而且内容风趣幽默。我觉得它对大家可能会有所帮助,所以我在此分享。点击这里跳转到网站。 文章目录 前言1. 部署WBO白板2. 本地访问WBO白板3. Linux 安装cp…...

js知识点1:防抖节流
js知识点1:防抖节流 防抖节流 防抖节流,本质上是优化高频率执行代码的一种手段 定义: 防抖: n 秒后再执行该事件,若在 n 秒内被重复触发,则重新计时 节流: n 秒内只运行一次,若在 n 秒内重复触发࿰…...

虚拟机下Ubuntu上网设置
文章目录 一、虚拟机上网的两种方式1.1 NAT模式(Network Address Translation)1.2 桥接模式(Bridge Mode)1.3 简介 二、实际配置2.1 NAT模式配置2.2 桥接模式配置 之前跟着博客配了好几个也没用,后来自己慢慢模式实践测…...

Unity3d C#利用Editor编辑器拓展实现配置UI背景样式一键设置UI背景样式功能(含源码)
前言 在开发UI滚动列表的时候,经常会有每项的背景图不统一的情况,会间隔重复的情况居多。这种情况下,手动去设置间隔一行的背景图或者颜色是比较麻烦的。在此背景下,笔者尝试写个小工具,在搭建UI时配置一下循环背景的…...
【微服务】服务间调用
当我们的应用从一个大单体拆分成多个微服务之后,服务间调用有多少种方式?服务间调用如果出现超时,如果避免雪崩,即如何做限流熔断机制,原理是什么? 服务间调用方式 OpenFeign 使用Feign进行服务间调用,我们会在启动类加@EnableFeignClients启用。 package org.sprin…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...