利用MMDetection将单阶段检测器作为Faster R-CNN的RPN

将单阶段检测器作为RPN

  • 一、在 Faster R-CNN 中使用 `FCOSHead` 作为` RPNHead`
    • 与原始配置的对比结果
      • Neck (FPN)
      • RPN Head
      • ROI Head
      • 学习率
    • 使用单阶段检测器作为RPN的优势
      • 1. 速度提升
      • 2. 准确性
      • 3. 简化架构
      • 4. 灵活性
  • 二、评估候选区域
  • 三、用预先训练的 FCOS 训练定制的 Faster R-CNN

在这里插入图片描述

本文参考MMDetection将单阶段检测器作为RPN。候选区域网络 (Region Proposal Network, RPN) 作为 Faster R-CNN 的一个子模块,将为 Faster R-CNN 的第二阶段产生候选区域。在 MMDetection 里大多数的二阶段检测器使用 作为候选区域网络来产生候选区域。然而,任何的单阶段检测器都可以作为候选区域网络,是因为他们对边界框的预测可以被视为是一种候选区域,并且因此能够在 R-CNN 中得到改进。因此在 MMDetection v3.0 中会支持将单阶段检测器作为 RPN 使用。

接下来我们通过一个例子,即如何在 中使用一个无锚框的单阶段的检测器模型 作为 RPN ,详细阐述具体的全部流程。

主要流程如下:

  1. 在 Faster R-CNN 中使用 FCOSHead 作为 RPNHead
  2. 评估候选区域
  3. 用预先训练的 FCOS 训练定制的 Faster R-CNN

一、在 Faster R-CNN 中使用 FCOSHead 作为 RPNHead

为了在 Faster R-CNN 中使用 FCOSHead 作为 RPNHead ,我们应该创建一个名为 configs/faster_rcnn/faster-rcnn_r50_fpn_fcos-rpn_1x_coco.py 的配置文件,并且在 configs/faster_rcnn/faster-rcnn_r50_fpn_fcos-rpn_1x_coco.py 中将 rpn_head 的设置替换为 bbox_head 的设置,此外我们仍然使用 FCOS 的瓶颈设置,步幅为[8,16,32,64,128],并且更新 bbox_roi_extractorfeatmap_stride[8,16,32,64,128]。相关配置如下:

_base_ = [
    '../_base_/models/faster-rcnn_r50_fpn.py',
    '../_base_/datasets/coco_detection.py',
    '../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'
]

以下是../_base_/models/faster-rcnn_r50_fpn.py的原始父类模型model设置(节选)

model = dict(
    # 从 configs/fcos/fcos_r50-caffe_fpn_gn-head_1x_coco.py 复制
    neck=dict(
        type='FPN',
        in_channels=[256, 512, 1024, 2048],
        out_channels=256,
        num_outs=5,
        init_cfg = dict(
            type='Kaiming', layer='Conv2d', distribution='uniform')),
    rpn_head=dict(
        type='RPNHead',
        in_channels=256,
        feat_channels=256,
        anchor_generator=dict(
            type='AnchorGenerator',
            scales=[8],
            ratios=[0.5, 1.0, 2.0],
            strides=[4, 8, 16, 32, 64]),
        bbox_coder=dict(
            type='DeltaXYWHBBoxCoder',
            target_means=[.0, .0, .0, .0],
            target_stds=[1.0, 1.0, 1.0, 1.0]),
        loss_cls=dict(
            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),
        loss_bbox=dict(type='L1Loss', loss_weight=1.0)),
    roi_head=dict(
        type='StandardRoIHead',
        bbox_roi_extractor=dict(
            type='SingleRoIExtractor',
            roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),
            out_channels=256,
            featmap_strides=[4, 8, 16, 32]),
        bbox_head=dict(
            type='Shared2FCBBoxHead',
            in_channels=256,
            fc_out_channels=1024,
            roi_feat_size=7,
            num_classes=2,
            bbox_coder=dict(
                type='DeltaXYWHBBoxCoder',
                target_means=[0., 0., 0., 0.],
                target_stds=[0.1, 0.1, 0.2, 0.2]),
            reg_class_agnostic=False,
            loss_cls=dict(
                type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0),
            loss_bbox=dict(type='L1Loss', loss_weight=1.0))),

