旋转框目标检测mmrotate v1.0.0rc1 之RTMDet训练DOTA(二)

news2024/12/24 11:43:53

1、模型rotated_rtmdet的论文链接与配置文件

注意

我们按照 DOTA 评测服务器的最新指标,原来的 voc 格式 mAP 现在是 mAP50。

IN表示ImageNet预训练,COCO表示COCO预训练。

与报告不同的是,这里的推理速度是在 NVIDIA 2080Ti GPU 上测量的,配备 TensorRT 8.4.3、cuDNN 8.2.0、FP16、batch size=1 和 NMS。

2、修改RTMDet-tiny的配置文件

  1. 基础配置文件:rotated_rtmdet_l-3x-dota.py

_base_ = [
    './_base_/default_runtime.py', './_base_/schedule_3x.py',
    './_base_/dota_rr.py'
]
checkpoint = 'https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-l_8xb256-rsb-a1-600e_in1k-6a760974.pth'  # noqa

angle_version = 'le90'
model = dict(
    type='mmdet.RTMDet',
    data_preprocessor=dict(
        type='mmdet.DetDataPreprocessor',
        mean=[103.53, 116.28, 123.675],
        std=[57.375, 57.12, 58.395],
        bgr_to_rgb=False,
        boxtype2tensor=False,
        batch_augments=None),
    backbone=dict(
        type='mmdet.CSPNeXt',
        arch='P5',
        expand_ratio=0.5,
        deepen_factor=1,
        widen_factor=1,
        channel_attention=True,
        norm_cfg=dict(type='SyncBN'),
        act_cfg=dict(type='SiLU'),
        init_cfg=dict(
            type='Pretrained', prefix='backbone.', checkpoint=checkpoint)),
    neck=dict(
        type='mmdet.CSPNeXtPAFPN',
        in_channels=[256, 512, 1024],
        out_channels=256,
        num_csp_blocks=3,
        expand_ratio=0.5,
        norm_cfg=dict(type='SyncBN'),
        act_cfg=dict(type='SiLU')),
    bbox_head=dict(
        type='RotatedRTMDetSepBNHead',
        num_classes=15,
        in_channels=256,
        stacked_convs=2,
        feat_channels=256,
        angle_version=angle_version,
        anchor_generator=dict(
            type='mmdet.MlvlPointGenerator', offset=0, strides=[8, 16, 32]),
        bbox_coder=dict(
            type='DistanceAnglePointCoder', angle_version=angle_version),
        loss_cls=dict(
            type='mmdet.QualityFocalLoss',
            use_sigmoid=True,
            beta=2.0,
            loss_weight=1.0),
        loss_bbox=dict(type='RotatedIoULoss', mode='linear', loss_weight=2.0),
        with_objectness=False,
        exp_on_reg=True,
        share_conv=True,
        pred_kernel_size=1,
        use_hbbox_loss=False,
        scale_angle=False,
        loss_angle=None,
        norm_cfg=dict(type='SyncBN'),
        act_cfg=dict(type='SiLU')),
    train_cfg=dict(
        assigner=dict(
            type='mmdet.DynamicSoftLabelAssigner',
            iou_calculator=dict(type='RBboxOverlaps2D'),
            topk=13),
        allowed_border=-1,
        pos_weight=-1,
        debug=False),
    test_cfg=dict(
        nms_pre=2000,
        min_bbox_size=0,
        score_thr=0.05,
        nms=dict(type='nms_rotated', iou_threshold=0.1),
        max_per_img=2000),
)

# batch_size = (2 GPUs) x (4 samples per GPU) = 8
train_dataloader = dict(batch_size=4, num_workers=4)
  1. 修改数据集路径信息——'./_base_/dota_rr.py'

更改数据集基础路径及训练、验证和测试路径、以及影像切片的大小

  1. 修改训练数据的类别数——rotated_rtmdet_l-3x-dota.py

  1. 修改线程和batch_size('./_base_/dota_rr.py')

'./_base_/dota_rr.py'

rotated_rtmdet_l-3x-dota.py

