opencv dnn模块 示例(25) 目标检测 object_detection 之 yolov9

news2024/11/15 10:38:41

文章目录

  • 1、YOLOv9 介绍
  • 2、测试
    • 2.1、官方Python测试
    • 2.1.1、正确的脚本
    • 2.2、Opencv dnn测试
      • 2.2.1、导出onnx模型
      • 2.2.2、c++测试代码
    • 2.3、测试统计
  • 3、自定义数据及训练
    • 3.1、准备工作
    • 3.2、训练
    • 3.3、模型重参数化

1、YOLOv9 介绍

YOLOv9 是 YOLOv7 研究团队推出的最新目标检测网络,它是 YOLO(You Only Look Once)系列的最新迭代。YOLOv9 在设计上旨在解决深度学习中信息瓶颈问题,并提高模型在不同任务上的准确性和参数效率。
在这里插入图片描述

  • Programmable Gradient Information (PGI):YOLOv9 引入了可编程梯度信息(PGI)的概念,这是一种新的辅助监督框架,用于生成可靠的梯度信息,以便在训练过程中更新网络权重。PGI 通过辅助可逆分支来解决深度网络加深导致的问题,并提供完整的输入信息以计算目标函数。

  • Generalized Efficient Layer Aggregation Network (GELAN):YOLOv9 设计了一种新的轻量级网络架构 GELAN,它基于梯度路径规划。GELAN 通过使用传统的卷积操作,实现了比基于深度可分离卷积的最先进方法更好的参数利用率。

  • 高效的性能:YOLOv9 在 MS COCO 数据集上的目标检测任务中取得了优异的性能,超越了所有先前的实时目标检测方法。它在准确性、参数利用率和计算效率方面都显示出了显著的优势

  • 适用于不同规模的模型:PGI 可以应用于从轻量级到大型的多种模型,并且可以用于获得完整的信息,使得从头开始训练的模型能够达到或超越使用大型数据集预训练的最先进的模型。

  • 改进的网络架构:YOLOv9 在网络架构上进行了改进,包括简化下采样模块和优化无锚点预测头。这些改进有助于提高模型的效率和准确性。训练策略:YOLOv9 遵循了 YOLOv7 AF 的训练设置,包括使用 SGD 优化器进行 500 个周期的训练,并在训练过程中采用了线性预热和衰减策略。

  • 数据增强:YOLOv9 在训练过程中使用了多种数据增强技术,如 HSV 饱和度、值增强、平移增强、尺度增强和马赛克增强,以提高模型的泛化能力。

总的来说,YOLOv9 通过其创新的 PGI 和 GELAN 架构,以及对现有训练策略的改进,提供了一种高效且准确的目标检测解决方案,适用于各种规模的模型和不同的应用场景。

2、测试

使用Pip在一个Python>=3.8环境中安装ultralytics包,此环境还需包含PyTorch>=1.7。这也会安装所有必要的依赖项。

git clone https://github.com/WongKinYiu/yolov9.git
cd yolov9
pip install -r requirements.txt

提供的cooc预训练模型性能如下

ModelTest SizeAPvalAP50valAP75valParam.FLOPs
YOLOv9-N (dev)64038.3%53.1%41.3%2.0M7.7G
YOLOv9-S64046.8%63.4%50.7%7.1M26.4G
YOLOv9-M64051.4%68.1%56.1%20.0M76.3G
YOLOv9-C64053.0%70.2%57.8%25.3M102.1G
YOLOv9-E64055.6%72.8%60.6%57.3M189.0G

2.1、官方Python测试

python detect.py --weights yolov9-c.pt --data data\coco.yaml --sources bus.jpg

注意,这里可能出现一个错误 fix solving AttributeError: 'list' object has no attribute 'device' in detect.py,在官方issues中可以找到解决方案,需要在将 detect.py 文件下面这种nms不分代码调整为

        # NMS
        with dt[2]:
            pred = pred[0][1] if isinstance(pred[0], list) else pred[0]
            pred = non_max_suppression(pred, conf_thres, iou_thres, classes, agnostic_nms, max_det=max_det)

        # Second-stage classifier (optional)

