微调神经机器翻译模型全流程

news2025/1/16 20:31:05

MBART: Multilingual Denoising Pre-training for Neural Machine Translation

模型下载

mBART 是一个基于序列到序列的去噪自编码器,使用 BART 目标在多种语言的大规模单语语料库上进行预训练。mBART 是首批通过去噪完整文本在多种语言上预训练序列到序列模型的方法之一,而以往的方法则仅集中在编码器、解码器或重构文本的部分内容。

首先需要在github上下载mbart的预训练模型,我们要完成的任务是微调:README
在这里插入图片描述
下载mbart.CC25模型,下载解压后的目录如下:

├── mbart.cc25.v2
    └── dict.txt
    └── model.pt
    └── sentence.bpe.model

dict是模型的词典文件,model是mbart的预训练模型,sentence.bpe.model是sentencepiece训练分词的模型。
我们在en->vi双语对上对预训练模型进行微调:
在这里插入图片描述
数据为IWSLT15的双语对,下载好数据之后对训练集、验证集和测试集重新命名,整理后的目录如下

├── en_vi 
    └── test.en_XX
    └── test.vi_VN
    └── train.en_XX
    └── train.vi_VN
    └── valid.en_XX
    └── valid.vi_VN

环境准备

这里需要特定的fairseq版本来完成以下的这些命令,因此推荐新创建一个conda环境来隔离版本,这里我们命名为mbart_ft.

fairseq=0.10.2
python=3.8
numpy=1.19.5

数据分词

首先使用sentencepiece模型对数据进行分词,由于原文中描述没有额外的 true-casing、normalizing punctuation / characters.因此我们直接分词即可。

#!/bin/bash

SPM=/path/to/sentencepiece/build/src/spm_encode
MODEL=/mbart/mbart.cc25.v2/sentence.bpe.model
DATA=/mbart/en_vi 
DEST=/mbart/en_vi/spm
TRAIN=train         
VALID=valid        
TEST=test           
SRC=en_XX              
TGT=vi_VN              

${SPM} --model=${MODEL} < ${DATA}/${TRAIN}.${SRC} > ${DEST}/${TRAIN}.spm.${SRC} &
${SPM} --model=${MODEL} < ${DATA}/${TRAIN}.${TGT} > ${DEST}/${TRAIN}.spm.${TGT} &
${SPM} --model=${MODEL} < ${DATA}/${VALID}.${SRC} > ${DEST}/${VALID}.spm.${SRC} &
${SPM} --model=${MODEL} < ${DATA}/${VALID}.${TGT} > ${DEST}/${VALID}.spm.${TGT} &
${SPM} --model=${MODEL} < ${DATA}/${TEST}.${SRC} > ${DEST}/${TEST}.spm.${SRC} &
${SPM} --model=${MODEL} < ${DATA}/${TEST}.${TGT} > ${DEST}/${TEST}.spm.${TGT} &

wait
echo "SentencePiece encoding completed!"

我们创建spm目录,分词后的目录文件为:

├── en_vi
	├── spm 
    	└── test.spm.en_XX
    	└── test.spm.vi_VN
    	└── train.spm.en_XX
    	└── train.spm.vi_VN
    	└── valid.spm.en_XX
    	└── valid.spm.vi_VN

数据预处理

使用fairseq将数据处理为满足训练的、输入模型的格式。包含两种语言的词典文件、二进制格式和分词转换为id的文件。

#!/bin/bash

BASEDIR=/mbart/en_vi
DATA=${BASEDIR}/spm
DEST=${BASEDIR}/ids
DICT=/mbart/mbart.cc25.v2/dict.txt
SRC=en_XX
TGT=en_vi

TRAIN=train
VALID=valid
TEST=test

fairseq-preprocess \
--source-lang ${SRC} \
--target-lang ${TGT} \
--trainpref ${DATA}/${TRAIN}.spm \
--validpref ${DATA}/${VALID}.spm \
--testpref ${DATA}/${TEST}.spm  \
--destdir ${DEST}/  \
--thresholdtgt 0 \
--thresholdsrc 0 \
--srcdict ${DICT} \
--tgtdict ${DICT} \
--workers 70

预处理后的模型数据准备的目录为:

├── en_vi
	├── ids 
    	└── dict.en_XX.txt
    	└── dict.vi_VN.txt
    	└── preprocess.log
    	└── test.en_XX-vi_VN.en_XX.bin
    	└── test.en_XX-vi_VN.en_XX.idx
    	└── test.en_XX-vi_VN.vi_VN.bin
    	└── test.en_XX-vi_VN.vi_VN.idx
    	└── train.en_XX-vi_VN.en_XX.bin
    	└── train.en_XX-vi_VN.en_XX.idx
    	└── train.en_XX-vi_VN.vi_VN.bin
    	└── train.en_XX-vi_VN.vi_VN.idx
    	└── valid.en_XX-vi_VN.en_XX.bin
    	└── valid.en_XX-vi_VN.en_XX.idx
    	└── valid.en_XX-vi_VN.vi_VN.bin
    	└── valid.en_XX-vi_VN.vi_VN.idx

训练集和验证集在训练过程中被用到,而测试集只在评价生成中被用到。

模型的训练

需要注意的是,与官方文档设置的参数相比,有一处需要修改。
--max-update 40000:模型参数更新次数。
----total-num-update 40000 这是设置学习率调度器的更新次数,即学习率更新40k次训练停止。
在mbart的原文中:

We use a maximum of 40K training updates for all low and medium resource pairs and 100K for high resource pairs.

我们的en-vi双语数据属于低资源语言对,因此参数更新次数40K次,即应该设置--max-update 40000

#!/bin/bash
source /path/to/conda/etc/profile.d/conda.sh
conda activate mbart_ft

BASEDIR=/mbart/en_vi
PRETRAIN=/mbart/mbart.cc25.v2/model.pt # 已下载的预训练模型路径
DATA=${BASEDIR}/ids    # 预处理后的二进制数据路径

SRC=en_XX
TGT=vi_VN

langs=ar_AR,cs_CZ,de_DE,en_XX,es_XX,et_EE,fi_FI,fr_XX,gu_IN,hi_IN,it_IT,ja_XX,kk_KZ,ko_KR,lt_LT,lv_LV,my_MM,ne_NP,nl_XX,ro_RO,ru_RU,si_LK,tr_TR,vi_VN,zh_CN

fairseq-train ${DATA} \
  --encoder-normalize-before --decoder-normalize-before \
  --arch mbart_large --layernorm-embedding \
  --task translation_from_pretrained_bart \
  --source-lang ${SRC} --target-lang ${TGT} \
  --criterion label_smoothed_cross_entropy --label-smoothing 0.2 \
  --optimizer adam --adam-eps 1e-06 --adam-betas '(0.9, 0.98)' \
  --lr-scheduler polynomial_decay --lr 3e-05 --warmup-updates 2500 --max-update 40000 \
  --dropout 0.3 --attention-dropout 0.1 --weight-decay 0.0 \
  --max-tokens 1024 --update-freq 2 \
  --save-interval 1 --save-interval-updates 5000 --keep-interval-updates 10 --no-epoch-checkpoints \
  --seed 222 --log-format simple --log-interval 2 \
  --restore-file $PRETRAIN \
  --reset-optimizer --reset-meters --reset-dataloader --reset-lr-scheduler \
  --langs $langs \
  --save-dir ${BASEDIR} \
  --ddp-backend no_c10d

在一块RTX 4090显卡上,运行3个小时后,训练结束。我们设置了每5000次更新保存一次检查点,微调模型保存的文件位置为 --save-dir ${BASEDIR}
微调后的目录文件为:

├── en_vi
	├── ids 
	├── spm
    └── dict.en_XX.txt
    └── checkpoint_2_5000.pt
    └── checkpoint_4_10000.pt
    └── checkpoint_6_15000.pt
    └── checkpoint_8_20000.pt
    └── checkpoint_10_25000.pt
    └── checkpoint_12_30000.pt
    └── checkpoint_14_35000.pt
    └── checkpoint_16_40000.pt
    └── checkpoint_best.pt
    └── checkpoint_last.pt
    └── ...train...test...valid

模型的解码

我们使用checkpoint_best.pt对其进行解码以及测BLEU分数。
这里我将分词模型复制到了en_vi文件夹中,并且添加--cpu使得解码在cpu上运行。解码生成的文件为/mbart/en_vi/ids/en_vi


2025.1.13修订:
需要注意的是,相比于官方文档,这里删除了--bpe "sentencepiece"--sentencepiece-model $model_dir/sentence.bpe.model以及--sacrebleu
若保留--sacrebleu,由于版本间不匹配会报错
若保留--bpe "sentencepiece",则除了模型推理行“H”,其他源句子、目标句子和行“D”均没有空格出现。说明解码过程中并不需要此参数。
--remove-bpe 'sentencepiece':用于去除分词过程中产生的spm标记。