4.修改训练epoches('./_base_/schedule_3x.py')

5.修改模型训练的日志打印和load from 加载与训练模型(configs_base_/default_runtime.py)

6.修改模型model的与训练模型路径

7.修改数据集的类别名称(mmrotate\datasets\dota.py)

8、修改图像数据集的后缀和图片大小(修改mmrotate/mmrotate/datasets/dota.py)

3、模型训练

1、Train with a single GPU

python tools/train.py ${CONFIG_FILE} [optional arguments]
如果你想在命令中指定工作目录,你可以添加一个参数–work_dir $[YOUR_WORK_DIR]。

2、Train with multiple GPUs

./tools/dist_train.sh ${CONFIG_FILE} ${GPU_NUM} [optional arguments]
Optional arguments are:
–no-validate (not suggested): By default, the codebase will perform evaluation during the training. To disable this behavior, use --no-validate.
–work-dir ${WORK_DIR}: Override the working directory specified in the config file.
–resume-from ${CHECKPOINT_FILE}: Resume from a previous checkpoint file.
Difference between resume-from and load-from: resume-from loads both the model weights and optimizer status, and the epoch is also inherited from the specified checkpoint. It is usually used for resuming the training process that is interrupted accidentally. load-from only loads the model weights and the training epoch starts from 0. It is usually used for finetuning.

3、Train with multiple machines

•如果你启动了多台连接以太网的机器,你可以简单地运行以下命令:

On the first machine:

NNODES=2 NODE_RANK=0 PORT=$MASTER_PORT MASTER_ADDR=$MASTER_ADDR sh tools/dist_train.sh $CONFIG $GPUS

On the second machine:

NNODES=2 NODE_RANK=1 PORT=$MASTER_PORT MASTER_ADDR=$MASTER_ADDR sh tools/dist_train.sh $CONFIG $GPUS

如果你没有像InfiniBand这样的高速网络,通常会很慢。

4、Manage jobs with Slurm

如果在由slurm管理的集群上运行MMRotate,可以使用脚本slurm_train.sh。(此脚本也支持单机训练。)

[GPUS=${GPUS}] ./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} ${CONFIG_FILE} ${WORK_DIR}

如果您有多台机器与以太网连接,您可以参考PyTorch启动实用程序添加链接描述。如果你没有像InfiniBand这样的高速网络,通常会很慢

5、在一台机器上启动多个作业

如果您在一台机器上启动多个作业,例如,在一台有8个gpu的机器上启动2个4-GPU训练的作业,您需要为每个作业指定不同的端口(默认为29500),以避免通信冲突。

If you use dist_train.sh to launch training jobs, you can set the port in commands.

CUDA_VISIBLE_DEVICES=0,1,2,3 PORT=29500 ./tools/dist_train.sh ${CONFIG_FILE} 4
CUDA_VISIBLE_DEVICES=4,5,6,7 PORT=29501 ./tools/dist_train.sh ${CONFIG_FILE} 4

如果使用Slurm启动培训作业,则需要修改配置文件(通常是配置文件中倒数第6行)以设置不同的通信端口。

In config1.py,

dist_params = dict(backend=‘nccl’, port=29500)

In config2.py,

dist_params = dict(backend=‘nccl’, port=29501)

Then you can launch two jobs with config1.py and config2.py.

CUDA_VISIBLE_DEVICES=0,1,2,3 GPUS=4 ./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} config1.py ${WORK_DIR}
CUDA_VISIBLE_DEVICES=4,5,6,7 GPUS=4 ./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} config2.py ${WORK_DIR}

6、开始启动模型训练

1、启动模型训练命令

python tools/train.py  configs/rotated_rtmdet/rotated_rtmdet_tiny-3x-dota.py --work-dir work_dirs/runs/train/rtmdet_tiny_rrship/

2、模型训练结果