以下是configs/faster_rcnn/faster-rcnn_r50_fpn_fcos-rpn_1x_coco.py 的模型model复写设置

model = dict(
    # 从 configs/fcos/fcos_r50-caffe_fpn_gn-head_1x_coco.py 复制
    neck=dict(
        start_level=1,
        add_extra_convs='on_output',  # 使用 P5
        relu_before_extra_convs=True),
    rpn_head=dict(
        _delete_=True,  # 忽略未使用的旧设置
        type='FCOSHead',
        num_classes=1,  # 对于 rpn, num_classes = 1,如果 num_classes > 1,它将在 TwoStageDetector 中自动设置为1
        in_channels=256,
        stacked_convs=4,
        feat_channels=256,
        strides=[8, 16, 32, 64, 128],
        loss_cls=dict(
            type='FocalLoss',
            use_sigmoid=True,
            gamma=2.0,
            alpha=0.25,
            loss_weight=1.0),
        loss_bbox=dict(type='IoULoss', loss_weight=1.0),
        loss_centerness=dict(
            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0)),
    roi_head=dict(  # featmap_strides 的更新取决于于颈部的步伐
        bbox_roi_extractor=dict(featmap_strides=[8, 16, 32, 64, 128])))

与原始配置的对比结果

Neck (FPN)

在原始配置中,FPN的初始化参数被指定,并且没有提到start_leveladd_extra_convs以及relu_before_extra_convs。而在修改后的配置中,我们看到了这些参数的添加:

  • start_level=1: 指定FPN从哪个级别的特征图开始融合,这里是从第二个级别开始(通常C2,即in_channels中的256通道那一层)。
  • add_extra_convs='on_output': 表示在最后一个输入特征图之后添加额外的卷积层,以产生更多的输出特征图。这对于增加模型对小物体的检测能力是有帮助的。
  • relu_before_extra_convs=True: 在额外的卷积层之前应用ReLU激活函数。

RPN Head

原始配置中使用的是传统的RPN Head,而在修改后的配置中,RPN Head被替换为了FCOS Head:

  • _delete_=True: 这意味着删除原配置中的RPN Head设置。
  • type='FCOSHead': 使用FCOS Head代替RPN Head。FCOS是一种无锚框的目标检测方法,这意味着它不再依赖于预定义的锚框来生成候选区域。
  • 其他参数,如num_classes=1stacked_convs=4feat_channels=256等,都是针对FCOS Head的具体配置,比如使用堆叠的卷积层、特征通道数等。
  • 损失函数也从RPN的交叉熵损失和L1损失变更为FCOS的Focal Loss、IoU Loss以及Centerness Loss,这反映了FCOS与RPN在损失计算上的差异。

ROI Head

对于ROI Head,原始配置中没有明确提及featmap_strides的更新,但在修改后的配置中,bbox_roi_extractorfeatmap_strides被显式设置为与Neck的strides相匹配,这是因为使用了FCOS Head,其步长与FPN的输出特征图步长一致。

学习率

为了避免损失变慢,我们在前1000次迭代而不是前500次迭代中应用预热,这意味着 lr 增长得更慢。相关配置如下:

以下是../_base_/schedules/schedule_1x.py的原始父类训练参数param_scheduler设置(节选)

# learning rate
param_scheduler = [
    dict(
        type='LinearLR', start_factor=0.001, by_epoch=False, begin=0, end=500),
    dict(
        type='MultiStepLR',
        begin=0,
        end=12,
        by_epoch=True,
        milestones=[8, 11],
        gamma=0.1)
]

