阿里云 邮件推送 DirectMail OP25B对策

阿里云 ECS 服务器默认已禁用 25 端口。如果要从 ECS 通过邮件推送的 SMTP 发信,
不加密时,可以使用 80 端口;
SSL 加密时,可使用 465 端口。

附上邮件推送的 SMTP 发信地址

SMTP 服务地址(华东 1): smtpdm.aliyun.com

SMTP 服务地址(新加坡):smtpdm-ap-southeast-1.aliyun.com

SMTP 服务地址(悉尼):smtpdm-ap-southeast-2.aliyun.com

SMTP 服务地址(虚商用户): smtpdm-ap-southeast-1.aliyuncs.com

Excel VBA 常用操作 2023

  1. 逗号分隔字符串,输出分割后的值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Sub splitStr()
    Dim msg As String

    splitedArr = Split(Cells(1, 1).Value, ",")
    For i = LBound(splitedArr) To UBound(splitedArr)
    msg = msg & splitedArr(i) & vbNewLine
    Next i
    MsgBox msg
    End Sub
  2. Excel列字母和数字的相互转换,用于Cells函数取值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Sub convertColNumAndLetter()
    Dim col As String
    Dim colInNum As Long
    Dim colInLetter As String
    Dim msg As String

    col = "AA"

    colInNum = Range(col & 1).Column
    colInLetter = Split(Cells(1, colInNum).Address, "$")(1)

    msg = col & " 's number is " & colInNum & vbNewLine & colInNum & " 's letter is " & colInLetter

    MsgBox msg
    End Sub
  3. 打开Excel文件的指定sheet。
    On Error Resume Next 可以规避【expecting object to be local】错误

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Sub openExcelFile()
    Dim sheetName As String

    sheetName = "result"

    On Error Resume Next
    With Workbooks.Open("D:\tmp\tmp.xlsx")
    With .Worksheets(sheetName)
    .Activate
    Cells(1, 1).Value = 1
    End With
    .Save
    .Close
    End With
    End Sub

通过 EasyDeploy 部署训练完成的 MMYOLO 模型 - 2023-03最新版

为什么需要工具来部署模型 ?
在模型训练阶段,我们经常会通过引入大量库,构建PyTorch、TensorFlow的学习环境,但是,真实生产环境下无法完成复杂的配置,保存庞大的模型。
现在比较有效的方式是把训练后的模型转换成描述网络结构的中间表示(比如ONNX),再部署到相应环境。

ONNX(英语:Open Neural Network Exchange)是一种针对机器学习所设计的开放式的文件格式,用于存储训练好的模型。它使得不同的人工智能框架(如Pytorch、MXNet)可以采用相同格式存储模型数据并交互。 ONNX的规范及代码主要由微软,亚马逊,Facebook和IBM等公司共同开发,以开放源代码的方式托管在Github上。目前官方支持加载ONNX模型并进行推理的深度学习框架有: Caffe2, PyTorch, MXNet,ML.NET,TensorRT 和 Microsoft CNTK,并且 TensorFlow 也非官方的支持ONNX。

部署步骤

  1. 进入安装好的conda虚拟环境

    1
    2
    3
    4
    5
    conda activate mmyolo
    pip install onnx
    pip install onnxruntime
    # 如果需要使用 simplify 功能需要安装
    pip install onnx-simplifier
  2. 训练完成的模型部署

    1
    2
    3
    4
    # 转到 MMYOLO 程序目录
    D:
    cd D:\yolo\202303-mmyolo
    python projects/easydeploy/tools/export.py configs/yolov5/yolov5_s-v61_fast_1xb12-40e_cat-202303.py work_dirs/yolov5_s-v61_fast_1xb12-40e_cat-202303/epoch_40.pth --work-dir work_dirs/yolov5_s-v61_fast_1xb12-40e_cat-202303 --img-size 640 640 --batch 1 --device cpu --simplify --opset 11 --backend 1 --pre-topk 1000 --keep-topk 100 --iou-threshold 0.65 --score-threshold 0.25

    转换后的模型存放于202303-mmyolo目录下的【work_dirs/yolov5_s-v61_fast_1xb12-40e_cat-202303\end2end.onnx】

  • 如果程序报错:ModuleNotFoundError: No module named ‘projects’
    可以在【projects/easydeploy/tools/export.py】的13行前加上以下代码
    1
    2
    3
    4
    5
    6
    # 添加如下两行
    import sys
    sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))

    # 13行原始代码
    from projects.easydeploy.model import DeployModel
  1. 验证转换后的onnx模型
    从网上寻找Free版权的猫片,进行验证。命令如下:
    1
    python projects/easydeploy/tools/image-demo.py data/cat/images/cat-test-202303.jpg configs/yolov5/yolov5_s-v61_fast_1xb12-40e_cat-202303.py work_dirs/yolov5_s-v61_fast_1xb12-40e_cat-202303/end2end.onnx --device cpu
    由于MMYOLO程序的pytorch版本有点旧,直接执行会报错误:AttributeError: module ‘torch’ has no attribute ‘asarray’
    可以修改 projects/easydeploy/tools/image-demo.py 来解决。
    1
    2
    3
    4
    5
    6
    # 修改前 100~104行
    pad_param = torch.asarray(
    [pad_param[2], pad_param[0], pad_param[2], pad_param[0]],
    device=args.device)
    scale_factor = samples.get('scale_factor', [1., 1])
    scale_factor = torch.asarray(scale_factor * 2, device=args.device)
    1
    2
    3
    4
    # 修改后
    pad_param = torch.from_numpy(np.array([pad_param[2], pad_param[0], pad_param[2], pad_param[0]]))
    scale_factor = samples.get('scale_factor', [1., 1])
    scale_factor = torch.from_numpy(np.array([scale_factor * 2]))