#!/bin/bash
source /path/to/conda/etc/profile.d/conda.sh
conda activate mbart_ft
model_dir=/mbart/en_vi/ids 

langs=ar_AR,cs_CZ,de_DE,en_XX,es_XX,et_EE,fi_FI,fr_XX,gu_IN,hi_IN,it_IT,ja_XX,kk_KZ,ko_KR,lt_LT,lv_LV,my_MM,ne_NP,nl_XX,ro_RO,ru_RU,si_LK,tr_TR,vi_VN,zh_CN
TOKENIZER=${model_dir}/sentence.bpe.model

fairseq-generate ${model_dir} \
  --path $model_dir/../checkpoint_best.pt \
  --task translation_from_pretrained_bart \
  --gen-subset test \
  --cpu \
  -t vi_VN -s en_XX \
  --remove-bpe 'sentencepiece' \
  --batch-size 32 \
  --langs $langs > ${model_dir}/en_vi

查看生成文件en_vi的片段:

S-74	I lost all hope .[en_XX]
T-74	Tôi hoàn toàn tuyệt vọng .
H-74	-0.4808153808116913	Tôi đã mất hết hy vọng .
D-74	-0.4808153808116913	Tôi đã mất hết hy vọng .
P-74	-0.3194 -0.9490 -0.5736 -0.8777 -0.7397 -0.0389 -0.4746 -0.2814 -0.2920 -0.2618
S-372	Today I am 22 .[en_XX]
T-372	Hôm nay tôi 22 tuổi .
H-372	-0.3478223383426666	Hôm nay tôi 22 tuổi .
D-372	-0.3478223383426666	Hôm nay tôi 22 tuổi .
P-372	-0.5605 -0.0631 -0.4549 -0.2989 -0.4617 -0.4079 -0.3166 -0.3061 -0.2606
S-336	Thank you very much .[en_XX]
T-336	Cám ơn rất nhiều .
H-336	-0.46486935019493103	Cám ơn các bạn rất nhiều .
D-336	-0.46486935019493103	Cám ơn các bạn rất nhiều .
P-336	-1.8484 -0.0979 -0.1278 -0.9053 -0.2160 -0.4894 -0.1446 -0.4404 -0.2856 -0.3061 -0.2521
S-1267	Thank you very much .[en_XX]
T-1267	Cảm ơn rất nhiều .
H-1267	-0.46486935019493103	Cám ơn các bạn rất nhiều .
D-1267	-0.46486935019493103	Cám ơn các bạn rất nhiều .
P-1267	-1.8484 -0.0979 -0.1278 -0.9053 -0.2160 -0.4894 -0.1446 -0.4404 -0.2856 -0.3061 -0.2521
S-21	But many die .[en_XX]
T-21	Nhưng rất nhiều người đã chết .
H-21	-0.5680863261222839	Nhưng nhiều người chết .
D-21	-0.5680863261222839	Nhưng nhiều người chết .
P-21	-0.3266 -1.4395 -0.1804 -1.2362 -0.5122 -0.2999 -0.2973 -0.2526

S:是源句子,在en->vi双语对上,源语言是英语。
T:是人工翻译句子,即测试集中的句子;
H:是模型输出的解码句子,第一个数字为其得分;
D:第一个数字为得分和H一致,但相比于H去掉了所有的空格,和S、T格式相同;
P:翻译过程中每个单词的预测概率。
运行解码脚本后,在ids目录中会生成 en_vi 文件。

├── en_vi
	├── ids 
    	└── sentence.bpe.model
    	└── en_vi
    	└── train...test...valid...dict...
	├── spm
	├── train...valid...test...

模型的评价

cat en_vi | grep -P "^H" |sort -V |cut -f 3- | sed 's/\[vi_VN\]//g' > en_vi.hyp
cat en_vi | grep -P "^T" |sort -V |cut -f 2- | sed 's/\[vi_VN\]//g' > en_vi.ref
sacrebleu  en_vi.ref -i en_vi.hyp -m bleu