之后重新运行正常。

以预训练的 yolov9-c.pt 模型为例测试:
CPU 0.8ms pre-process, 1438.7ms inference, 2.0ms NMS per image
GPU 0.7ms pre-process, 41.3ms inference, 1.4ms NMS per image

以预训练的简化模型 yolov9-c-converted.pt 为例测试:
CPU 0.9ms pre-process, 704.8ms inference, 1.6ms NMS per image
GPU 0.4ms pre-process, 22.9ms inference, 1.5ms NMS per image

从推理时间上,可以看出 converted 之后的模型执行时间降低了50%=,这个归功于模型重参数化,可以查看本文章最后一节内容。


2.1.1、正确的脚本

其实上面是错误的使用方式,可能库还没完善。目前推理、训练、验证个截断针对不同模型使用脚本文件是不同的

# inference converted yolov9 models
python detect.py --source './data/images/horses.jpg' --img 640 --device 0 --weights './yolov9-c-converted.pt' --name yolov9_c_c_640_detect

# inference yolov9 models
python detect_dual.py --source './data/images/horses.jpg' --img 640 --device 0 --weights './yolov9-c.pt' --name yolov9_c_640_detect

# inference gelan models
python detect.py --source './data/images/horses.jpg' --img 640 --device 0 --weights './gelan-c.pt' --name gelan_c_c_640_detect

2.2、Opencv dnn测试

2.2.1、导出onnx模型

按照惯例将pt转换为onnx模型,

python export.py --weights yolov9-c.pt --include onnx

输出如下:

(yolo_pytorch) E:\DeepLearning\yolov9>python export.py --weights yolov9-c.pt --include onnx
export: data=E:\DeepLearning\yolov9\data\coco.yaml, weights=['yolov9-c.pt'], imgsz=[640, 640], batch_size=1, device=cpu, half=False, inplace=False, keras=False, optimize=False, int8=False, dynamic=False, simplify=False, opset=12, verbose=False, workspace=4, nms=False, agnostic_nms=False, topk_per_class=100, topk_all=100, iou_thres=0.45, conf_thres=0.25, include=['onnx']
YOLOv5  v0.1-30-ga8f43f3 Python-3.9.16 torch-1.13.1+cu117 CPU

Fusing layers...
Model summary: 604 layers, 50880768 parameters, 0 gradients, 237.6 GFLOPs

PyTorch: starting from yolov9-c.pt with output shape (1, 84, 8400) (98.4 MB)

ONNX: starting export with onnx 1.14.0...
ONNX: export success  9.6s, saved as yolov9-c.onnx (194.6 MB)

Export complete (14.7s)
Results saved to E:\DeepLearning\yolov9
Detect:          python detect.py --weights yolov9-c.onnx
Validate:        python val.py --weights yolov9-c.onnx
PyTorch Hub:     model = torch.hub.load('ultralytics/yolov5', 'custom', 'yolov9-c.onnx')
Visualize:       https://netron.app

2.2.2、c++测试代码

测试代码和 yolov8一样。

参考前面博文 【opencv dnn模块 示例(23) 目标检测 object_detection 之 yolov8】训练部分。

2.3、测试统计

这里仅给出 yolov9-c-converted 的测试数据

python (CPU):704ms
python (GPU):22ms

opencv dnn(CPU):760ms
opencv dnn(GPU):27ms (使用opencv4.8相同的代码,gpu版本结果异常,cpu正常)

以下包含 预处理+推理+后处理:
openvino(CPU): 316ms
onnxruntime(GPU): 29ms
TensorRT:19ms

3、自定义数据及训练

3.1、准备工作

基本和yolov5以后的训练一样了,可以参考前面博文 【opencv dnn模块 示例(23) 目标检测 object_detection 之 yolov8】训练部分。