以下是configs/faster_rcnn/faster-rcnn_r50_fpn_fcos-rpn_1x_coco.py 的训练参数param_scheduler复写设置

param_scheduler = [
    dict(
        type='LinearLR', start_factor=0.001, by_epoch=False, begin=0,
        end=1000),  # 慢慢增加 lr,否则损失变成 NAN
    dict(
        type='MultiStepLR',
        begin=0,
        end=12,
        by_epoch=True,
        milestones=[8, 11],
        gamma=0.1)
]

以下是configs/faster_rcnn/faster-rcnn_r50_fpn_fcos-rpn_1x_coco.py 完整代码

_base_ = [
    '../_base_/models/faster-rcnn_r50_fpn.py',
    '../_base_/datasets/coco_detection.py',
    '../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'
]

# 修改数据集相关配置
metainfo = {
    'classes': ('cat', 'dog'),
    'palette':
        [(220, 20, 60), (110, 76, 0)]
}

# 自定义数据集中这一步很关键,这决定你的自定义类别映射是否正确且预测类别和预期一致
train_dataloader = dict(dataset=dict(metainfo=metainfo))
test_dataloader = dict(dataset=dict(metainfo=metainfo))


model = dict(
    # copied from configs/fcos/fcos_r50-caffe_fpn_gn-head_1x_coco.py
    neck=dict(
        start_level=1,
        add_extra_convs='on_output',  # use P5
        relu_before_extra_convs=True),
    rpn_head=dict(
        _delete_=True,  # ignore the unused old settings
        type='FCOSHead',
        # num_classes = 1 for rpn,
        # if num_classes > 1, it will be set to 1 in
        # TwoStageDetector automatically
        num_classes=1,
        in_channels=256,
        stacked_convs=4,
        feat_channels=256,
        strides=[8, 16, 32, 64, 128],
        loss_cls=dict(
            type='FocalLoss',
            use_sigmoid=True,
            gamma=2.0,
            alpha=0.25,
            loss_weight=1.0),
        loss_bbox=dict(type='IoULoss', loss_weight=1.0),
        loss_centerness=dict(
            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0)),
    roi_head=dict(  # update featmap_strides
        bbox_roi_extractor=dict(featmap_strides=[8, 16, 32, 64, 128])))

# learning rate
param_scheduler = [
    dict(
        type='LinearLR', start_factor=0.001, by_epoch=False, begin=0,
        end=1000),  # Slowly increase lr, otherwise loss becomes NAN
    dict(
        type='MultiStepLR',
        begin=0,
        end=12,
        by_epoch=True,
        milestones=[8, 11],
        gamma=0.1)
]

然后,我们可以使用下面的命令来训练我们的定制模型:

CUDA_VISIBLE_DEVICES=0,1,9 ./tools/dist_train.sh \
   configs/faster_rcnn/faster-rcnn_r50_fpn_fcos-rpn_1x_coco.py \
    3 \
    --work-dir  work_dirs/faster-rcnn_r50_fpn_fcos-rpn_1x_coco

训练结果如下:

 Average Precision  (AP) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.806
 Average Precision  (AP) @[ IoU=0.50      | area=   all | maxDets=1000 ] = 0.988
 Average Precision  (AP) @[ IoU=0.75      | area=   all | maxDets=1000 ] = 0.938
 Average Precision  (AP) @[ IoU=0.50:0.95 | area= small | maxDets=1000 ] = -1.000
 Average Precision  (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=1000 ] = 0.752
 Average Precision  (AP) @[ IoU=0.50:0.95 | area= large | maxDets=1000 ] = 0.823
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.843
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=300 ] = 0.843
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=1000 ] = 0.843
 Average Recall     (AR) @[ IoU=0.50:0.95 | area= small | maxDets=1000 ] = -1.000
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=1000 ] = 0.779
 Average Recall     (AR) @[ IoU=0.50:0.95 | area= large | maxDets=1000 ] = 0.858