这里将 H 开头的行提取,并去掉前两个字段,仅保留模型输出的解码句子,将他们合成 en_vi.hyp文件;
将 T 开头的行提取,并去掉第一个字段,保留test文件中的目标句子,将他们合成 en_vi.ref 文件。
这两行代码运行后,目录ids中应该多出两个文件。

├── en_vi
	├── ids 
    	└── en_vi
    	└── en_vi.hyp
    	└── en_vi.ref
    	└── train...test...valid...dict...
	├── spm
	├── train...valid...test...

这两个文件的行数应该一致,使用sacrebleu来测bleu的分数,指定 -tok 分词方式是 “spm” 即sentencepiece。
我们测试的模型评价结果为:

{
 "name": "BLEU",
 "score": 34.7,
 "signature": "nrefs:1|case:mixed|eff:no|tok:13a|smooth:exp|version:2.4.3",
 "verbose_score": "66.2/42.0/27.8/18.7 (BP = 1.000 ratio = 1.007 hyp_len = 33986 ref_len = 33738)",
 "nrefs": "1",
 "case": "mixed",
 "eff": "no",
 "tok": "13a",
 "smooth": "exp",
 "version": "2.4.3"
}

附录

2025.1.13修订:
原版本未删除--bpe "sentencepiece"--sentencepiece-model $model_dir/sentence.bpe.model参数,fairseq推理后生成的en_vi文件为:

S-74    Ilostallhope.[en_XX]
T-74    Tôihoàntoàntuyệtvọng.
H-74    -0.4808153808116913     Tôi đã mất hết hy vọng .
D-74    -0.4808153808116913     Tôiđãmấthếthyvọng.
P-74    -0.3194 -0.9490 -0.5736 -0.8777 -0.7397 -0.0389 -0.4746 -0.2814 -0.2920 -0.2618
S-372   TodayIam22.[en_XX]
T-372   Hômnaytôi22tuổi.
H-372   -0.3478223383426666     Hôm nay tôi 22 tuổi .
D-372   -0.3478223383426666     Hômnaytôi22tuổi.
P-372   -0.5605 -0.0631 -0.4549 -0.2989 -0.4617 -0.4079 -0.3166 -0.3061 -0.2606
S-336   Thankyouverymuch.[en_XX]
T-336   Cámơnrấtnhiều.
H-336   -0.46486935019493103    Cám ơn các bạn rất nhiều .
D-336   -0.46486935019493103    Cámơncácbạnrấtnhiều.
P-336   -1.8484 -0.0979 -0.1278 -0.9053 -0.2160 -0.4894 -0.1446 -0.4404 -0.2856 -0.3061 -0.2521
S-1267  Thankyouverymuch.[en_XX]
T-1267  Cảmơnrấtnhiều.
H-1267  -0.46486935019493103    Cám ơn các bạn rất nhiều .
D-1267  -0.46486935019493103    Cámơncácbạnrấtnhiều.
P-1267  -1.8484 -0.0979 -0.1278 -0.9053 -0.2160 -0.4894 -0.1446 -0.4404 -0.2856 -0.3061 -0.2521
S-21    Butmanydie.[en_XX]
T-21    Nhưngrấtnhiềungườiđãchết.
H-21    -0.5680863261222839     Nhưng nhiều người chết .
D-21    -0.5680863261222839     Nhưngnhiềungườichết.
P-21    -0.3266 -1.4395 -0.1804 -1.2362 -0.5122 -0.2999 -0.2973 -0.2526

可以看到,测试集源句子S以及目标句子T的空格被误删除。由此提取的模型生成文件en_vi.hyp和翻译参考文件en_vi.ref同样误删空格。且模型输出句子H是正常的,这就说明是在解码过程中出现的问题。


2025.1.15修订:
在使用sacrebleu测bleu分数时,-tok 参数指定分词器。
默认为“13a”,即不添加此参数时的默认,我们测出评分为34.7.
指定为"spm" 等同于 “flores101”,使用基于Flores-101和Flores-200数据集构建的SentencePiece模型。

{
 "name": "BLEU",
 "score": 35.4,
 "signature": "nrefs:1|case:mixed|eff:no|tok:flores101|smooth:exp|version:2.4.3",
 "verbose_score": "66.3/42.8/28.8/19.5 (BP = 0.997 ratio = 0.997 hyp_len = 34971 ref_len = 35063)",
 "nrefs": "1",
 "case": "mixed",
 "eff": "no",
 "tok": "flores101",
 "smooth": "exp",
 "version": "2.4.3"
}