参考文档:https://mmyolo.readthedocs.io/zh_CN/latest/get_started/15_minutes_object_detection.html

15 分钟上手 MMYOLO 目标检测 - Windows10平台 - 2023-03最新版

操作步骤

  1. 进入安装好的conda虚拟环境

    1
    2
    3
    conda activate mmyolo
    D:
    cd D:\yolo
  2. 下载mmyolo代码,安装依赖,下载数据集

    1
    2
    3
    4
    git clone https://github.com/open-mmlab/mmyolo.git 202303-mmyolo
    mim install -r requirements/albu.txt
    cd 202303-mmyolo
    python tools/misc/download_dataset.py --dataset-name cat --save-dir ./data/cat --unzip --delete

    下载后的数据集存放于202303-mmyolo目录下的【data/cat/images】

  3. 使用优化后的配置设定
    在configs/yolov5 文件夹下新建 yolov5_s-v61_fast_1xb12-40e_cat-202303.py,代码如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    # 基于该配置进行继承并重写部分配置
    _base_ = 'yolov5_s-v61_syncbn_fast_8xb16-300e_coco.py'

    data_root = './data/cat/' # 数据集根路径
    class_name = ('cat', ) # 数据集类别名称
    num_classes = len(class_name) # 数据集类别数
    # metainfo 必须要传给后面的 dataloader 配置,否则无效
    # palette 是可视化时候对应类别的显示颜色
    # palette 长度必须大于或等于 classes 长度
    metainfo = dict(classes=class_name, palette=[(20, 220, 60)])

    # 基于 tools/analysis_tools/optimize_anchors.py 自适应计算的 anchor
    anchors = [
    [(68, 69), (154, 91), (143, 162)], # P3/8
    [(242, 160), (189, 287), (391, 207)], # P4/16
    [(353, 337), (539, 341), (443, 432)] # P5/32
    ]
    # 最大训练 40 epoch
    max_epochs = 40
    # bs 为 12
    train_batch_size_per_gpu = 12
    # dataloader 加载进程数
    train_num_workers = 4

    # 加载 COCO 预训练权重
    load_from = 'https://download.openmmlab.com/mmyolo/v0/yolov5/yolov5_s-v61_syncbn_fast_8xb16-300e_coco/yolov5_s-v61_syncbn_fast_8xb16-300e_coco_20220918_084700-86e02187.pth' # noqa

    model = dict(
    # 固定整个 backbone 权重,不进行训练
    backbone=dict(frozen_stages=4),
    bbox_head=dict(
    head_module=dict(num_classes=num_classes),
    prior_generator=dict(base_sizes=anchors)
    ))

    train_dataloader = dict(
    batch_size=train_batch_size_per_gpu,
    num_workers=train_num_workers,
    dataset=dict(
    data_root=data_root,
    metainfo=metainfo,
    # 数据集标注文件 json 路径
    ann_file='annotations/trainval.json',
    # 数据集前缀
    data_prefix=dict(img='images/')))

    val_dataloader = dict(
    dataset=dict(
    metainfo=metainfo,
    data_root=data_root,
    ann_file='annotations/test.json',
    data_prefix=dict(img='images/')))

    test_dataloader = val_dataloader

    _base_.optim_wrapper.optimizer.batch_size_per_gpu = train_batch_size_per_gpu

    val_evaluator = dict(ann_file=data_root + 'annotations/test.json')
    test_evaluator = val_evaluator

    default_hooks = dict(
    # 每隔 10 个 epoch 保存一次权重,并且最多保存 2 个权重
    # 模型评估时候自动保存最佳模型
    checkpoint=dict(interval=10, max_keep_ckpts=2, save_best='auto'),
    # warmup_mim_iter 参数非常关键,因为 cat 数据集非常小,默认的最小 warmup_mim_iter 是 1000,导致训练过程学习率偏小
    param_scheduler=dict(max_epochs=max_epochs, warmup_mim_iter=10),
    # 日志打印间隔为 5
    logger=dict(type='LoggerHook', interval=5))
    # 评估间隔为 10
    train_cfg = dict(max_epochs=max_epochs, val_interval=10)
  4. 模型训练

    1
    2
    3
    python tools/train.py configs/yolov5/yolov5_s-v61_fast_1xb12-40e_cat-202303.py
    中间可以 Ctrl + C 中断,需要恢复的话使用如下命令
    python tools/train.py configs/yolov5/yolov5_s-v61_fast_1xb12-40e_cat-202303.py --resume

