车牌检测模型训练(含源码和数据集)

news2024/9/18 15:53:43

车牌检测模型训练(含源码和数据集)

本教程利用NVIDIA TAO进行车牌检测模型的训练:

  1. 模型框架:SSD
  2. 数据集: CRPD, 连接:https://github.com/yxgong0/CRPD
  3. 训练框架: NVIDIA TAO, 安装教程连接: https://docs.nvidia.com/tao/tao-toolkit/text/tao_toolkit_quick_start_guide.html#tao-toolkit-package-content
  4. 预训练模型: 可从NGC下载, 连接:https://catalog.ngc.nvidia.com/orgs/nvidia/teams/tao/models/pretrained_object_detection/files
  5. 本教程文件夹目录(不含数据和模型): 链接:https://pan.baidu.com/s/1IKrXQX3m21bzFSOljrDULA
    提取码:0512

教程目录

  1. 设置环境以及路径
  2. 安装TAO启动器
  3. 准备数据集和预训练模型

    2.1 下载预训练模型
  4. 定义训练参数
  5. 利用TAO开始训练
  6. 评估模型
  7. 剪枝模型
  8. 重新训练模型
  9. 评估模型
  10. 可视化推理
  11. 模型导出
  12. 验证部署模型

0.设置环境以及路径

NVIDIA TAO是以docker镜像的形式运行, 我们需要设置自己的计算机系统和docker镜像内系统的路径映射关系.

我们采用了clearml的可视化技术, 可以利用clearml来监测我们的训练过程, 这里还需要设置clearml相关的配置信息

import os

print("Please replace the variable with your key.")
#设置NVIDIA TAO的api key, 这个key是用来加密你的模型的
%env KEY=nvidia_tlt
%env GPU_INDEX=0

#设置实验路径和数据集路径, 这里的路径指的是docker镜像内部的路径
%env USER_EXPERIMENT_DIR=/workspace/tao-experiments/ssd
%env DATA_DOWNLOAD_DIR=/workspace/tao-experiments/data

#设置clearml的相关配置信息
%env CLEARML_WEB_HOST=https://app.clear.ml
%env CLEARML_API_HOST=https://api.clear.ml
%env CLEARML_FILES_HOST=https://files.clear.ml
%env CLEARML_API_ACCESS_KEY=SY1OMSO6JY6W24WVBHOR
%env CLEARML_API_SECRET_KEY=URcjcox7nx9YIE7mDFoabr1CsdVcMWKSU0NPb5machH3aPP8FZ

#这里设置的路径是指的你自己计算机系统的路径, 当前设置的是我的, 你需要根据你自己的实验路径更改
%env LOCAL_PROJECT_DIR=/home/hekun/mydata/tao-3.0-sample/cv_samples_v1.4.0/ssd
os.environ["LOCAL_DATA_DIR"] = os.path.join(os.getenv("LOCAL_PROJECT_DIR", os.getcwd()), "data")
os.environ["LOCAL_EXPERIMENT_DIR"] = os.path.join(os.getenv("LOCAL_PROJECT_DIR", os.getcwd()), "ssd")

#这里设置的是训练,数据转换等定义文件的存放路径
os.environ["LOCAL_SPECS_DIR"] = os.path.join(
    os.getenv("NOTEBOOK_ROOT", os.getcwd()),
    "specs"
)
%env SPECS_DIR=/workspace/tao-experiments/ssd/specs


!ls -rlt $LOCAL_SPECS_DIR

下面的单元格将本地主机上的项目目录映射到 TAO docker 实例中的工作区目录,以便数据和结果从 docker 中映射出来。 更多信息请参考用户指南中的启动器实例。

envs里面指的是clearml可视化的设置信息, 你需要根据你自己的账户设置CLEARML_API_ACCESS_KEYCLEARML_API_SECRET_KEY

# Mapping up the local directories to the TAO docker.
import json
mounts_file = os.path.expanduser("~/.tao_mounts.json")