准备数据集,一个标注文件夹,一个图片文件夹,以及训练、测试使用的样本集图像序列(实际使用),
在这里插入图片描述

文件 myvoc.yaml 描述了数据集的情况,简单如下:

train: E:/DeepLearning/yolov9/custom-data/vehicle/train.txt
val: E:/DeepLearning/yolov9/custom-data/vehicle/val.txt
 
# number of classes
nc: 4
 
# class names
names: ["car", "huoche", "guache", "keche"]

3.2、训练

之后直接训练,例如使用 yolov9-c 模型训练,脚本如下:

python train_dual.py --device 0 --batch 8 --data custom-data/vehicle/myvoc.yaml --img 640 --cfg models/detect/yolov9-c.yaml --weights '' --name yolov9-c --hyp hyp.scratch-high.yaml --min-items 0 --epochs 50 --close-mosaic 15

运行过程前3次可能出现 AttributeError: 'FreeTypeFont' object has no attribute 'getsize' 错误,可以选择更新 Pillow 版本即可。

(yolo_pytorch) E:\DeepLearning\yolov9>python train_dual.py --device 0 --batch 8 --data custom-data/vehicle/myvoc.yaml --img 640 --cfg models/detect/yolov9-c.yaml --weights '' --name yolov9-c --hyp hyp.scratch-high.yaml --min-items 0 --epochs 50 --close-mosaic 15
train_dual: weights='', cfg=models/detect/yolov9-c.yaml, data=custom-data/vehicle/myvoc.yaml, hyp=hyp.scratch-high.yaml, epochs=50, batch_size=8, imgsz=640, rect=False, resume=False, nosave=False, noval=False, noautoanchor=False, noplots=False, evolve=None, bucket=, cache=None, image_weights=False, device=0, multi_scale=False, single_cls=False, optimizer=SGD, sync_bn=False, workers=8, project=runs\train, name=yolov9-c, exist_ok=False, quad=False, cos_lr=False, flat_cos_lr=False, fixed_lr=False, label_smoothing=0.0, patience=100, freeze=[0], save_period=-1, seed=0, local_rank=-1, min_items=0, close_mosaic=15, entity=None, upload_dataset=False, bbox_interval=-1, artifact_alias=latest
YOLO  v0.1-61-g3e4f970 Python-3.9.16 torch-1.13.1+cu117 CUDA:0 (NVIDIA GeForce GTX 1080 Ti, 11264MiB)