default_scope = 'mmrotate'
default_hooks = dict(
    timer=dict(type='IterTimerHook'),
    logger=dict(type='LoggerHook', interval=50),#模型训练日志打印间隔
    param_scheduler=dict(type='ParamSchedulerHook'),
    checkpoint=dict(type='CheckpointHook', interval=12, max_keep_ckpts=3),#模型保存间隔和最多保存个数
    sampler_seed=dict(type='DistSamplerSeedHook'),
    visualization=dict(type='mmdet.DetVisualizationHook'))
env_cfg = dict(
    cudnn_benchmark=False,
    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),
    dist_cfg=dict(backend='nccl'))
vis_backends = [dict(type='LocalVisBackend')]
visualizer = dict(
    type='RotLocalVisualizer',
    vis_backends=[dict(type='LocalVisBackend')],
    name='visualizer')
log_processor = dict(type='LogProcessor', window_size=50, by_epoch=True)
log_level = 'INFO'
load_from = '/media/lhy/mmrotate-1.0.0rc1/checkpoints/RTMDet/rotated_rtmdet_tiny-3x-dota-9d821076.pth'
resume = False
custom_hooks = [
    dict(type='mmdet.NumClassCheckHook'),
    dict(
        type='EMAHook',
        ema_type='mmdet.ExpMomentumEMA',
        momentum=0.0002,
        update_buffers=True,
        priority=49)
]
max_epochs = 36
base_lr = 0.00025
interval = 12
train_cfg = dict(type='EpochBasedTrainLoop', max_epochs=36, val_interval=12)
val_cfg = dict(type='ValLoop')
test_cfg = dict(type='TestLoop')
param_scheduler = [
    dict(
        type='LinearLR', start_factor=1e-05, by_epoch=False, begin=0,
        end=1000),
    dict(
        type='CosineAnnealingLR',
        eta_min=1.25e-05,
        begin=18,
        end=36,
        T_max=18,
        by_epoch=True,
        convert_to_iter_based=True)
]
optim_wrapper = dict(
    type='OptimWrapper',
    optimizer=dict(type='AdamW', lr=0.00025, weight_decay=0.05),
    paramwise_cfg=dict(
        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))
dataset_type = 'DOTADataset'
data_root = 'data/DOTA/optship1280/'
file_client_args = dict(backend='disk')
train_pipeline = [
    dict(
        type='mmdet.LoadImageFromFile', file_client_args=dict(backend='disk')),
    dict(type='mmdet.LoadAnnotations', with_bbox=True, box_type='qbox'),
    dict(type='ConvertBoxType', box_type_mapping=dict(gt_bboxes='rbox')),
    dict(type='mmdet.Resize', scale=(1280, 1280), keep_ratio=True),
    dict(
        type='mmdet.RandomFlip',
        prob=0.75,
        direction=['horizontal', 'vertical', 'diagonal']),
    dict(
        type='RandomRotate',
        prob=0.5,
        angle_range=180,
        rect_obj_labels=[9, 11]),
    dict(
        type='mmdet.Pad', size=(1280, 1280),
        pad_val=dict(img=(114, 114, 114))),
    dict(type='mmdet.PackDetInputs')
]
val_pipeline = [
    dict(
        type='mmdet.LoadImageFromFile', file_client_args=dict(backend='disk')),
    dict(type='mmdet.Resize', scale=(1280, 1280), keep_ratio=True),
    dict(type='mmdet.LoadAnnotations', with_bbox=True, box_type='qbox'),
    dict(type='ConvertBoxType', box_type_mapping=dict(gt_bboxes='rbox')),
    dict(
        type='mmdet.Pad', size=(1280, 1280),
        pad_val=dict(img=(114, 114, 114))),
    dict(
        type='mmdet.PackDetInputs',
        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',
                   'scale_factor'))
]
test_pipeline = [
    dict(
        type='mmdet.LoadImageFromFile', file_client_args=dict(backend='disk')),
    dict(type='mmdet.Resize', scale=(1280, 1280), keep_ratio=True),
    dict(
        type='mmdet.Pad', size=(1280, 1280),
        pad_val=dict(img=(114, 114, 114))),
    dict(
        type='mmdet.PackDetInputs',
        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',
                   'scale_factor'))
]
train_dataloader = dict(
    batch_size=8,
    num_workers=8,
    persistent_workers=True,
    sampler=dict(type='DefaultSampler', shuffle=True),
    batch_sampler=None,
    pin_memory=False,
    dataset=dict(
        type='DOTADataset',
        data_root='data/DOTA/optship1280/',
        ann_file='train/obb_annfiles/',
        data_prefix=dict(img_path='train/images/'),
        img_shape=(1280, 1280),
        filter_cfg=dict(filter_empty_gt=True),
        pipeline=[
            dict(
                type='mmdet.LoadImageFromFile',
                file_client_args=dict(backend='disk')),
            dict(
                type='mmdet.LoadAnnotations', with_bbox=True, box_type='qbox'),
            dict(
                type='ConvertBoxType',
                box_type_mapping=dict(gt_bboxes='rbox')),
            dict(type='mmdet.Resize', scale=(1280, 1280), keep_ratio=True),
            dict(
                type='mmdet.RandomFlip',
                prob=0.75,
                direction=['horizontal', 'vertical', 'diagonal']),
            dict(
                type='RandomRotate',
                prob=0.5,
                angle_range=180,
                rect_obj_labels=[9, 11]),
            dict(
                type='mmdet.Pad',
                size=(1280, 1280),
                pad_val=dict(img=(114, 114, 114))),
            dict(type='mmdet.PackDetInputs')
        ]))