指定为“none”,将不应用任何分词,测出评分为:

{
 "name": "BLEU",
 "score": 34.6,
 "signature": "nrefs:1|case:mixed|eff:no|tok:none|smooth:exp|version:2.4.3",
 "verbose_score": "66.2/42.0/27.8/18.6 (BP = 1.000 ratio = 1.008 hyp_len = 33948 ref_len = 33682)",
 "nrefs": "1",
 "case": "mixed",
 "eff": "no",
 "tok": "none",
 "smooth": "exp",
 "version": "2.4.3"
}

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

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

相关文章

基于32QAM的载波同步和定时同步性能仿真,包括Costas环的gardner环

目录 1.算法仿真效果 2.算法涉及理论知识概要 3.MATLAB核心程序 4.完整算法代码文件获得 1.算法仿真效果 matlab2022a仿真结果如下&#xff08;完整代码运行后无水印&#xff09;&#xff1a; 仿真操作步骤可参考程序配套的操作视频。 2.算法涉及理论知识概要 载波同步是…

设计模式-工厂模式/抽象工厂模式

工厂模式 定义 定义一个创建对象的接口&#xff0c;让子类决定实列化哪一个类&#xff0c;工厂模式使一个类的实例化延迟到其子类&#xff1b; 工厂方法模式是简单工厂模式的延伸。在工厂方法模式中&#xff0c;核心工厂类不在负责产品的创建&#xff0c;而是将具体的创建工作…

【机器学习】零售行业的智慧升级:机器学习驱动的精准营销与库存管理

我的个人主页 我的领域&#xff1a;人工智能篇&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;&#x1f44d;点赞 收藏❤ 在当今数字化浪潮汹涌澎湃的时代&#xff0c;零售行业正站在转型升级的十字路口。市场竞争的白热化使得企业必须另辟蹊径&#xff0…

day_2_排序算法和树

文章目录 排序算法和树排序算法算法稳定性排序算法☆ 冒泡排序冒泡思路冒泡步骤代码实现效率优化 ☆ 选择排序排序思路排序步骤代码实现 ... 树01-树的基本概念02-树的相关术语03-二叉树的种类04-二叉树的存储05-树的应用场景_数据库索引06-二叉树的概念和性质07-广度优先遍历0…

蓝桥杯刷题第二天——背包问题

题目描述 有N件物品和一个容量是V的背包。每件物品只能使用一次。第i件物品的体积是Vi价值是Wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式 第一行两个整数&#xff0c;N&#xff0c;V&am…

Linux x86_64 程序动态链接之GOT 和 PLT

文章目录 前言一、动态链接二、位置无关代码三、GOT 和 PLT3.1 GOT3.2 PLT3.3 延时绑定3.4 示例 四、demo演示五、延迟绑定技术和代码修补参考资料 前言 这篇文章描述了&#xff1a;Linux x86_64 程序静态链接之重定位&#xff0c;接来本文描述Linux x86_64 程序动态链接之GOT…

学习记录-责任链模式验证参数

学习记录-责任链模式验证参数 1.什么是责任链模式 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为设计模式&#xff0c;它允许将请求沿着一个处理链传递&#xff0c;直到链中的某个对象处理它。这样&#xff0c;发送者无需知道哪个对象将处理…

练习:MySQL单表查询与多表查询

一.单表查询 创建worke数据库&#xff0c;在数据库底下创建worker表 mysql> create database worke; Query OK, 1 row affected (0.00 sec)mysql> show databases; -------------------- | Database | -------------------- | information_schema | | mysql …

HarmonyOS NEXT应用开发边学边玩系列:从零实现一影视APP (四、最近上映电影滚动展示及加载更多的实现)

在HarmonyOS NEXT开发环境中&#xff0c;可以使用多种组件和库来构建丰富且交互友好的应用。本文将展示如何使用HarmonyOS NEXT框架和nutpi/axios库&#xff0c;从零开始实现一个简单的影视APP的首页&#xff0c;主要关注最近上映电影的滚动展示及加载更多功能的实现。 开源项目…

卷积神经05-GAN对抗神经网络

卷积神经05-GAN对抗神经网络 使用Python3.9CUDA11.8Pytorch实现一个CNN优化版的对抗神经网络 简单的GAN图片生成 CNN优化后的图片生成 优化模型代码对比 0-核心逻辑脉络 1&#xff09;Anacanda使用CUDAPytorch2&#xff09;使用本地MNIST进行手写图片训练3&#xff09;…