06/27 20:38:47 - mmengine - INFO - bbox_mAP_copypaste: 0.806 0.988 0.938 -1.000 0.752 0.823
06/27 20:38:47 - mmengine - INFO - Epoch(val) [12][246/246]    coco/bbox_mAP: 0.8060  coco/bbox_mAP_50: 0.9880  coco/bbox_mAP_75: 0.9380  coco/bbox_mAP_s: -1.0000  coco/bbox_mAP_m: 0.7520  coco/bbox_mAP_l: 0.8230  data_time: 0.0018  time: 0.0334

将单阶段检测器用作区域提议网络(RPN,Region Proposal Network)是一种常见的实践,尤其是在构建更复杂的检测系统时。传统上,RPN是在两阶段检测器(如Faster R-CNN)中使用的,用于生成潜在的物体边界框(候选区域)。

使用单阶段检测器作为RPN的优势

1. 速度提升

单阶段检测器通常设计为实时检测,具有较高的推理速度。将它们用作RPN可以显著提高整个系统的处理速度,因为它们能够快速生成大量高质量的候选区域。

2. 准确性

尽管单阶段检测器在小物体检测上可能不如两阶段检测器准确,但它们在大中型物体上的表现通常很好。这意味着它们可以有效地产生包含物体的候选区域,这对于后续的精确定位和分类步骤至关重要。

3. 简化架构

使用单阶段检测器作为RPN可以简化整体架构。传统的两阶段检测器需要一个RPN网络和一个后续的检测网络,而将单阶段检测器集成进来可以减少模型的复杂性,有时甚至可以实现端到端的训练和推理流程。

4. 灵活性

单阶段检测器的灵活性意味着它们可以容易地调整以适应不同的应用场景。例如,可以通过修改锚点大小、比例或特征图层来优化RPN的性能,以更好地适应特定的检测任务。

二、评估候选区域

候选区域的质量对检测器的性能有重要影响,因此,我们也提供了一种评估候选区域的方法。和上面一样创建一个新的名为 configs/rpn/fcos-rpn_r50_fpn_1x_coco.py 的配置文件,并且在 configs/rpn/fcos-rpn_r50_fpn_1x_coco.py 中将 rpn_head 的设置替换为 bbox_head 的设置。

_base_ = [
    '../_base_/models/rpn_r50_fpn.py', '../_base_/datasets/coco_detection.py',
    '../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'
]
val_evaluator = dict(metric='proposal_fast')
test_evaluator = val_evaluator

# 修改数据集相关配置
metainfo = {
    'classes': ('cat', 'dog'),
    'palette':
        [(220, 20, 60), (110, 76, 0)]
}

# 自定义数据集中这一步很关键,这决定你的自定义类别映射是否正确且预测类别和预期一致
train_dataloader = dict(dataset=dict(metainfo=metainfo))
test_dataloader = dict(dataset=dict(metainfo=metainfo))

model = dict(
    # 从 configs/fcos/fcos_r50-caffe_fpn_gn-head_1x_coco.py 复制
    neck=dict(
        start_level=1,
        add_extra_convs='on_output',  # 使用 P5
        relu_before_extra_convs=True),
    rpn_head=dict(
        _delete_=True,  # 忽略未使用的旧设置
        type='FCOSHead',
        num_classes=1,  # 对于 rpn, num_classes = 1,如果 num_classes >为1,它将在 rpn 中自动设置为1
        in_channels=256,
        stacked_convs=4,
        feat_channels=256,
        strides=[8, 16, 32, 64, 128],
        loss_cls=dict(
            type='FocalLoss',
            use_sigmoid=True,
            gamma=2.0,
            alpha=0.25,
            loss_weight=1.0),
        loss_bbox=dict(type='IoULoss', loss_weight=1.0),
        loss_centerness=dict(
            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0)))