val_dataloader = dict(
    batch_size=1,
    num_workers=2,
    persistent_workers=True,
    drop_last=False,
    sampler=dict(type='DefaultSampler', shuffle=False),
    dataset=dict(
        type='DOTADataset',
        data_root='data/DOTA/optship1280/',
        ann_file='val/obb_annfiles/',
        data_prefix=dict(img_path='val/images/'),
        img_shape=(1280, 1280),
        test_mode=True,
        pipeline=[
            dict(
                type='mmdet.LoadImageFromFile',
                file_client_args=dict(backend='disk')),
            dict(type='mmdet.Resize', scale=(1280, 1280), keep_ratio=True),
            dict(
                type='mmdet.LoadAnnotations', with_bbox=True, box_type='qbox'),
            dict(
                type='ConvertBoxType',
                box_type_mapping=dict(gt_bboxes='rbox')),
            dict(
                type='mmdet.Pad',
                size=(1280, 1280),
                pad_val=dict(img=(114, 114, 114))),
            dict(
                type='mmdet.PackDetInputs',
                meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',
                           'scale_factor'))
        ]))
test_dataloader = dict(
    batch_size=1,
    num_workers=2,
    persistent_workers=True,
    drop_last=False,
    sampler=dict(type='DefaultSampler', shuffle=False),
    dataset=dict(
        type='DOTADataset',
        data_root='data/DOTA/optship1280/',
        ann_file='val/obb_annfiles/',
        data_prefix=dict(img_path='val/images/'),
        img_shape=(1280, 1280),
        test_mode=True,
        pipeline=[
            dict(
                type='mmdet.LoadImageFromFile',
                file_client_args=dict(backend='disk')),
            dict(type='mmdet.Resize', scale=(1280, 1280), keep_ratio=True),
            dict(
                type='mmdet.LoadAnnotations', with_bbox=True, box_type='qbox'),
            dict(
                type='ConvertBoxType',
                box_type_mapping=dict(gt_bboxes='rbox')),
            dict(
                type='mmdet.Pad',
                size=(1280, 1280),
                pad_val=dict(img=(114, 114, 114))),
            dict(
                type='mmdet.PackDetInputs',
                meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',
                           'scale_factor'))
        ]))