hyperparameters: lr0=0.01, lrf=0.01, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=7.5, cls=0.5, cls_pw=1.0, obj=0.7, obj_pw=1.0, dfl=1.5, iou_t=0.2, anchor_t=5.0, fl_gamma=0.0, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.1, scale=0.9, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, mosaic=1.0, mixup=0.15, copy_paste=0.3
ClearML: run 'pip install clearml' to automatically track, visualize and remotely train YOLO  in ClearML
Comet: run 'pip install comet_ml' to automatically track and visualize YOLO  runs in Comet
TensorBoard: Start with 'tensorboard --logdir runs\train', view at http://localhost:6006/
Overriding model.yaml nc=80 with nc=4

                 from  n    params  module                                  arguments
  0                -1  1         0  models.common.Silence                   []
  1                -1  1      1856  models.common.Conv                      [3, 64, 3, 2]
  2                -1  1     73984  models.common.Conv                      [64, 128, 3, 2]
  3                -1  1    212864  models.common.RepNCSPELAN4              [128, 256, 128, 64, 1]
  4                -1  1    164352  models.common.ADown                     [256, 256]
  5                -1  1    847616  models.common.RepNCSPELAN4              [256, 512, 256, 128, 1]
  6                -1  1    656384  models.common.ADown                     [512, 512]
  7                -1  1   2857472  models.common.RepNCSPELAN4              [512, 512, 512, 256, 1]
  8                -1  1    656384  models.common.ADown                     [512, 512]
  9                -1  1   2857472  models.common.RepNCSPELAN4              [512, 512, 512, 256, 1]
 10                -1  1    656896  models.common.SPPELAN                   [512, 512, 256]
 11                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']
 12           [-1, 7]  1         0  models.common.Concat                    [1]
 13                -1  1   3119616  models.common.RepNCSPELAN4              [1024, 512, 512, 256, 1]
 14                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']
 15           [-1, 5]  1         0  models.common.Concat                    [1]
 16                -1  1    912640  models.common.RepNCSPELAN4              [1024, 256, 256, 128, 1]
 17                -1  1    164352  models.common.ADown                     [256, 256]
 18          [-1, 13]  1         0  models.common.Concat                    [1]
 19                -1  1   2988544  models.common.RepNCSPELAN4              [768, 512, 512, 256, 1]
 20                -1  1    656384  models.common.ADown                     [512, 512]
 21          [-1, 10]  1         0  models.common.Concat                    [1]
 22                -1  1   3119616  models.common.RepNCSPELAN4              [1024, 512, 512, 256, 1]
 23                 5  1    131328  models.common.CBLinear                  [512, [256]]
 24                 7  1    393984  models.common.CBLinear                  [512, [256, 512]]
 25                 9  1    656640  models.common.CBLinear                  [512, [256, 512, 512]]
 26                 0  1      1856  models.common.Conv                      [3, 64, 3, 2]
 27                -1  1     73984  models.common.Conv                      [64, 128, 3, 2]
 28                -1  1    212864  models.common.RepNCSPELAN4              [128, 256, 128, 64, 1]
 29                -1  1    164352  models.common.ADown                     [256, 256]
 30  [23, 24, 25, -1]  1         0  models.common.CBFuse                    [[0, 0, 0]]
 31                -1  1    847616  models.common.RepNCSPELAN4              [256, 512, 256, 128, 1]
 32                -1  1    656384  models.common.ADown                     [512, 512]
 33      [24, 25, -1]  1         0  models.common.CBFuse                    [[1, 1]]
 34                -1  1   2857472  models.common.RepNCSPELAN4              [512, 512, 512, 256, 1]
 35                -1  1    656384  models.common.ADown                     [512, 512]
 36          [25, -1]  1         0  models.common.CBFuse                    [[2]]
 37                -1  1   2857472  models.common.RepNCSPELAN4              [512, 512, 512, 256, 1]
 38[31, 34, 37, 16, 19, 22]  1  21549752  models.yolo.DualDDetect                 [4, [512, 512, 512, 256, 512, 512]]
yolov9-c summary: 962 layers, 51006520 parameters, 51006488 gradients, 238.9 GFLOPs

AMP: checks passed
optimizer: SGD(lr=0.01) with parameter groups 238 weight(decay=0.0), 255 weight(decay=0.0005), 253 bias
albumentations: Blur(p=0.01, blur_limit=(3, 7)), MedianBlur(p=0.01, blur_limit=(3, 7)), ToGray(p=0.01), CLAHE(p=0.01, clip_limit=(1, 4.0), tile_grid_size=(8, 8))
train: Scanning E:\DeepLearning\yolov9\custom-data\vehicle\train.cache... 998 images, 0 backgrounds, 0 corrupt: 100%|██████████| 998/998 00:00
val: Scanning E:\DeepLearning\yolov9\custom-data\vehicle\val.cache... 998 images, 0 backgrounds, 0 corrupt: 100%|██████████| 998/998 00:00
Plotting labels to runs\train\yolov9-c4\labels.jpg...
Image sizes 640 train, 640 val
Using 8 dataloader workers
Logging results to runs\train\yolov9-c4
Starting training for 50 epochs...

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
       0/49      9.46G      5.685      6.561      5.295         37        640:   0%|          | 0/125 00:04Exception in thread Thread-5:
Traceback (most recent call last):
  File "D:\Python\anaconda3\envs\yolo_pytorch\lib\threading.py", line 980, in _bootstrap_inner
    self.run()
  File "D:\Python\anaconda3\envs\yolo_pytorch\lib\threading.py", line 917, in run
    self._target(*self._args, **self._kwargs)
  File "E:\DeepLearning\yolov9\utils\plots.py", line 300, in plot_images
    annotator.box_label(box, label, color=color)
  File "E:\DeepLearning\yolov9\utils\plots.py", line 86, in box_label
    w, h = self.font.getsize(label)  # text width, height
AttributeError: 'FreeTypeFont' object has no attribute 'getsize'
WARNING  TensorBoard graph visualization failure Only tensors, lists, tuples of tensors, or dictionary of tensors can be output from traced functions
       0/49      9.67G      6.055      6.742      5.403         65        640:   2%|▏         | 2/125 00:08Exception in thread Thread-6:
Traceback (most recent call last):
  File "D:\Python\anaconda3\envs\yolo_pytorch\lib\threading.py", line 980, in _bootstrap_inner
    self.run()
  File "D:\Python\anaconda3\envs\yolo_pytorch\lib\threading.py", line 917, in run
    self._target(*self._args, **self._kwargs)
  File "E:\DeepLearning\yolov9\utils\plots.py", line 300, in plot_images
    annotator.box_label(box, label, color=color)
  File "E:\DeepLearning\yolov9\utils\plots.py", line 86, in box_label
    w, h = self.font.getsize(label)  # text width, height
AttributeError: 'FreeTypeFont' object has no attribute 'getsize'
       0/49      9.67G      6.201      6.812      5.505         36        640:   2%|▏         | 3/125 00:09Exception in thread Thread-7:
Traceback (most recent call last):
  File "D:\Python\anaconda3\envs\yolo_pytorch\lib\threading.py", line 980, in _bootstrap_inner
    self.run()
  File "D:\Python\anaconda3\envs\yolo_pytorch\lib\threading.py", line 917, in run
    self._target(*self._args, **self._kwargs)
  File "E:\DeepLearning\yolov9\utils\plots.py", line 300, in plot_images
    annotator.box_label(box, label, color=color)
  File "E:\DeepLearning\yolov9\utils\plots.py", line 86, in box_label
    w, h = self.font.getsize(label)  # text width, height
AttributeError: 'FreeTypeFont' object has no attribute 'getsize'
       0/49      10.2G      5.603       6.38      5.564         21        640: 100%|██████████| 125/125 02:44
                 Class     Images  Instances          P          R      mAP50   mAP50-95: 100%|██████████| 63/63 01:12
                   all        998       2353   3.88e-05    0.00483   2.16e-05   2.63e-06

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
       1/49      12.1G      5.553      6.034      5.431         40        640: 100%|██████████| 125/125 02:53
                 Class     Images  Instances          P          R      mAP50   mAP50-95: 100%|██████████| 63/63 01:29
                   all        998       2353    0.00398     0.0313    0.00276   0.000604

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
       2/49      12.1G      5.061      5.749      5.102         49        640: 100%|██████████| 125/125 07:44
                 Class     Images  Instances          P          R      mAP50   mAP50-95: 100%|██████████| 63/63 01:26
                   all        998       2353    0.00643      0.364    0.00681     0.0017

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
       3/49      12.1G      4.292      5.013       4.58         35        640: 100%|██████████| 125/125 08:04
                 Class     Images  Instances          P          R      mAP50   mAP50-95: 100%|██████████| 63/63 01:28
                   all        998       2353     0.0425      0.242     0.0273    0.00944

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
       4/49      12.1G      3.652       4.46      4.164         30        640:  34%|███▎      | 42/125 02:45

3.3、模型重参数化

这里以 yolov9-c 转换为 yolov9-c-converted 模型为例。
例如在上一节我们已经训练好了一个模型,如下
在这里插入图片描述
我们使用如下reparameterization_yolov9-c.py脚本,

import torch
from models.yolo import Model