日志最后部分如下
03/21 22:26:43 - mmengine - INFO - Epoch(val) [40][25/28] eta: 0:00:00 time: 0.1056 data_time: 0.0502 memory: 117
03/21 22:26:43 - mmengine - INFO - Evaluating bbox…
Loading and preparing results…
DONE (t=0.01s)
creating index…
index created!
Running per image evaluation…
Evaluate annotation type bbox
DONE (t=0.16s).
Accumulating evaluation results…
DONE (t=0.02s).
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.000
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.002
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.000
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = -1.000
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = -1.000
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.000
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.000
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.000
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.083
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = -1.000
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = -1.000
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.083
03/21 22:26:44 - mmengine - INFO - bbox_mAP_copypaste: 0.000 0.002 0.000 -1.000 -1.000 0.000
03/21 22:26:45 - mmengine - INFO - Epoch(val) [40][28/28] coco/bbox_mAP: 0.0000 coco/bbox_mAP_50: 0.0020 coco/bbox_mAP_75: 0.0000 coco/bbox_mAP_s: -1.0000 coco/bbox_mAP_m: -1.0000 coco/bbox_mAP_l: 0.0000data_time: 0.0532 time: 0.1111

  1. 用训练完的参数进行测试

    1
    python tools/test.py configs/yolov5/yolov5_s-v61_fast_1xb12-40e_cat-202303.py work_dirs/yolov5_s-v61_fast_1xb12-40e_cat-202303/epoch_40.pth --show-dir show_results

    日志最后部分如下
    03/21 23:00:05 - mmengine - INFO - bbox_mAP_copypaste: 0.733 0.957 0.835 -1.000 -1.000 0.733
    03/21 23:00:05 - mmengine - INFO - Epoch(test) [28/28] coco/bbox_mAP: 0.7330 coco/bbox_mAP_50: 0.9570 coco/bbox_mAP_75: 0.8350 coco/bbox_mAP_s: -1.0000 coco/bbox_mAP_m: -1.0000 coco/bbox_mAP_l: 0.7330data_time: 2.8175 time: 3.1257
    wandb: Waiting for W&B process to finish… (success).
    wandb: View run light-snow-2 at: https://wandb.ai/zhangna-jp/202303-mmyolo-tools/runs/xh6coxf4
    wandb: Synced 6 W&B file(s), 0 media file(s), 351 artifact file(s) and 0 other file(s)
    wandb: Find logs at: .\work_dirs\yolov5_s-v61_fast_1xb12-40e_cat-202303\20230321_225807\vis_data\wandb\run-20230321_225820-xh6coxf4\logs

  2. 测试结果展示

参考文档:https://mmyolo.readthedocs.io/zh_CN/latest/get_started/15_minutes_object_detection.html

Windows10平台 MMYOLO 环境安装搭建 2023-03最新版