val_evaluator = dict(type='DOTAMetric', metric='mAP')
test_evaluator = dict(type='DOTAMetric', metric='mAP')
checkpoint = '/media/lhy/mmrotate-1.0.0rc1/work_dirs/pretrain/cspnext-tiny_imagenet_600e.pth'
angle_version = 'le90'
model = dict(
    type='mmdet.RTMDet',
    data_preprocessor=dict(
        type='mmdet.DetDataPreprocessor',
        mean=[103.53, 116.28, 123.675],
        std=[57.375, 57.12, 58.395],
        bgr_to_rgb=False,
        boxtype2tensor=False,
        batch_augments=None),
    backbone=dict(
        type='mmdet.CSPNeXt',
        arch='P5',
        expand_ratio=0.5,
        deepen_factor=0.167,
        widen_factor=0.375,
        channel_attention=True,
        norm_cfg=dict(type='SyncBN'),
        act_cfg=dict(type='SiLU'),
        init_cfg=dict(
            type='Pretrained',
            prefix='backbone.',
            checkpoint=
            '/media/lhy/mmrotate-1.0.0rc1/work_dirs/pretrain/cspnext-tiny_imagenet_600e.pth'
        )),
    neck=dict(
        type='mmdet.CSPNeXtPAFPN',
        in_channels=[96, 192, 384],
        out_channels=96,
        num_csp_blocks=1,
        expand_ratio=0.5,
        norm_cfg=dict(type='SyncBN'),
        act_cfg=dict(type='SiLU')),
    bbox_head=dict(
        type='RotatedRTMDetSepBNHead',
        num_classes=22,
        in_channels=96,
        stacked_convs=2,
        feat_channels=96,
        angle_version='le90',
        anchor_generator=dict(
            type='mmdet.MlvlPointGenerator', offset=0, strides=[8, 16, 32]),
        bbox_coder=dict(type='DistanceAnglePointCoder', angle_version='le90'),
        loss_cls=dict(
            type='mmdet.QualityFocalLoss',
            use_sigmoid=True,
            beta=2.0,
            loss_weight=1.0),
        loss_bbox=dict(type='RotatedIoULoss', mode='linear', loss_weight=2.0),
        with_objectness=False,
        exp_on_reg=False,
        share_conv=True,
        pred_kernel_size=1,
        use_hbbox_loss=False,
        scale_angle=False,
        loss_angle=None,
        norm_cfg=dict(type='SyncBN'),
        act_cfg=dict(type='SiLU')),
    train_cfg=dict(
        assigner=dict(
            type='mmdet.DynamicSoftLabelAssigner',
            iou_calculator=dict(type='RBboxOverlaps2D'),
            topk=13),
        allowed_border=-1,
        pos_weight=-1,
        debug=False),
    test_cfg=dict(
        nms_pre=2000,
        min_bbox_size=0,
        score_thr=0.05,
        nms=dict(type='nms_rotated', iou_threshold=0.1),
        max_per_img=2000))
launcher = 'none'
work_dir = 'work_dirs/runs/train/rtmdet_tiny_rrship/'

模型验证发现模型检测的目标远远多于真实的目标,我们修改配置文件的训练数据集路径为trainval,扩大训练样本。

4、mmrotate模型测试

修改模型测试评估的域值map(mmrotate/evaluation/metrics/dota_metric.py)

模型默认的iou阈值为0.5,可以修改为0.75等。

single GPU

single node multiple GPU

multiple node

可以使用以下命令推断数据集。

# single-gpu
python tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [optional arguments]

# multi-gpu
./tools/dist_test.sh ${CONFIG_FILE} ${CHECKPOINT_FILE} ${GPU_NUM} [optional arguments]

# multi-node in slurm environment
python tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [optional arguments] --launcher slurm

例子:

在DOTA-1.0数据集上推理RotatedRetinaNet,可以生成压缩文件在线提交。(请先更改data_root。)

python ./tools/test.py  \
  configs/rotated_retinanet/rotated-retinanet-rbox-le90_r50_fpn_1x_dota.py \
  checkpoints/SOME_CHECKPOINT.pth --format-only \
  --eval-options submission_dir=work_dirs/Task1_results

或者

./tools/dist_test.sh  \
  configs/rotated_retinanet/rotated-retinanet-rbox-le90_r50_fpn_1x_dota.py \
  checkpoints/SOME_CHECKPOINT.pth 1 --format-only \
  --eval-options submission_dir=work_dirs/Task1_results