model_file_path = r'runs\train\yolov9-c5\weights\best.pt'
model_converted_path = r'runs\train\yolov9-c5\weights\best-c-c.pt'
nc = 4
 

device = torch.device("cpu")
cfg = "./models/detect/gelan-c.yaml"
model = Model(cfg, ch=3, nc=nc, anchors=3)
#model = model.half()
model = model.to(device)
_ = model.eval()
ckpt = torch.load(model_file_path, map_location='cpu')
model.names = ckpt['model'].names
model.nc = ckpt['model'].nc

idx = 0
for k, v in model.state_dict().items():
    if "model.{}.".format(idx) in k:
        if idx < 22:
            kr = k.replace("model.{}.".format(idx), "model.{}.".format(idx+1))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
        elif "model.{}.cv2.".format(idx) in k:
            kr = k.replace("model.{}.cv2.".format(idx), "model.{}.cv4.".format(idx+16))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
        elif "model.{}.cv3.".format(idx) in k:
            kr = k.replace("model.{}.cv3.".format(idx), "model.{}.cv5.".format(idx+16))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
        elif "model.{}.dfl.".format(idx) in k:
            kr = k.replace("model.{}.dfl.".format(idx), "model.{}.dfl2.".format(idx+16))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
    else:
        while True:
            idx += 1
            if "model.{}.".format(idx) in k:
                break
        if idx < 22:
            kr = k.replace("model.{}.".format(idx), "model.{}.".format(idx+1))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
        elif "model.{}.cv2.".format(idx) in k:
            kr = k.replace("model.{}.cv2.".format(idx), "model.{}.cv4.".format(idx+16))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
        elif "model.{}.cv3.".format(idx) in k:
            kr = k.replace("model.{}.cv3.".format(idx), "model.{}.cv5.".format(idx+16))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
        elif "model.{}.dfl.".format(idx) in k:
            kr = k.replace("model.{}.dfl.".format(idx), "model.{}.dfl2.".format(idx+16))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
_ = model.eval()


m_ckpt = {'model': model.half(),
          'optimizer': None,
          'best_fitness': None,
          'ema': None,
          'updates': None,
          'opt': None,
          'git': None,
          'date': None,
          'epoch': -1}
torch.save(m_ckpt, model_converted_path)

运行成功后,多了一个文件 best-c-c.pt 文件,且和官方提供的大小相同
在这里插入图片描述
我们进行测试如下,

(yolo_pytorch) E:\DeepLearning\yolov9>python detect.py --weights runs\train\yolov9-c5\weights\best-c-c.pt --source custom-data\vehicle\images\11.jpg --device 0
detect: weights=['runs\\train\\yolov9-c5\\weights\\best-c-c.pt'], source=custom-data\vehicle\images\11.jpg, data=data\coco128.yaml, imgsz=[640, 640], conf_thres=0.25, iou_thres=0.45, max_det=1000, device=0, view_img=False, save_txt=False, save_conf=False, save_crop=False, nosave=False, classes=None, agnostic_nms=False, augment=False, visualize=False, update=False, project=runs\detect, name=exp, exist_ok=False, line_thickness=3, hide_labels=False, hide_conf=False, half=False, dnn=False, vid_stride=1
YOLO  v0.1-61-g3e4f970 Python-3.9.16 torch-1.13.1+cu117 CUDA:0 (NVIDIA GeForce GTX 1080 Ti, 11264MiB)

Fusing layers...
gelan-c summary: 387 layers, 25230172 parameters, 6348 gradients, 101.8 GFLOPs
image 1/1 E:\DeepLearning\yolov9\custom-data\vehicle\images\11.jpg: 480x640 8 cars, 52.2ms
Speed: 0.0ms pre-process, 52.2ms inference, 7.0ms NMS per image at shape (1, 3, 640, 640)
Results saved to runs\detect\exp39

结果如下图
在这里插入图片描述

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

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

相关文章

手撕快速排序