# Define the dictionary with the mapped drives
drive_map = {
    "Mounts": [
            # Mapping the data directory
            {
                "source": os.environ["LOCAL_PROJECT_DIR"],
                "destination": "/workspace/tao-experiments"
            },
            # Mapping the specs directory.
            {
                "source": os.environ["LOCAL_SPECS_DIR"],
                "destination": os.environ["SPECS_DIR"]
            },
        ],
    "Envs": [
        {
            "variable": "CLEARML_WEB_HOST",
            "value": "https://app.clear.ml"
        },
        {
            "variable": "CLEARML_API_HOST",
            "value": "https://api.clear.ml"
        },
        {
            "variable": "CLEARML_FILES_HOST",
            "value": "https://files.clear.ml"
        },
        {
            "variable": "CLEARML_API_ACCESS_KEY",
            "value": "SY1OMSO6JY6W24WVBHOR"
        },
        {
            "variable": "CLEARML_API_SECRET_KEY",
            "value": "URcjcox7nx9YIE7mDFoabr1CsdVcMWKSU0NPb5machH3aPP8FZ"
        }
    ],
    "DockerOptions": {
        "shm_size": "16G",
        "ulimits": {
            "memlock": -1,
            "stack": 67108864
        },
        "user": "1000:1000",
        "ports": {
            "8888": 8888
        }
    }
}

# Writing the mounts file.
with open(mounts_file, "w") as mfile:
    json.dump(drive_map, mfile, indent=4)
!cat ~/.tao_mounts.json

1. 安装tao启动器

TAO 启动器是一个 python 包,作为 PyPI 中列出的 python wheel 分发。 您可以通过执行以下单元格来安装启动器。

请注意,TAO Toolkit 建议用户使用 python 3.6.9 在虚拟环境中运行 TAO 启动器。 您可以按照此 页面 中的说明使用 virtualenvvirtualenvwrapper 包设置 python 虚拟环境。 设置 virtualenvwrapper 后,请使用 VIRTUALENVWRAPPER_PYTHON 变量设置要在虚拟环境中使用的 python 版本。 你可以通过运行来做到这一点

export VIRTUALENVWRAPPER_PYTHON=/path/to/bin/python3.x

其中 x >= 6 且 <= 8

我们建议先执行此步骤,然后从虚拟环境启动笔记本。 除了安装 TAO python 包外,请确保满足以下软件要求:

  • python >=3.6.9 < 3.8.x
  • docker-ce > 19.03.5
  • docker-API 1.40
  • nvidia-container-toolkit > 1.3.0-1
  • nvidia-container-runtime > 3.4.0-1
  • nvidia-docker2 > 2.5.0-1
  • nvidia-driver > 455+

安装先决条件后,请按照以下命令登录到 docker registry nvcr.io

docker login nvcr.io

您将被触发输入用户名和密码。 用户名是“$oauthtoken”,密码是从“ngc.nvidia.com”生成的 API 密钥。 请按照 NGC 设置指南 中的说明生成您自己的 API 密钥。

# SKIP this step IF you have already installed the TAO launcher.
!pip3 install nvidia-tao
# View the versions of the TAO launcher
!tao info

2. 准备数据集和预训练模型

CRPD (Chinese Road Plate Dataset)是一个大型的中文车牌数据集, 它包含三个子集— CRPD-single, CRPD-double ,CRPD-multi. 本教程采用了其中的CRPD-single为例. 他的标注包含:

x1, y1, x2, y2, x3, y3, x4, y4, type, content

  • 前八个数字表示边界四边形角的坐标。
  • “type”标注表示LP的类型,0代表蓝盘,1代表黄盘和单行车牌,2代表黄牌和双行车牌,3代表白牌。
  • “content”注释表示 LP 内容。