假设我们在训练之后有检查点 ./work_dirs/faster-rcnn_r50_fpn_fcos-rpn_1x_coco/iter_5904.pth ,然后,我们可以使用下面的命令来评估建议的质量。

CUDA_VISIBLE_DEVICES=0,1,9 ./tools/dist_test.sh \
   configs/rpn/fcos-rpn_r50_fpn_1x_coco.py \
   work_dirs/faster-rcnn_r50_fpn_fcos-rpn_1x_coco/iter_5904.pth \
   3 \
   --out fcos-rpn-result.pkl

测试结果如下:

/home/miqi/mmdetection/mmdet/evaluation/functional/recall.py:39: RuntimeWarning: invalid value encountered in divide
  recalls[:, i] = (_ious >= thr).sum(axis=1) / float(total_gt_num)
06/27 21:21:33 - mmengine - INFO - 
+------+-----+------+-----+------+-----+------+-----+------+--------------------+------+
|      | 0.5 | 0.55 | 0.6 | 0.65 | 0.7 | 0.75 | 0.8 | 0.85 | 0.8999999999999999 | 0.95 |
+------+-----+------+-----+------+-----+------+-----+------+--------------------+------+
| 100  | nan | nan  | nan | nan  | nan | nan  | nan | nan  | nan                | nan  |
| 300  | nan | nan  | nan | nan  | nan | nan  | nan | nan  | nan                | nan  |
| 1000 | nan | nan  | nan | nan  | nan | nan  | nan | nan  | nan                | nan  |
+------+-----+------+-----+------+-----+------+-----+------+--------------------+------+
06/27 21:21:33 - mmengine - INFO - 
AR@100  nan
AR@300  nan
AR@1000 nan
06/27 21:21:34 - mmengine - INFO - Results has been saved to fcos-rpn-result.pkl.
06/27 21:21:34 - mmengine - INFO - Epoch(test) [246/246]    coco/AR@100: nan  coco/AR@300: nan  coco/AR@1000: nan  data_time: 0.0021  time: 0.0469

尚不清楚为什么出现nan问题,可能与数据集训练结果 Average Recall(AR) @[ IoU=0.50:0.95 | area= small | maxDets=1000 ] = -1.000有关。Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=1000 ] = -1.000这一结果表明在评估模型在检测小尺寸目标时的召回率性能时遇到了异常。具体而言,这通常意味着计算召回率的标准化过程中出现了问题,导致无法得到一个有效的量化指标。在目标检测的标准评估中,AR值应该是一个介于0和1之间的数值,表示在考虑最多1000个检测结果的前提下,模型能够召回所有实际存在的小目标(根据IoU阈值从0.5到0.95)的比例。

出现-1.000这样的非正常值,可能的直接原因包括但不限于:

  • 评估逻辑错误:代码中处理召回率计算的部分可能存在逻辑错误,特别是在处理边界情况(如分母为零时尝试做除法运算)时。
  • 数据异常:数据集中可能存在的问题,比如小尺寸目标的标注极其稀少或完全缺失,或者这些目标的标注质量不高,导致在计算召回率时无法匹配到任何预测结果。
  • 评估配置错误:评估设置中可能有误,比如不正确地设置了IoU阈值范围、最大检测数或其他参数,影响了召回率的正确计算。

三、用预先训练的 FCOS 训练定制的 Faster R-CNN

预训练不仅加快了训练的收敛速度,而且提高了检测器的性能。因此,我们在这里给出一个例子来说明如何使用预先训练的 FCOS 作为 RPN 来加速训练和提高精度。假设我们想在 Faster R-CNN 中使用 FCOSHead 作为 rpn_head,并加载预先训练权重来进行训练 fcos_r50-caffe_fpn_gn-head_1x_coco。 配置文件 configs/faster_rcnn/faster-rcnn_r50-caffe_fpn_fcos- rpn_1x_copy .py 的内容如下所示。注意,fcos_r50-caffe_fpn_gn-head_1x_coco 使用 ResNet50 的 caffe 版本,因此需要更新 data_preprocessor 中的像素平均值和 std。