搭建步骤

  1. 安装包管理工具 Miniconda,配置环境变量
    Miniconda下载地址
    本次选择 【Latest Miniconda Installer Links -> Miniconda3 Windows 64-bit】,
    安装到整个计算机,默认安装路径是【C:\ProgramData\miniconda3】。
    完成后添加环境变量:【系统】->【Path】->【新建】->【C:\ProgramData\miniconda3\Scripts】

  2. 创建激活conda环境
    打开Windows命令行,执行如下命令

    1
    2
    3
    conda create -n mmyolo python=3.8 -y
    conda init cmd.exe <- 完成后,关闭当前命令行窗口,然后新开一个
    conda activate mmyolo
  3. 安装 PyTorch
    *CPU 平台

    1
    2
    3
    4
    5
    6
    7
    conda install pytorch torchvision cpuonly -c pytorch
    conda list | findstr pytorch
    结果显式为CPU版本的pytorch
    cpuonly 2.0 0 pytorch
    pytorch 2.0.0 py3.8_cpu_0 pytorch
    pytorch-mutex 1.0 cpu pytorch
    torchvision 0.15.0 py38_cpu pytorch

    *GPU 平台

    1
    2
    3
    4
    5
    6
    7
    conda install pytorch=*=*cuda10.2* torchaudio torchvision cudatoolkit=10.2 -c pytorch
    conda list | findstr pytorch
    结果显式为带cuda的GPU版本的pytorch
    pytorch 1.10.2 py3.8_cuda10.2_cudnn7_0 pytorch
    pytorch-mutex 1.0 cuda pytorch
    torchaudio 0.10.2 py38_cu102 pytorch
    torchvision 0.11.3 py38_cu102 pytorch

    如果误装了CPU平台,卸载cpuonly未能实现顺利重装,最简单的方法是新建虚拟环境装GPU版本。

  4. 验证 PyTorch 安装
    *CPU平台

    1
    2
    3
    4
    python -c "import torch; print(torch.__version__); print(torch.cuda.is_available())"
    预期输出
    2.0.0
    False

    *GPU平台

    1
    2
    3
    4
    python -c "import torch; print(torch.__version__); print(torch.cuda.is_available())"
    预期输出
    1.10.2
    True
  5. 使用 MIM 安装 MMEngine、 MMCV 和 MMDetection

    1
    2
    3
    4
    pip install -U openmim
    mim install "mmengine>=0.6.0"
    mim install "mmcv>=2.0.0rc4,<2.1.0"
    mim install "mmdet>=3.0.0rc6,<3.1.0"
  6. 使用 MIM 安装 MMYOLO

    1
    mim install "mmyolo"
  7. 下载配置文件和模型权重文件

    1
    mim download mmyolo --config yolov5_s-v61_syncbn_fast_8xb16-300e_coco --dest .
  8. 从python解析器,粘贴执行以下代码,验证
    命令行的当前目录新建【demo】文件夹,存放验证用图片【demo.jpg】

    1
    2
    3
    4
    5
    6
    python
    from mmdet.apis import init_detector, inference_detector
    config_file = 'yolov5_s-v61_syncbn_fast_8xb16-300e_coco.py'
    checkpoint_file = 'yolov5_s-v61_syncbn_fast_8xb16-300e_coco_20220918_084700-86e02187.pth'
    model = init_detector(config_file, checkpoint_file, device='cpu') # or device='cuda:0'
    inference_detector(model, 'demo/demo.jpg')

    得到以下输出即代表安装成功

    1
    2
    3
    4
    5
    6
    >>> inference_detector(model, 'demo/demo.jpg')
    <DetDataSample(

    META INFORMATION
    ori_shape: (375, 500)
    img_path: 'demo/demo.jpg'

下一篇文章:15 分钟上手 MMYOLO 目标检测

参考文档:https://mmyolo.readthedocs.io/zh_CN/latest/get_started/dependencies.html

小知识

MM:Multimedia 的简写
YOLO:You only look once 的简写

Hexo 报错: Cannot read property 'utcOffset' of null

配置完【_config.yml】后执行hexo报如下错误:

1
2
3
4
5
6
7
8
9
10
11
12
INFO  Validating config
INFO Start processing
ERROR {
err: TypeError: Cannot read properties of null (reading 'utcOffset')
at exports.timezone (/opt/blog-another-se/node_modules/hexo/lib/plugins/processor/common.js:56:42)
at /opt/blog-another-se/node_modules/hexo/lib/plugins/processor/post.js:123:36
...

at _drainQueueStep (/opt/blog-another-se/node_modules/bluebird/js/release/async.js:93:12)
} Process failed: %s _posts/test.md
INFO Files loaded in 268 ms
Moment Timezone has no data for Asian/Tokyo. See http://momentjs.com/timezone/docs/#/data-loading/.

检查半天才发现是低级错误,把Asia 给写成了 Asian …/捂脸

【eNSP】安装完打包报错:VirtualBox version is not supported.

现象

eNSP版本:1.3.00.100
安装【eNSP】时,VirtualBox是6.1.8版本,安装过程可以正确识别到VirtualBox,顺利完成安装。但是打开eNSP时,提示以下错误

VirtualBox version is not supported

解决方法

  1. 安装VirtualBox 5.2.8
    eNSP(v1.3.00.100)所支持的VirtualBox版本是5.2.8,卸载现有的6.1.8后,从以下地址下载5.2.8版本,安装后,错误提示消失。
    VirtualBox 5.2.8 下载地址
    VirtualBox-5.2.38-136252-Win.exe

  2. 重新注册虚拟机镜像
    打开eNSP右上角的【菜单】 -》 【工具】 -》 【注册设备】,选中右侧所有的设备点击【注册】,即可正常使用eNSP启动设备了。