由于NVIDIA TAO目标检测模型训练数据集需要KITTI格式, 所以我们需要将数据集的标注进行转换.我已经将转换格式的脚本放在本教程文件夹中, 请查看preprocess_crpd.py文件, 并根据你实际的路径作出简单调整就可以使用

!python3 preprocess_crpd.py

接下来将准备好的数据集分割一部分出来当做测试集

# Generate val dataset out of training dataset
!python3 generate_val_dataset.py --input_image_dir=$LOCAL_DATA_DIR/lpd_images \
                                 --input_label_dir=$LOCAL_DATA_DIR/lpd_labels \
                                 --output_dir=$LOCAL_DATA_DIR/val

当我们准备好数据集之后, 我们需要将数据集转换成tfrecords格式, 这里可以利用tao自带的工具.

我们在这里需要定义数据的路径, 格式, 目标类别等信息.

需要注意的是这里的路径root_directory_path指的是docker系统内的路径

print("TFRecords conversion spec file:")
!cat $LOCAL_SPECS_DIR/ssd_tfrecords_kitti_train.txt

开始转换

# Creating a new directory for the output tfrecords dump.
print("Converting the training set to TFRecords.")
!mkdir -p $LOCAL_DATA_DIR/tfrecords && rm -rf $LOCAL_DATA_DIR/tfrecords/*
!tao ssd dataset_convert \
         -d $SPECS_DIR/ssd_tfrecords_kitti_train.txt \
         -o $DATA_DOWNLOAD_DIR/tfrecords/kitti_train
!ls -rlt $LOCAL_DATA_DIR/tfrecords/

2.1 下载预训练模型

我们将使用 NGC CLI 获取预训练模型。 有关详细信息,请访问 ngc.nvidia.com 并单击导航栏上的 SETUP。

这里如果因为网络的原因没法下载, 也可以手动登录并下载模型:

https://catalog.ngc.nvidia.com/orgs/nvidia/teams/tao/models/pretrained_object_detection/files

# Installing NGC CLI on the local machine.
## Download and install
%env CLI=ngccli_cat_linux.zip
!mkdir -p $LOCAL_PROJECT_DIR/ngccli

# Remove any previously existing CLI installations
!rm -rf $LOCAL_PROJECT_DIR/ngccli/*
!wget "https://ngc.nvidia.com/downloads/$CLI" -P $LOCAL_PROJECT_DIR/ngccli
!unzip -u "$LOCAL_PROJECT_DIR/ngccli/$CLI" -d $LOCAL_PROJECT_DIR/ngccli/
!rm $LOCAL_PROJECT_DIR/ngccli/*.zip 
os.environ["PATH"]="{}/ngccli:{}".format(os.getenv("LOCAL_PROJECT_DIR", ""), os.getenv("PATH", ""))
!ngc registry model list nvidia/tao/pretrained_object_detection:*
!mkdir -p $LOCAL_EXPERIMENT_DIR/pretrained_resnet18/
# Pull pretrained model from NGC
!ngc registry model download-version nvidia/tao/pretrained_object_detection:resnet18 --dest $LOCAL_EXPERIMENT_DIR/pretrained_resnet18
print("Check that model is downloaded into dir.")
!ls -l $LOCAL_EXPERIMENT_DIR/pretrained_resnet18/pretrained_object_detection_vresnet18

3. 定义训练参数

我们需要定义训练的一些参数, 通过scpecs/ssd_train_resnet18_kitti.txt文件来定义:

!cat $LOCAL_SPECS_DIR/ssd_train_resnet18_kitti.txt

4. 利用tao开始训练

接下来我们开始训练, 这个过程会比较久, 你也可以通过clearml来监控训练过程

在这里插入图片描述

!mkdir -p $LOCAL_EXPERIMENT_DIR/experiment_dir_unpruned
print("To run with multigpu, please change --gpus based on the number of available GPUs in your machine.")
!tao ssd train --gpus 1 --gpu_index=$GPU_INDEX \
               -e $SPECS_DIR/ssd_train_resnet18_kitti.txt \
               -r $USER_EXPERIMENT_DIR/experiment_dir_unpruned \
               -k $KEY \
               -m $USER_EXPERIMENT_DIR/pretrained_resnet18/pretrained_object_detection_vresnet18/resnet_18.hdf5
print("To resume from checkpoint, please uncomment and run this instead. Change last two arguments accordingly.")
# !tao ssd train --gpus 1 --gpu_index=$GPU_INDEX \
#                -e $SPECS_DIR/ssd_train_resnet18_kitti.txt \
#                -r $USER_EXPERIMENT_DIR/experiment_dir_unpruned \
#                -k $KEY \
#                -m $USER_EXPERIMENT_DIR/experiment_dir_unpruned/weights/ssd_resnet18_epoch_001.tlt \
#                --initial_epoch 2
print('Model for each epoch:')
print('---------------------')
!ls -ltrh $LOCAL_EXPERIMENT_DIR/experiment_dir_unpruned/weights
# Now check the evaluation stats in the csv file and pick the model with highest eval accuracy.
!cat $LOCAL_EXPERIMENT_DIR/experiment_dir_unpruned/ssd_training_log_resnet18.csv
%set_env EPOCH=080

5. 评估模型

!tao ssd evaluate --gpu_index=$GPU_INDEX \
                  -e $SPECS_DIR/ssd_train_resnet18_kitti.txt \
                  -m $USER_EXPERIMENT_DIR/experiment_dir_unpruned/weights/ssd_resnet18_epoch_$EPOCH.tlt \
                  -k $KEY

6. 模型剪枝

  • 指定预训练模型
  • 设置剪枝阈值

通常,您只需要调整 -pth(阈值)以获得准确性和模型大小的权衡。 更高的 pth 给你更小的模型(因此推理速度更快)但准确性更差。 阈值取决于数据集和模型。 下面块中的“0.5”只是一个起点。 如果重新训练的准确性很好,您可以增加此值以获得更小的模型。 否则,降低此值以获得更好的准确性。

!mkdir -p $LOCAL_EXPERIMENT_DIR/experiment_dir_pruned
!tao ssd prune --gpu_index=$GPU_INDEX \
               -m $USER_EXPERIMENT_DIR/experiment_dir_unpruned/weights/ssd_resnet18_epoch_$EPOCH.tlt \
               -o $USER_EXPERIMENT_DIR/experiment_dir_pruned/ssd_resnet18_pruned.tlt \
               -eq intersection \
               -pth 0.1 \
               -k $KEY
!ls -rlt $LOCAL_EXPERIMENT_DIR/experiment_dir_pruned/

7. 重新训练模型

  • 剪枝后需要重新训练模型以恢复准确率
  • 指定再训练参数
  • 警告:训练需要数小时或一天才能完成
# Printing the retrain spec file. 
# Here we have updated the spec file to include the newly pruned model as a pretrained weights.
!cat $LOCAL_SPECS_DIR/ssd_retrain_resnet18_kitti.txt
!mkdir -p $LOCAL_EXPERIMENT_DIR/experiment_dir_retrain
# Retraining using the pruned model as pretrained weights 
!tao ssd train --gpus 1 --gpu_index=$GPU_INDEX \
               -e $SPECS_DIR/ssd_retrain_resnet18_kitti.txt \
               -r $USER_EXPERIMENT_DIR/experiment_dir_retrain \
               -m $USER_EXPERIMENT_DIR/experiment_dir_pruned/ssd_resnet18_pruned.tlt \
               -k $KEY
# Listing the newly retrained model.
!ls -rlt $LOCAL_EXPERIMENT_DIR/experiment_dir_retrain/weights
# Now check the evaluation stats in the csv file and pick the model with highest eval accuracy.
!cat $LOCAL_EXPERIMENT_DIR/experiment_dir_retrain/ssd_training_log_resnet18.csv
%set_env EPOCH=080

8. 评估模型

!tao ssd evaluate --gpu_index=$GPU_INDEX \
                  -e $SPECS_DIR/ssd_retrain_resnet18_kitti.txt \
                  -m $USER_EXPERIMENT_DIR/experiment_dir_retrain/weights/ssd_resnet18_epoch_$EPOCH.tlt \
                  -k $KEY

9. 可视化推理

在本节中,我们运行 infer 工具来生成对训练模型的推理并可视化结果。

# Running inference for detection on n images
!tao ssd inference --gpu_index=$GPU_INDEX -i $DATA_DOWNLOAD_DIR/test_samples \
                   -o $USER_EXPERIMENT_DIR/ssd_infer_images \
                   -e $SPECS_DIR/ssd_retrain_resnet18_kitti.txt \
                   -m $USER_EXPERIMENT_DIR/experiment_dir_retrain/weights/ssd_resnet18_epoch_$EPOCH.tlt \
                   -l $USER_EXPERIMENT_DIR/ssd_infer_labels \
                   -k $KEY

tao 推理工具产生两个输出。

  1. $USER_EXPERIMENT_DIR/ssd_infer_images 中叠加图像
  2. kitti 格式的逐帧 bbox 标签位于 $USER_EXPERIMENT_DIR/ssd_infer_labels
# Simple grid visualizer
!pip3 install matplotlib==3.3.3
import matplotlib.pyplot as plt
import os
from math import ceil
valid_image_ext = ['.jpg', '.png', '.jpeg', '.ppm']

def visualize_images(image_dir, num_cols=4, num_images=10):
    output_path = os.path.join(os.environ['LOCAL_EXPERIMENT_DIR'], image_dir)
    num_rows = int(ceil(float(num_images) / float(num_cols)))
    f, axarr = plt.subplots(num_rows, num_cols, figsize=[80,30])
    f.tight_layout()
    a = [os.path.join(output_path, image) for image in os.listdir(output_path) 
         if os.path.splitext(image)[1].lower() in valid_image_ext]
    for idx, img_path in enumerate(a[:num_images]):
        col_id = idx % num_cols
        row_id = idx // num_cols
        img = plt.imread(img_path)
        axarr[row_id, col_id].imshow(img) 

# Visualizing the sample images.
OUTPUT_PATH = 'ssd_infer_images' # relative path from $USER_EXPERIMENT_DIR.
COLS = 3 # number of columns in the visualizer grid.
IMAGES = 9 # number of images to visualize.

visualize_images(OUTPUT_PATH, num_cols=COLS, num_images=IMAGES)

10. 模型导出

如果您训练了非 QAT 模型,您可以使用下面的代码块以 FP32、FP16 或 INT8 模式导出。 对于 INT8,您需要提供校准图像目录。

# tao <task> export will fail if .etlt already exists. So we clear the export folder before tao <task> export
!rm -rf $LOCAL_EXPERIMENT_DIR/export
!mkdir -p $LOCAL_EXPERIMENT_DIR/export
# Export in FP32 mode. Change --data_type to fp16 for FP16 mode
!tao ssd export --gpu_index=$GPU_INDEX \
                -m $USER_EXPERIMENT_DIR/experiment_dir_retrain/weights/ssd_resnet18_epoch_$EPOCH.tlt \
                -k $KEY \
                -o $USER_EXPERIMENT_DIR/export/ssd_resnet18_epoch_$EPOCH.etlt \
                -e $SPECS_DIR/ssd_retrain_resnet18_kitti.txt \
                --batch_size 16 \
                --data_type fp32 \
                --gen_ds_config

# Uncomment to export in INT8 mode (generate calibration cache file).
# !tao ssd export --gpu_index=$GPU_INDEX \
#                 -m $USER_EXPERIMENT_DIR/experiment_dir_retrain/weights/ssd_resnet18_epoch_$EPOCH.tlt  \
#                 -o $USER_EXPERIMENT_DIR/export/ssd_resnet18_epoch_$EPOCH.etlt \
#                 -e $SPECS_DIR/ssd_retrain_resnet18_kitti.txt \
#                 -k $KEY \
#                 --cal_image_dir $DATA_DOWNLOAD_DIR/testing/image_2 \
#                 --data_type int8 \
#                 --batch_size 16 \
#                 --batches 10 \
#                 --cal_cache_file $USER_EXPERIMENT_DIR/export/cal.bin  \
#                 --cal_data_file $USER_EXPERIMENT_DIR/export/cal.tensorfile \
#                 --gen_ds_config
print('Exported model:')
print('------------')
!ls -lh $LOCAL_EXPERIMENT_DIR/export

使用 docker 附带的“tao-converter”实用程序验证引擎生成。

tao-converter 为它所在的平台生成优化的 tensorrt 引擎。 因此,为了获得最佳性能,请实例化此 docker 并在目标设备上使用导出的 .etlt 文件和校准缓存(用于 int8 模式)执行 tao-converter 命令。 此 docker 中包含的 tao-converter 实用程序仅适用于具有独立 NVIDIA GPU 的 x86 设备。

对于 jetson 设备,请从开发区链接 此处 下载 tao-converter for jetson。

如果您选择将您的模型直接集成到 deepstream 中,您可以通过简单地将导出的 .etlt 文件连同校准缓存复制到目标设备并更新配置 gst-nvinfer 元素指向的 spec 文件来实现 到这个新导出的模型。 通常,此文件对于检测模型称为“config_infer_primary.txt”,对于分类模型称为“config_infer_secondary_*.txt”。

# Convert to TensorRT engine (FP32)
!tao converter -k $KEY \
                   -d 3,300,300 \
                   -o NMS \
                   -e $USER_EXPERIMENT_DIR/export/trt.engine \
                   -m 16 \
                   -t fp32 \
                   -i nchw \
                   $USER_EXPERIMENT_DIR/export/ssd_resnet18_epoch_$EPOCH.etlt

# Convert to TensorRT engine (FP16)
# !tao converter -k $KEY \
#                    -d 3,300,300 \
#                    -o NMS \
#                    -e $USER_EXPERIMENT_DIR/export/trt.engine \
#                    -m 16 \
#                    -t fp16 \
#                    -i nchw \
#                    $USER_EXPERIMENT_DIR/export/ssd_resnet18_epoch_$EPOCH.etlt

# Convert to TensorRT engine (INT8).
# !tao converter -k $KEY  \
#                    -d 3,300,300 \
#                    -o NMS \
#                    -c $USER_EXPERIMENT_DIR/export/cal.bin \
#                    -e $USER_EXPERIMENT_DIR/export/trt.engine \
#                    -b 8 \
#                    -m 16 \
#                    -t int8 \
#                    -i nchw \
#                    $USER_EXPERIMENT_DIR/export/ssd_resnet18_epoch_$EPOCH.etlt
print('Exported engine:')
print('------------')
!ls -lh $LOCAL_EXPERIMENT_DIR/export/trt.engine

11. 验证部署模型

通过可视化 TensorRT 推理来验证转换后的引擎。

# Infer using TensorRT engine

# The engine batch size once created, cannot be alterred. So if you wish to run with a different batch-size,
# please re-run tlt-convert.

!tao ssd inference --gpu_index=$GPU_INDEX \
                   -m $USER_EXPERIMENT_DIR/export/trt.engine \
                   -e $SPECS_DIR/ssd_retrain_resnet18_kitti.txt \
                   -i $DATA_DOWNLOAD_DIR/test_samples \
                   -o $USER_EXPERIMENT_DIR/ssd_infer_images \
                   -t 0.4
# Visualizing the sample images.
OUTPUT_PATH = 'ssd_infer_images' # relative path from $USER_EXPERIMENT_DIR.
COLS = 3 # number of columns in the visualizer grid.
IMAGES = 9 # number of images to visualize.

visualize_images(OUTPUT_PATH, num_cols=COLS, num_images=IMAGES)

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

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

相关文章

目标检测之YOLOv3算法分析

基本原理 特征网络 输入输出 输入416∗416∗3416*416*3416∗416∗3大小的图片&#xff08;不唯一&#xff0c;但图片大小必为32的倍数&#xff09;&#xff0c;输出3个尺度的feature map,分别为13∗13∗25513*13*25513∗13∗255&#xff0c;26∗26∗25526*26*25526∗26∗255…

RV1126笔记十九:吸烟行为检测及部署<六>

若该文为原创文章,转载请注明原文出处。 模型测试 一、pt文件测试 pt文件是在windows下训练生成的,测试环境为py3.8 1、首先查看虚拟环境列表,然后切换于是py3.8的虚拟环境。 conda env list // 查看虚拟环境列表 conda activate yolo // 切换虚拟环境 2…

leetcode:1739. 放置盒子【找规律!】

目录题目截图题目分析ac code总结题目截图 题目分析 样例有规律&#xff0c;它希望我们先按每层1, 3, 6这样叠起来&#xff0c;比如能跌i层那么至少有i * ( i 1) // 2个底层多出来的东西再做考虑多出来的东西考虑1 2 3…能加到多少个比如说如果多出来3个的话&#xff0c;放…

【小5聊】Asp.Net Core3.1基础之跨域设置以及设置不对的地方

最近微软的.Net Core平台更新换代速度非常快&#xff0c;还没把2.1整熟悉&#xff0c;就把2.1淘汰了。 目前最新版本已经到了7.0&#xff0c;.net core3.1还在长期维护范围内&#xff0c;估计能用一段时间。 所以&#xff0c;.net core2.1升级到3.1&#xff0c;跨域方法的设置也…

gerber 文件格式 [一]

在电路设计这块, 目前还绕不开 gerber 文件的工程交互, 所以来了解一下. 目前官网的文档gerber-layer-format-specification-revision-2022-02_en.pdf. gerber 文件是一个ascii码的命令文档, 格式比较简单,主要命令有下面这些 命令名称说明G04注释对文档生成没有影响MO模式设…

基于天鹰算法改进的DELM预测-附代码

天鹰算法改进的深度极限学习机DELM的回归预测 文章目录天鹰算法改进的深度极限学习机DELM的回归预测1.ELM原理2.深度极限学习机&#xff08;DELM&#xff09;原理3.天鹰算法4.天鹰算法改进DELM5.实验结果6.参考文献7.Matlab代码1.ELM原理 ELM基础原理请参考&#xff1a;https:…

一文弄懂 React HOC

1. 提出问题 1.HOC 能解决什么问题&#xff1f; 2.HOC 的使用场景&#xff1f; 2. HOC 能解决什么问题&#xff1f; 1.拦截组件渲染&#xff0c;包括是否渲染组件、懒加载组件 2.往组件的 props 中混入所需的东西&#xff0c;比如给非 Route 组件的 props 混入 history 对象…

node.js+uni计算机毕设项目交流微信小程序LW(程序+小程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等…

信号量和共享内存

信号量 信号量(Semaphore)&#xff0c;有时被称为信号灯&#xff0c;是在多线程环境下使用的一种设施&#xff0c;是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前&#xff0c;线程必须获取一个信号量;一旦该关键代码段完成了&#xff0c;那么该线…

Joplin插件推荐-持续更新

背景 之前因为印象笔记、语雀等笔记软件使用起来都不满足自己的需求&#xff0c;所以后面自己调研后使用了Joplin这个开源笔记软件 &#xff0c;项目主页&#xff1a; https://joplinapp.org 。目前搭建在自己的服务器上。最近发现有很多好用的插件。所以记录分享一下。 总插…

# LowCode 低代码建表工具

LowCode 低代码建表工具 需求描述 将数据库的表映射为实体类&#xff0c;服务启动时&#xff0c;扫描表相关的实体类&#xff0c;根据实体类模型在数据库创建相关的表 依赖 主要依赖&#xff1a;使用 Sprintboot、druid、spring-jdbc、mybatis <!-- https://mvnreposit…

为啥这些开源的网络框架这么强

hi&#xff0c; 大家好&#xff0c;我是大师兄&#xff0c;今天分享一下网络编程下半部分内容&#xff0c;主要分享开源网络io框架用到了哪些核心技术&#xff0c;使他们如此流行&#xff0c;这些技术值得我们学习&#xff0c;可以增加我们编程技巧和优化思路。只有掌握更多技能…

【类和对象(上)】

Quitters never win and winners never quit. 目录 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 4.类的访问限定符及封装 4.1 访问限定符 4.2 封装 5.类的作用域 6.类的实例化 7.类对象模型 7.1 如何计算类对象的大小 7.2 结构体内存对齐规则 8.this指针 …

理解 Proxy 和 Reflect

03_02_理解 Proxy 和 Reflect 一、开始之前: 为什么还会有这一篇文章呢&#xff1f;不是手写mini-vue吗&#xff1f;其实可以理解成支线任务、番外篇&#xff0c;是对主线内容的补充。 这一篇文章可能文字比较多&#xff0c;理论知识比较多&#xff0c;参考了4本书相关的章节…

九、Express 基本使用(简)

前一篇内容讲到Express框架的安装以及对Express项目的目录文件有一定的认识了解之后&#xff0c;使用Express创建了最基本的一个Web服务器&#xff0c;接下来进行对Express框架的一些内容来做一个基本的使用&#xff1b; 创建 Web 服务器 node 或 nodemon 执行app.js文件&#…

踩坑了、踩到一个特别无语的常识坑

大家好 踩坑了啊&#xff0c;又踩坑了啊&#xff01; 这次踩到一个特别无语的常识坑。知道真相的那一刻&#xff0c;人就是整个麻掉。 先上个代码&#xff1a; private static double calculate(double a, int b) {return a / b; } 复制代码 你先别问为什么计算不用 BigDec…

RxJS初认识

概念&#xff1a; RxJS的运行就是Observable和Observer之间的互动游戏。 Observable就是“可以被观察的对象”&#xff0c;即“可被观察者”&#xff0c;而Observer就是‘观察者’&#xff0c;连接两者的桥梁就是Observable对象的函数subscribe。 RxJS中的数据流就是Observable…

第二十三章 数论——质数(1)(超级详细的推导)

第二十三章 数论——质数一、什么是质数二、质数的判断1、试除法&#xff08;朴素版&#xff09;2、试除法&#xff08;优化版&#xff09;三、分解质因数1、什么是质因数2、算术基本定理3、分解质因数&#xff08;1&#xff09;问题&#xff08;2&#xff09;思路&#xff08;…

RepNAS: 基于NAS的结构重参数化技术

1. 介绍 在过去几年里&#xff0c;NAS技术取得了长足进展。然而&#xff0c;由于搜索约束与实际推理之间的差异导致高效网络搜索仍极具挑战性。为搜索一个具有高性能、低推理延迟的模型&#xff0c;已有方案往往在算法中添加计算复杂度约束。然而&#xff0c;推理速度会受多种…

【强化学习笔记】马尔可夫过程、马尔可夫奖励过程

文章目录1.马尔可夫过程1.1.随机过程1.2.马尔可夫性质1.3.马尔可夫过程2. 马尔可夫奖励过程2.1.回报2.2.价值函数3.马尔可夫决策过程1.马尔可夫过程 马尔可夫过程&#xff08;Markov process&#xff09; 指具有 马尔可夫性质 的 随机过程 &#xff0c;也被称为马尔可夫链&…