_base_ = [
    '../_base_/models/faster-rcnn_r50_fpn.py',
    '../_base_/datasets/coco_detection.py',
    '../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'
]

# 修改数据集相关配置
metainfo = {
    'classes': ('cat', 'dog'),
    'palette':
        [(220, 20, 60), (110, 76, 0)]
}

# 自定义数据集中这一步很关键,这决定你的自定义类别映射是否正确且预测类别和预期一致
train_dataloader = dict(dataset=dict(metainfo=metainfo))
test_dataloader = dict(dataset=dict(metainfo=metainfo))

model = dict(
    data_preprocessor=dict(
        mean=[103.530, 116.280, 123.675],
        std=[1.0, 1.0, 1.0],
        bgr_to_rgb=False),
    backbone=dict(
        norm_cfg=dict(type='BN', requires_grad=False),
        style='caffe',
        init_cfg=None),  # the checkpoint in ``load_from`` contains the weights of backbone
    neck=dict(
        start_level=1,
        add_extra_convs='on_output',  # 使用 P5
        relu_before_extra_convs=True),
    rpn_head=dict(
        _delete_=True,  # 忽略未使用的旧设置
        type='FCOSHead',
        num_classes=1,  # 对于 rpn, num_classes = 1,如果 num_classes > 1,它将在 TwoStageDetector 中自动设置为1
        in_channels=256,
        stacked_convs=4,
        feat_channels=256,
        strides=[8, 16, 32, 64, 128],
        loss_cls=dict(
            type='FocalLoss',
            use_sigmoid=True,
            gamma=2.0,
            alpha=0.25,
            loss_weight=1.0),
        loss_bbox=dict(type='IoULoss', loss_weight=1.0),
        loss_centerness=dict(
            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0)),
    roi_head=dict(  # update featmap_strides due to the strides in neck
        bbox_roi_extractor=dict(featmap_strides=[8, 16, 32, 64, 128])))
load_from = 'https://download.openmmlab.com/mmdetection/v2.0/fcos/fcos_r50_caffe_fpn_gn-head_1x_coco/fcos_r50_caffe_fpn_gn-head_1x_coco-821213aa.pth'

训练命令如下:

CUDA_VISIBLE_DEVICES=0,1,9 ./tools/dist_train.sh \
   configs/faster_rcnn/faster-rcnn_r50-caffe_fpn_fcos-rpn_1x_coco.py \
    3 \
    --work-dir  work_dirs/faster-rcnn_r50-caffe_fpn_fcos-rpn_1x_coco

训练结果如下:

 Average Precision  (AP) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.829
 Average Precision  (AP) @[ IoU=0.50      | area=   all | maxDets=1000 ] = 0.984
 Average Precision  (AP) @[ IoU=0.75      | area=   all | maxDets=1000 ] = 0.954
 Average Precision  (AP) @[ IoU=0.50:0.95 | area= small | maxDets=1000 ] = -1.000
 Average Precision  (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=1000 ] = 0.761
 Average Precision  (AP) @[ IoU=0.50:0.95 | area= large | maxDets=1000 ] = 0.848
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.865
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=300 ] = 0.865
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=1000 ] = 0.865
 Average Recall     (AR) @[ IoU=0.50:0.95 | area= small | maxDets=1000 ] = -1.000
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=1000 ] = 0.793
 Average Recall     (AR) @[ IoU=0.50:0.95 | area= large | maxDets=1000 ] = 0.883