定义 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法. 其基本思想为:任取待排序的某个元素作为基准值,按照该排序码将待排序集合分割成两个子序列, 左子序列中所有元素均小于基准值,右子序列均大于基准值,然后左右子序列重复该过程,知道所有元素都有序为止. (核心…

投后管理系统的功能模块

投后管理系统的技术难点可能包括以下几个方面&#xff0c;这些技术难点需要综合考虑&#xff0c;并结合具体的业务需求和技术实现&#xff0c;才能构建出高效、安全、稳定的投后管理系统。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作…

【Python】成功解决NameError: name ‘sns‘ is not defined

【Python】成功解决NameError: name ‘sns’ is not defined &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您…

基于Java (spring-boot)的毕业作品管理系统

一、项目介绍 管理员管理设计题目&#xff0c;投票记录&#xff0c;选题信息以及公告。 教师对设计题目进行投票&#xff0c;审核并管理用户选题信息。 用户选择设计题目&#xff0c;查看选题审核状态&#xff0c;管理选题信息。 二、作品包含 三、项目技术 后端语言&#xff1…

一体式以电折水智能终端:化繁为简,智能八合一

一体式以电折水智能终端通过高度集成化设计&#xff0c;巧妙融合了空气开关、开关电源、隔离变压器、接触器、智能电表、RTU、4G通信模块、定位模块等八大核心功能&#xff0c;不仅展现了经济高效和智能运维的双重优势&#xff0c;更以其超强的安全防护能力确保了使用的高度安全…

maven打包把所有依赖的jar copy到一个文件夹

在maven项目中&#xff0c;是使用依赖坐标来引入jar包&#xff0c;在引入jar包的时候&#xff0c;maven也会默默的帮助我们导入这个jar包所依赖的jar包。 但是当我们打包项目使用jar包运行的时候&#xff0c;往往会出现缺少jar的情况&#xff1a; 如果我们一个一个添加缺少的…

对比学习(Contrastive Learning)和孪生网络(Siamese Network)的区别!

对比学习&#xff08;Contrastive Learning&#xff09;和孪生网络&#xff08;Siamese Network&#xff09;是两种常见的无监督学习方法&#xff0c;它们有着不同的原理和应用场景。 原理与目标&#xff1a; 对比学习旨在通过最小化相似样本对之间的距离&#xff0c;最大化不相…

西井科技参与IATA全球货运大会 以AI绿动能引领智慧空港新未来

3月12日至14日&#xff0c;由国际航空运输协会IATA主办的全球货运大会&#xff08;World Cargo Symposium&#xff09;在中国香港成功举办&#xff0c;这是全球航空货运领域最大规模与影响力的年度盛会。作为大物流领域全球领先的“智能化与新能源化”综合解决方案提供商&#…

从零开始写 Docker(六)---实现 mydocker run -v 支持数据卷挂载

本文为从零开始写 Docker 系列第六篇&#xff0c;实现类似 docker -v 的功能&#xff0c;通过挂载数据卷将容器中部分数据持久化到宿主机。 完整代码见&#xff1a;https://github.com/lixd/mydocker 欢迎 Star 推荐阅读以下文章对 docker 基本实现有一个大致认识&#xff1a; …

[C++]20.实现红黑树。

实现红黑树 一.基本概念&#xff1a;1.红黑树的概念&#xff1a;2.红黑树的性质&#xff1a; 二.实现红黑树&#xff1a;1.基本结构&#xff1a;2.插入节点的多种情况&#xff1a;1.叔叔存在且为红&#xff1a;2.叔叔不存在/存在且为黑(单旋变色)3.叔叔不存在/存在且为黑(多旋&…

【计算机网络篇】计算机网络的定义和分类

文章目录 &#x1f354;什么是计算机网络&#x1f5c3;️计算机网络的分类⭐按交换方式分类⭐按使用者分类⭐按传输介质分类⭐按覆盖范围分类⭐按拓扑结构分类 &#x1f6f8;小结 &#x1f354;什么是计算机网络 计算机网络是指将多台计算机或其他网络设备通过通信链路连接起来…

C语言 ——常量

3, 常量 3.1 什么是常量 ​ 程序运行的过程中&#xff0c;其值永远不会发生改变的数据 3.2 常量的分类 3.3 练习 ​ 给你一组数据&#xff0c;说出下面每组数据中&#xff0c;分别是哪种类型的常量 3.4 细节补充 实型常量的小细节&#xff1a; * 小数点前后&#xff0c;如果…

【数据结构】二叉树---AVL树的实现

目录 一. 什么是AVL树 二. AVL树的结点结构定义 三. AVL树的动态平衡法 1. 左单旋转 --- RL(RotateLeft) 型调整操作 2. 右单旋转 --- RR(RotateRight) 型调整操作 3. 先左后右双旋转 --- RLR (RotateLeftRight) 型调整操作 4. 先右后左双旋转 --- RRL (RotateRightL…

python工具方法 47 基于paddleseg将目标检测数据升级为语义分割数据

在进行项目研究时,通常需要搜集开源数据集。但是所能搜集到的数据集通常会存在形式上的差异,比如我想要的是语义分割数据,而搜集到的数据集却是目标检测数据;在这种情况下所搜集的数据就完成没有利用价值了么?不,其还存在价值,我们可以通过模型训练对数据标签的标注粒度…

【学习】python装饰器

这篇文章讲的太清楚了&#xff01;非常好好好&#xff01;&#xff01;&#xff01;Python】一文弄懂python装饰器&#xff08;附源码例子&#xff09; 在他的基础上加了一些自己的话&#xff0c;便于自己理解。 注意的点&#xff1a; func 表示函数对象&#xff0c;可以将其…

智慧公厕建设,助力打造宜居、韧性、可持续的智慧城市

公共厕所作为智慧城市的重要组成部分&#xff0c;对于城市的高质量发展起着至关重要的作用。智慧公厕建设旨在通过全面监测、控制和管理公共厕所&#xff0c;实现多方面功能&#xff0c;包括公共厕所环境监测与调控、厕位占用监测与引导、消耗品监测与缺失提示、安全防范与管理…

使用OCC进行旋转扫掠

旋转扫掠是将物体以某一个坐标轴为参照&#xff0c;按照指定的角度旋转生成新的图形的过程 这里使用面的案例&#xff0c;使用线的逻辑处理其实是一样的 //构造旋转轴 gp_Ax1 anAxis; //设置轴的原点 anAxis.SetLocation(0,0,0); //设置轴的方向 anAxis.SetDirection(gp_Dir(0…

N3-Chitosan N3 叠氮修饰壳聚糖 改性叠氮 CS-Azide

碳水科技&#xff08;Tanshtech&#xff09;可以提供壳聚糖衍生物 1.壳聚糖的各种改性(NH2/COOH/SH/N3/MAL-Chitosan等) 2.各种靶向小分子修饰壳聚糖&#xff08;Biotin/FA/cRGD-Chitosan等&#xff09; 3.各种荧光标记壳聚糖(FITC/RB/CY-Chitosan等) 4.壳聚糖和各种聚合物…

基于springboot实现数据资产管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现数据资产管理系统演示 摘要 固定资产管理系统主要是完成对系统用户管理、资产信息管理、资产变更管理、资产用途管理、资产类别管理和资产增减管理。因为利用本系统管理员可以直接录入信息&#xff0c;修改信息&#xff0c;删除信息&#xff0c;并且若在录入…

【学一点RISC-V】RISC-V IMSIC

IMSIC RISC-V AIA 文档 第三章 Incoming MSI Controller (IMSIC) 传入 MSI 控制器&#xff08;IMSIC&#xff09;是一个可选的 RISC-V 硬件组件&#xff0c;与 hart 紧密相连&#xff0c;每个 hart 有一个 IMSIC。IMSIC 接收并记录 Hart 的传入消息信号中断 (MSI)&#xff0c;并…