客户案例:某家居制造企业跨境电商,解决业务端(亚马逊平台)、易仓ERP与财务端(金蝶ERP)系统间的业务财务数据对账互通

一、系统定义 1、系统定位&#xff1a; 数据中台系统是一种战略选择和组织形式&#xff0c;通过有型的产品支撑和实施方法论&#xff0c;解决企业面临的数据孤岛、数据维护混乱、数据价值利用低的问题&#xff0c;依据企业特有的业务和架构&#xff0c;构建一套从数据汇聚、开…

服务器一次性部署One API + ChatGPT-Next-Web

服务器一次性部署One API ChatGPT-Next-Web One API ChatGPT-Next-Web 介绍One APIChatGPT-Next-Web docker-compose 部署One API ChatGPT-Next-WebOpen API docker-compose 配置ChatGPT-Next-Web docker-compose 配置docker-compose 启动容器 后续配置 同步发布在个人笔记服…

辅助云运维

为客户提供运维支持&#xff0c;保障业务连续性。 文章目录 一、服务范围二、服务内容三、服务流程四、 服务交付件五、责任分工六、 完成标志 一、服务范围 覆盖范围 云产品使用咨询、问题处理、配置指导等&#xff1b; 云产品相关操作的技术指导&#xff1b; 云相关资源日常…

[Qt]常用控件介绍-多元素控件-QListWidget、QTableWidget、QQTreeWidget

目录 1.多元素控件介绍 2.ListWidget控件 属性 核心方法 核心信号 细节 Demo&#xff1a;编辑日程 3.TableWidget控件 核心方法 QTableWidgetItem核心信号 QTableWidgetItem核心方法 细节 Demo&#xff1a;编辑学生信息 4.TreeWidget控件 核心方法 核心信号…

Windows部署NVM并下载多版本Node.js的方法(含删除原有Node的方法)

本文介绍在Windows电脑中&#xff0c;下载、部署NVM&#xff08;node.js version management&#xff09;环境&#xff0c;并基于其安装不同版本的Node.js的方法。 在之前的文章Windows系统下载、部署Node.js与npm环境的方法&#xff08;https://blog.csdn.net/zhebushibiaoshi…

基于STM32设计的粮食仓库(粮仓)环境监测系统

一、前言 1.1 项目开发背景 随着现代农业的发展和粮食储存规模的扩大&#xff0c;粮仓环境的智能化监控需求日益增长。传统的粮仓管理方式通常依赖人工检测和定期巡查&#xff0c;效率低下且容易出现疏漏&#xff0c;无法及时发现潜在问题&#xff0c;可能导致粮食受潮、霉变…

【Linux】--- 进程的等待与替换

进程的等待与替换 一、进程等待1、进程等待的必要性2、获取子进程status3、进程等待的方法&#xff08;1&#xff09;wait&#xff08;&#xff09;函数&#xff08;2&#xff09;waitpid函数 4、多进程创建以及等待的代码模型5、非阻塞接口 轮询 二、进程替换1、替换原理2、替…

Vue2+OpenLayers添加/删除点、点击事件功能实现(提供Gitee源码)

目录 一、案例截图 二、安装OpenLayers库 三、安装Element-UI 四、代码实现 4.1、添加一个点 4.2、删除所有点 4.3、根据经纬度删除点 4.4、给点添加点击事件 4.5、完整代码 五、Gitee源码 一、案例截图 可以新增/删除标记点&#xff0c;点击标记点可以获取到当前标…

HTML中如何保留字符串的空白符和换行符号的效果

有个字符串 储值门店{{thing3.DATA}}\n储值卡号{{character_string1.DATA}}\n储值金额{{amount4.DATA}}\n当前余额{{amount5.DATA}}\n储值时间{{time2.DATA}} &#xff0c; HTML中想要保留 \n的换行效果的有下面3种方法&#xff1a; 1、style 中 设置 white-space: pre-lin…

GB44495-2024 汽车整车信息安全技术要求 - V2X部分前置要求

背景 GB 44495-2024《汽车整车信息安全技术要求》中关于V2X&#xff08;车与外界通信&#xff09;的部分&#xff0c;主要关注于通信安全要求&#xff0c;旨在确保车辆在与外部设备进行数据交互时的信息安全。其测试大致可分为消息层&#xff08;数据无异常&#xff09;、应用…