您可以将data_root中的test set路径改为val set或trainval set进行离线评估。

python ./tools/test.py \
  configs/rotated_retinanet/rotated-retinanet-rbox-le90_r50_fpn_1x_dota.py \
  checkpoints/SOME_CHECKPOINT.pth --eval mAP

或者

./tools/dist_test.sh  \
  configs/rotated_retinanet/rotated-retinanet-rbox-le90_r50_fpn_1x_dota.py \
  checkpoints/SOME_CHECKPOINT.pth 1 --eval mAP

您还可以可视化结果。

python ./tools/test.py \
  configs/rotated_retinanet/rotated-retinanet-rbox-le90_r50_fpn_1x_dota.py \
  checkpoints/SOME_CHECKPOINT.pth \
  --show-dir work_dirs/vis

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

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

相关文章

国外客户只想跟工厂合作?可以这样破解

1.客户是愿意和外贸公司合作还是更愿意和工厂合作?一个外贸公司的朋友说:“我去工厂接待过七八次外国人,基本上都是英国、德国、日本、加拿大、美国的。”贸易公司根本不避讳自己是贸易公司,外国人也不在乎。他们更关心的是贸易公司能否妥善安…

十五载厚积薄发,电信级分布式数据库是这样炼成

所在论坛:数据库技术创新&云原生论坛 分享时段:2.18 10:00-10:30 分享主题:大规模并行处理:AntDB分布式演进之路 分享嘉宾:沈夺,亚信科技AntDB数据库内核开发工程师 由中国开源软件推进联盟Postgre…

JFET(结型场效应管)

JFET的结构示意图 参考:https://blog.csdn.net/weixin_45882303/article/details/106008695 下图是实际结构图, 下面是原理图和符号表示(参考连接中的图片) 分析 VGS 对电压id的控制(固定VDS) 当让D和…

华为OD机试 - 箱子之字形摆放(Python)| 核心知识点 + 代码编写思路

箱子之字形摆放 题目 有一批箱子(形式为字符串,设为str), 要求将这批箱子按从上到下以之字形的顺序摆放在宽度为 n 的空地,请输出箱子的摆放位置。 例如:箱子ABCDEFG,空地宽度为3,摆放结果如图: 则输出结果为: AFG BE CD 输入 输入一行字符串,通过空格分隔,前面…

别具一格,原创唯美浪漫情人节表白专辑,(复制就可用)(html5,css3,svg)表白爱心代码(3)

别具一格,原创唯美浪漫情人节表白专辑, (复制就可用)(html5,css3,svg)表白爱心代码(3) 目录 款式三:心形实时显示认识多长时间桃花飞舞(猫咪)款 1、拷贝完整源代码 2、拷贝完整js代码 3、修改时间 4、…

深入浅出带你学习shiro-550漏洞

//发点去年存货 前言 apache shiro是一个java安全框架,作用是提供身份验证,Apache Shiro框架提供了一个Rememberme的功能,存储在cookie里面的Key里面,攻击者可以使用Shiro的默认密钥构造恶意序列化对象进行编码来伪造用户的 Cookie&#xf…

一起学习用Verilog在FPGA上实现CNN----(七)全连接层设计

1 全连接层设计 1.1 Layer 进行线性计算的单元layer,原理图如图所示: 1.2 processingElement Layer中的线性计算单元processingElement,原理图如图所示: processingElement模块展开原理图,如图所示,包含…

Transformation(转换算子)

分布式代码的分析 启动spark程序的代码 在yarn中启动(没有配置环境变量) /export/server/spark/bin/spark-submit --master yarn --num-executors 6 /root/helloword.py # 配置环境变量 spark-submit --master yarn --num-executors 6 /root/helloword.py RDD的五大特征 1、…

ZYNQ-嵌入式学习(4)