06/28 00:31:26 - mmengine - INFO - bbox_mAP_copypaste: 0.829 0.984 0.954 -1.000 0.761 0.848
06/28 00:31:26 - mmengine - INFO - Epoch(val) [12][246/246]    coco/bbox_mAP: 0.8290  coco/bbox_mAP_50: 0.9840  coco/bbox_mAP_75: 0.9540  coco/bbox_mAP_s: -1.0000  coco/bbox_mAP_m: 0.7610  coco/bbox_mAP_l: 0.8480  data_time: 0.0018  time: 0.0331

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

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

相关文章

开源模型应用落地-FastAPI-助力模型交互-WebSocket篇(五)

一、前言 使用 FastAPI 可以帮助我们更简单高效地部署 AI 交互业务。FastAPI 提供了快速构建 API 的能力,开发者可以轻松地定义模型需要的输入和输出格式,并编写好相应的业务逻辑。 FastAPI 的异步高性能架构,可以有效支持大量并发的预测请求,为用户提供流畅的交互体验。此外,F…

shellhub 部署

1、环境介绍 操作系统:龙蜥os 7.9 2、安装docker yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sed -i sdownload.docker.commirrors.aliyun.c…

江协科技51单片机学习- p23 DS1302实时时钟

🚀write in front🚀 🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝​…

【TB作品】智能台灯,ATMEGA16单片机,Proteus仿真

智能台灯 1 adc检测光强光敏电阻 显示电压 2 光强太高 也就是高于临界值 就关闭小灯 3 光强太低 也就是低于临界值 就打开小灯 3 按键修改临界值 显示 实验报告:基于ATMEGA16单片机的智能台灯设计与Proteus仿真 1. 实验背景 智能台灯是一种能够根据环境光强自动调…

计算机网络-第5章运输层

5.1运输层协议概述 5.1.1进程之间的通信 运输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最低层。 通信的两端应当是两个主机中的应用进程。 运输层复用和分用:复用指在发送方不同的应用进程都可以…

Vue2组件传值(通信)的方式

目录 1.父传后代 ( 后代拿到了父的数据 )1. 父组件引入子组件,绑定数据2. 子组件直接使用父组件的数据3. 依赖注入(使用 provide/inject API)1.在祖先组件中使用 provide2.在后代组件中使用 inject 2.后代传父 (父拿到了后代的数据)1. 子组件…

【Qt】认识Qt界面Hello world小程序

一.认识Qt界面 1.左边栏 在编辑模式下,左边竖排的两个窗⼝叫做 "边栏" 。 ① 是项⽬⽂件管理窗⼝ ② 是打开⽂件列表窗⼝。 边栏⾥的窗⼝数⽬可以增加,边栏⼦窗⼝标题栏有⼀排⼩按钮,最右边的是关闭按钮,倒数第⼆个是 …

千元好礼等你来拿 MatrixOne最强体验官

开发者集合![MatrixOne最强体验官]带着丰厚的奖品走来啦!MatrixOne 是一款高度兼容 MySQL 语法的 HTAP 数据库,MatrixOne Cloud (MO Cloud) 是基于 MatrixOne 内核的全托管云原生数据平台,具备实时 HTAP,多租户&#x…

Unity Shader 软粒子

Unity Shader 软粒子 前言项目Shader连连看项目渲染管线设置 鸣谢 前言 当场景有点单调的时候,就需要一些粒子点缀,此时软粒子就可以发挥作用了。 使用软粒子与未使用软粒子对比图 项目 Shader连连看 这里插播一点,可以用Vertex Color与…

antd(5.x) Popover 的content有个modal,关不掉了

问题描述&#xff1a; 如上图所示&#xff0c;我的提示modal 关不掉了&#xff0c;思考问题症结在handleVisibleChange const content (<div className{styles.box}>别的样式</div>{/* 链接 */}<div className{styles.linkBox}><Modaltitle{提示}open{…

deepin基于apt-mirror同步软件源及构建本地内网源