GPIO之MIO中断GPIO的MIO中断功能实验:使用GPIO的MIO中断功能,实现按键控制LED的亮灭。GPIO的MIO中断功能 从MIO输入到GPIO的线路有一个通向中断检测模块的分支。 INT_TYPE寄存器表示中断类型。包括边沿和电平两种类型。 INT_POLARITY寄存器表示极性。包括…

基于 STM32+FPGA 的多轴运动控制器的设计

运动控制器是数控机床、高端机器人等自动化设备控制系统的核心。为保证控制器的实用性、实时性和稳定 性,提出一种以 STM32 为主控制器、FPGA 为辅助控制器的多轴运动控制器设计方案。给出了运动控制器的硬件电路设计, 将 S 形加减速算法融入运动控制器&…

【Git】合并多条 commit 注释信息

文章目录1、查看 commit 记录2、合并 commit 注释1、查看 commit 记录 # 3 指的是查看最近 3 次的 commit 记录,如果要查看多次的可以修改数字 # -3 不加,则表示查看所有 commit 记录,一般还是用数字去指定 git log -32、合并 commit 注释 …

【图像分类】基于PyTorch搭建LSTM实现MNIST手写数字体识别(单向LSTM,附完整代码和数据集)

写在前面: 首先感谢兄弟们的关注和订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 提起LSTM大家第一反应是在NLP的数据集上比较常见,不过在图片分类中,它同样也可以使用。我们以比较熟悉的 mnist…

软件测试面试自我介绍/项目介绍居然还有模板?我要是早点发现就好了

目录 1、自我介绍 2、项目介绍 2.1、最全电商项目介绍 2.2、电商项目介绍 2.3、在线教育项目介绍 2.4、互联网金融项目介绍 总结 1、自我介绍 以XXX简历来举例(参照下面的案例,编写你的自我介绍,框架就是:我是谁&#xff0…

深入Kafka核心设计与实践原理读书笔记第三章消费者

消费者 消费者与消费组 消费者Consumer负责定于kafka中的主题Topic,并且从订阅的主题上拉取消息。与其他消息中间件不同的在于它有一个消费组。每个消费者对应一个消费组,当消息发布到主题后,只会被投递给订阅它的消费组的一个消费者。 如…

go gin学习记录1

环境: MAC M1,Go 1.17.2,GoLand 默认执行指令的终端,如果没有特别说明,指的都是goland->Terminal 创建项目 Goland中新建项目,在$GOPATH/src/目录下建立t_gin项目。 进入项目,在goland的T…

spark04-文件读取分区数据分配原理

接 https://blog.csdn.net/oracle8090/article/details/129013345?spm1001.2014.3001.5502通过上一节知道 总字节数为7 每个分区字节数为3代码val conf: SparkConf new SparkConf().setMaster("local").setAppName("wordcount")val sc: SparkContext ne…

日日顺供应链|想要看清供应链发展趋势,先回答这三个问题

技术变革如何支撑供应链及管理服务的发展? 数字化与科技化开始承托供应链管理能力的升级与变革? 如何从客户需求的纬度反推供应链及管理服务的模式变革?在过去的三年中,我国的供应链企业经受了最为极端的挑战,但当下&a…

论文写作——公式编辑器、latex表格、颜色搭配器

1、公式编辑器(网页版mathtype可用于latex公式编辑): MathType demo - For DevelopersLive demonstration about the features of Mathtype which allows edition equations and formulas (PNG, flash, SVG, PDF, EPS), based on MathML and compatible with LaTeX.https:/…

C++之可调用对象、bind绑定器和function包装器

可调用对象在C中,可以像函数一样调用的有:普通函数、类的静态成员函数、仿函数、lambda函数、类的非静态成员函数、可被转换为函数的类的对象,统称可调用对象或函数对象。可调用对象有类型,可以用指针存储它们的地址,可…

孙子兵法-36计

目录 04、攻其无备,出其不意。——《孙子兵法始计篇》 08、不战而屈人之兵,善之善者也。——《孙子兵法谋攻篇》 09、上兵伐谋,其次伐交,其次伐兵,其下攻城。 01、兵者,国之大事,死生之地&…