1.安装apt-mirror sudo apt install -y apt-mirror2.配置apt-mirror(/etc/apt/mirror.list) sudo cp /etc/apt/mirror.list /etc/apt/mirror.list.deepin.bak #备份配置文件 sudo gedit /etc/apt/mirror.list修改如下&#xff1a; deb [trustedyes] https://mirrors.bfsu.ed…

在线如何快速把图片变小?图片轻松修改大小的3个在线工具

随着现在图片在工作和生活中的广泛使用&#xff0c;在使用图片的时候经常会因为图片太大的问题受到影响&#xff0c;比较简单的一种处理方法可以通过压缩图片的方式来缩小图片大小&#xff0c;那么图片压缩具体该怎么来操作呢&#xff1f;下面就给大家分享几款图片在线压缩工具…

python如何求不定积分

sympy介绍 sympy库的安装非常的简单&#xff0c;利用conda命令可以快速的完成安装。 conda install sympy 接下来&#xff0c;我们将介绍利用第三方库sympy来完成积分的计算。 python求解不定积分 接下来&#xff0c;我们将介绍上述的不定积分的求解。 首先导入sympy库中的…

切片的基础知识

文章目录 ● Slice 的底层实现原理&#xff1f;● array 和 Slice 的区别&#xff1f;● 拷贝大切片一定比小切片代价大吗&#xff1f;● Slice 深拷贝和浅拷贝&#xff1f;● 零切片、空切片、nil切片&#xff1f;● Slice 的扩容机制&#xff1f;● Slice 为什么不是线程安全…

父子节点内容和个数提取

有时我们需要获得菜单的内容和个数&#xff0c;这个时候通常有父子菜单&#xff0c;那么怎么分别获取到他们呢&#xff1f;以下面的智慧物业管理系统为例&#xff0c;有7个父节点&#xff0c;每个父节点下面有子节点。如何把父节点名称和总数&#xff0c;以及子节点的名称和总数…

Golang-context理解

golang-context笔记整理 golang为何设计context&#xff1f;代码上理解原理空context类cancelCtx类.withcancelctx方法 timerCtx类valueCtx类 golang为何设计context&#xff1f; 有并发特性的语言中&#xff0c;都会有一种说法&#xff1a;创建异步线程或者携程的时候&#x…

在postman中调试supabase的API接口

文章目录 在supabase中获取API地址和key知道它的restfull风格在postman中进行的设置1、get请求调试2、post新增用户调试3、使用patch更新数据&#xff0c;不用put&#xff01;4、delete删除数据 总结 在supabase中获取API地址和key 首先登录dashboard后台&#xff0c;首页- 右…

OFDM的缺点与关键技术

子载波间干扰英文简写ICI&#xff0c;ICI可能由各种原因引起 在多径信道中&#xff0c;CP小于最大附加时延时收发系统载波频率偏差和采样偏差收发系统相对移动&#xff0c;存在多普勒频移 ICI是制约OFDM系统性能的主要重要因素之一 对频率偏差敏感----->同步技术&#xff0…

Figma-ui设计学习APP Store

Figma汉化&#xff1a;Figma 中文社区_插件组件库,软件汉化教程 - Figma.Cool 选择Chorme汉化版离线包 插件安装&#xff1a; 打开浏览器安装扩展&#xff0c;解压加载进去即可。 打开标尺&#xff0c;设置左右内边距参考线&#xff08;左21 右356&#xff09;&#xff0c;wi…

同一个excel表格,为什么在有的电脑上会显示#NAME?

一、哪些情况会产生#NAME?的报错 1.公式名称拼写错误 比如求和函数SUM&#xff0c;如果写成SUN就会提示#NAME&#xff1f;报错。 2.公式中的文本值未添加双引号 如下图&#xff1a; VLOOKUP(丙,A:B,2,0) 公式的计算结果会返回错误值#NAME?&#xff0c;这是因为公式中文本…