大模型的分词器——算法及示例

article/2025/6/8 12:28:52

文章目录

    • 1. 分词的概述
      • 1.1 什么是分词?
      • 1.2 分词的重要性
      • 1.3 分词方法的演变
      • 1.4 分词器的选择
    • 2. Byte-Pair Encoding (BPE)
      • 2.1 BPE的概述
      • 2.2 BPE的工作原理
        • 示例:BPE训练
        • 示例:BPE分词
        • 伪代码:BPE训练
      • 2.3 BPE的优缺点
      • 2.4 BPE在模型中的应用
    • 3. WordPiece
      • 3.1 WordPiece的概述
      • 3.2 WordPiece的工作原理
        • 示例:WordPiece训练
        • 示例:WordPiece分词
        • 伪代码:WordPiece训练
      • 3.3 WordPiece的优缺点
      • 3.4 WordPiece在模型中的应用
    • 4. Unigram
      • 4.1 Unigram的概述
      • 4.2 Unigram的工作原理
        • 示例:Unigram训练
        • 示例:Unigram分词
        • 伪代码:Unigram分词
      • 4.3 Unigram的优缺点
      • 4.4 Unigram在模型中的应用
    • 5. SentencePiece
      • 5.1 SentencePiece的概述
      • 5.2 SentencePiece的工作原理
        • 示例:SentencePiece使用
        • 伪代码:SentencePiece训练
      • 5.3 SentencePiece的优缺点
      • 5.4 SentencePiece在模型中的应用
    • 6. Byte-level BPE (BBPE)
      • 6.1 BBPE的概述
      • 6.2 BBPE的工作原理
        • 示例:BBPE分词
        • 伪代码:BBPE训练
      • 6.3 BBPE的优缺点
      • 6.4 BBPE在模型中的应用
    • 7. 分词器比较
    • 8. 实际应用中的考虑

1. 分词的概述

1.1 什么是分词?

分词(Tokenization)是自然语言处理(NLP)中的基础步骤,将连续的文本分割成离散的单元(tokens),如单词、子词或字符。这些tokens是大型语言模型(LLMs)的输入,模型通过学习tokens之间的关系来理解和生成语言。例如,句子“Hello world”可以被分词为["Hello", "world"](词级分词)或["H", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"](字符级分词)。
在这里插入图片描述

1.2 分词的重要性

分词直接影响LLMs的性能和效率,主要体现在以下几个方面:

  • 词汇表大小:词级分词可能导致词汇表过大(例如,英语可能有数十万单词),增加模型的参数量和计算成本。子词分词通过将单词拆分为更小的单元(如“playing”拆为“play”和“##ing”),可以显著减少词汇表大小。
  • 未知词汇(OOV):词级分词无法处理训练数据中未出现的词汇,而子词分词可以通过组合已知子词表示新词。例如,“unseen”可以拆为“un”和“seen”。
  • 序列长度:字符级分词会导致序列过长,增加计算负担。子词分词在词汇表大小和序列长度之间找到平衡。
  • 语言适应性:多语言模型需要处理不同语言的文本,子词分词(如BBPE)可以适应多种语言的字符集。
    在这里插入图片描述

1.3 分词方法的演变

早期的分词方法包括:

  • 词级分词:按空格或标点分割,但词汇表过大,且无法处理OOV词汇。
  • 字符级分词:将每个字符作为一个token,解决了OOV问题,但序列长度过长,计算效率低。

子词分词方法(如BPE、WordPiece、Unigram)通过将单词拆分为更小的有意义单元,解决了上述问题。这些方法在现代LLMs中广泛应用。

1.4 分词器的选择

选择分词器取决于任务需求:

  • 单语言任务:BPE或WordPiece通常更高效。
  • 多语言任务:BBPE或SentencePiece(结合Unigram)更适合。
  • 处理未知词汇或噪声:Unigram的子词正则化可以提高模型鲁棒性。

2. Byte-Pair Encoding (BPE)

2.1 BPE的概述

Byte-Pair Encoding(BPE)最初用于数据压缩,后来被应用于NLP分词 Byte-Pair Encoding。它通过迭代合并最频繁的字符对或子词对来构建词汇表,广泛用于GPT、RoBERTa等模型。

2.2 BPE的工作原理

BPE的训练过程如下:

  1. 初始化词汇表:从训练数据中提取所有唯一字符。例如,对于语料库["hug", "pug", "pun", "bun", "hugs"],初始词汇表为["h", "u", "g", "p", "n", "b", "s"]
  2. 统计字符对频率:遍历语料库,计算连续字符对的频率。例如,在“hug”中,字符对为("h", "u")("u", "g")
  3. 合并最频繁的字符对:选择频率最高的字符对,合并为新token。例如,如果("u", "g")频率最高,创建“ug”。
  4. 更新词汇表:将新token加入词汇表,重新分词语料库,重复步骤2-3,直到达到目标词汇表大小。
示例:BPE训练

语料库:["hug" (10次), "pug" (5次), "pun" (12次), "bun" (4次), "hugs" (5次)]

  • 步骤0:初始化

    • 词汇表:["h", "u", "g", "p", "n", "b", "s"]
    • 语料库分词:
      • hug: ["h", "u", "g"]
      • pug: ["p", "u", "g"]
      • pun: ["p", "u", "n"]
      • bun: ["b", "u", "n"]
      • hugs: ["h", "u", "g", "s"]
  • 步骤1:统计频率

    • 字符对:
      • ("h", "u"):15次(hug x10, hugs x5)
      • ("u", "g"):20次(hug x10, pug x5, hugs x5)
      • ("p", "u"):17次(pug x5, pun x12)
      • ("u", "n"):16次(pun x12, bun x4)
      • ("b", "u"):4次(bun x4)
      • ("g", "s"):5次(hugs x5)
    • 最高频率:("u", "g")(20次)
    • 合并为“ug”,新词汇表:["h", "u", "g", "p", "n", "b", "s", "ug"]
  • 步骤2:重新分词

    • hug: ["h", "ug"]
    • pug: ["p", "ug"]
    • pun: ["p", "u", "n"]
    • bun: ["b", "u", "n"]
    • hugs: ["h", "ug", "s"]
    • 继续统计频率,合并下一个最高频率对,依此类推。
示例:BPE分词

假设最终词汇表为:["h", "u", "g", "p", "n", "b", "s", "ug", "un", "hug"]

  • 分词“hugs”:

    • 从左到右匹配最长子词:
      • “h”匹配
      • “hu”不匹配
      • “hug”匹配
      • “s”匹配
    • 结果:["hug", "s"]
  • 分词“bugs”:

    • “b”匹配
    • “bu”不匹配
    • “bug”不匹配
    • “ugs”不匹配
    • “ug”匹配
    • “s”匹配
    • 结果:["b", "ug", "s"]
伪代码:BPE训练
from collections import defaultdictdef get_pair_frequencies(corpus, vocab):pairs = defaultdict(int)for word, freq in corpus.items():tokens = word.split()  # 假设已分词为字符for i in range(len(tokens) - 1):pairs[(tokens[i], tokens[i + 1])] += freqreturn pairsdef merge_pair(corpus, pair, new_token):new_corpus = {}for word, freq in corpus.items():new_word = word.replace(f"{pair[0]} {pair[1]}", new_token)new_corpus[new_word] = freqreturn new_corpusdef train_bpe(corpus, vocab_size):vocab = set()for word in corpus:for char in word:vocab.add(char)while len(vocab) < vocab_size:pairs = get_pair_frequencies(corpus, vocab)if not pairs:breakbest_pair = max(pairs, key=pairs.get)new_token = best_pair[0] + best_pair[1]corpus = merge_pair(corpus, best_pair, new_token)vocab.add(new_token)return vocab

可视化建议:一个树形图,展示从字符(如“h”, “u”, “g”)到子词(如“ug”, “hug”)的合并过程。节点表示tokens,边表示合并操作,标注频率。

2.3 BPE的优缺点

  • 优点
    • 高效词汇表:用较小的词汇表覆盖大量文本。
    • 处理OOV:通过子词组合表示未知词汇。
    • 语言无关:适用于任何语言。
  • 缺点
    • 合并顺序敏感:不同顺序可能导致不同词汇表。
    • 形态学限制:可能无法有效捕捉某些语言的词根或词缀。

2.4 BPE在模型中的应用

BPE广泛应用于:

  • GPT系列 (OpenAI)
  • RoBERTa (Hugging Face)
  • BART
  • DeBERTa

3. WordPiece

3.1 WordPiece的概述

WordPiece是Google为BERT模型开发的分词算法 WordPiece Tokenization。它与BPE类似,但使用互信息分数选择合并对,倾向于选择更有意义的子词。
在这里插入图片描述

3.2 WordPiece的工作原理

WordPiece的训练过程如下:

  1. 初始化词汇表:包含所有唯一字符,并为非首字符添加“##”前缀(如“hug”拆为["h", "##u", "##g"])。
  2. 计算合并分数:对于每对连续token (A, B),计算:分数高的对表示A和B的关联性强。
  3. 合并最高分对:将分数最高的对合并为新token。
  4. 重复:直到达到目标词汇表大小。
示例:WordPiece训练

语料库:["hug" (10次), "pug" (5次), "pun" (12次), "bun" (4次), "hugs" (5次)]

  • 步骤0:初始化

    • 词汇表:["h", "##u", "##g", "p", "##n", "b", "##s"]
    • 分词:
      • hug: ["h", "##u", "##g"]
      • hugs: ["h", "##u", "##g", "##s"]
  • 步骤1:计算分数

    • 频率:
      • freq(“h”) = 15, freq(“##u”) = 36, freq(“##g”) = 20, freq(“##s”) = 5
      • freq(“h”, “##u”) = 15, freq(“##u”, “##g”) = 20, freq(“##g”, “##s”) = 5
    • 分数:
      • score(“h”, “##u”) = 15 / (15 * 36) ≈ 0.0278
      • score(“##u”, “##g”) = 20 / (36 * 20) ≈ 0.0278
      • score(“##g”, “##s”) = 5 / (20 * 5) = 0.05
    • 合并("##g", "##s")为“##gs”,新词汇表:["h", "##u", "##g", "p", "##n", "b", "##s", "##gs"]
示例:WordPiece分词

假设词汇表为:["h", "##u", "##g", "p", "##n", "b", "##s", "##gs", "hug"]

  • 分词“hugs”:
    • 匹配“hug” → ["hug", "##s"]
  • 分词“bugs”:
    • 匹配“b” → ["b", "##u", "##g", "##s"]
伪代码:WordPiece训练
def get_pair_scores(corpus, vocab):pair_freq = defaultdict(int)token_freq = defaultdict(int)for word, freq in corpus.items():tokens = word.split()for token in tokens:token_freq[token] += freqfor i in range(len(tokens) - 1):pair_freq[(tokens[i], tokens[i + 1])] += freqscores = {}for pair in pair_freq:scores[pair] = pair_freq[pair] / (token_freq[pair[0]] * token_freq[pair[1]])return scoresdef train_wordpiece(corpus, vocab_size):vocab = set()for word in corpus:for char in word:vocab.add(char if word.index(char) == 0 else "##" + char)while len(vocab) < vocab_size:scores = get_pair_scores(corpus, vocab)if not scores:breakbest_pair = max(scores, key=scores.get)new_token = best_pair[0] + best_pair[1].lstrip("##")corpus = merge_pair(corpus, best_pair, new_token)vocab.add(new_token)return vocab

可视化建议:树形图,展示合并过程,节点标注分数(如0.05 for “##g”, “##s”)。

3.3 WordPiece的优缺点

  • 优点
    • 更有意义的子词:互信息分数优先合并关联性强的子词。
    • BERT标准:广泛用于BERT及其变体。
  • 缺点
    • 复杂性:分数计算比BPE复杂。
    • 非完全开源:Google未公开完整训练算法。

3.4 WordPiece在模型中的应用

  • BERT (Google Research)
  • DistilBERT
  • MobileBERT
  • Funnel Transformers
  • MPNET

4. Unigram

4.1 Unigram的概述

Unigram是一种从大词汇表开始,通过剪枝优化到目标大小的分词算法 Unigram Tokenization。它使用Unigram语言模型计算损失,选择删除损失增加最少的子词。

4.2 Unigram的工作原理

  1. 初始化大词汇表:包含所有可能的子词(如“h”, “u”, “g”, “hu”, “ug”, “hug”)。
  2. 计算损失:使用Unigram语言模型(每个token概率为freq(token)/总频率)计算语料库的负对数似然。
  3. 剪枝:删除增加损失最少的子词(通常删除10-20%)。
  4. 重复:直到达到目标词汇表大小。
  5. 分词:使用Viterbi算法选择概率最高的分词方式。
示例:Unigram训练

语料库:["hug" (10次), "pug" (5次), "pun" (12次), "bun" (4次), "hugs" (5次)]

  • 步骤0:初始化

    • 词汇表:["h", "u", "g", "hu", "ug", "p", "pu", "n", "un", "b", "bu", "s", "hug", "gs", "ugs"]
    • 频率:h=15, u=36, g=20, hu=15, ug=20, p=17, pu=17, n=16, un=16, b=4, bu=4, s=5, hug=15, gs=5, ugs=5,总和210。
  • 步骤1:计算概率

    • P(“h”) = 15/210 ≈ 0.0714, P(“ug”) = 20/210 ≈ 0.0952
  • 步骤2:剪枝

    • 计算删除每个子词的损失增加,选择最小者(如“ugs”)。
    • 新词汇表:["h", "u", "g", "hu", "ug", "p", "pu", "n", "un", "b", "bu", "s", "hug", "gs"]
示例:Unigram分词
  • 分词“pug”:
    • 可能分词:["p", "u", "g"](概率:(17/210)(36/210)(20/210)≈0.00132),["p", "ug"]((17/210)(20/210)≈0.00771),["pu", "g"]((17/210)(20/210)≈0.00771)
    • 选择最高概率:["p", "ug"]["pu", "g"]
伪代码:Unigram分词
def viterbi_tokenize(word, vocab, probs):dp = [0.0] * (len(word) + 1)dp[0] = 1.0prev = [None] * (len(word) + 1)for i in range(1, len(word) + 1):for j in range(i):subword = word[j:i]if subword in vocab:prob = probs[subword] * dp[j]if prob > dp[i]:dp[i] = probprev[i] = (j, subword)tokens = []i = len(word)while i > 0:j, subword = prev[i]tokens.append(subword)i = jreturn tokens[::-1]

可视化建议:折线图,展示词汇表大小随剪枝迭代减少的趋势。

4.3 Unigram的优缺点

  • 优点
    • 灵活性:初始包含所有子词,覆盖广泛。
    • 子词正则化:支持多种分词方式,提高模型鲁棒性。
  • 缺点
    • 计算成本高:初始词汇表大,训练复杂。
    • 实现复杂:损失计算和Viterbi算法较复杂。

4.4 Unigram在模型中的应用

  • XLNet
  • ALBERT
  • T5

5. SentencePiece

5.1 SentencePiece的概述

SentencePiece是一个支持多种分词算法的框架 SentencePiece,可以直接从原始文本训练,语言无关,广泛用于多语言任务。

5.2 SentencePiece的工作原理

  • 训练:使用spm_train指定算法(如BPE或Unigram)和词汇表大小。
  • 编码/解码:使用spm_encodespm_decode处理文本。
  • 子词正则化:支持随机采样分词方式,增强模型鲁棒性。
示例:SentencePiece使用
  • 训练

    spm_train --input=corpus.txt --model_prefix=m --vocab_size=8000 --model_type=bpe
    
  • 编码

    echo "Hello world" | spm_encode --model=m.model
    
    • 输出:▁Hello ▁world
  • 解码

    echo "▁Hello ▁world" | spm_decode --model=m.model
    
    • 输出:Hello world
伪代码:SentencePiece训练
import sentencepiece as spmdef train_sentencepiece(corpus_file, model_prefix, vocab_size, model_type):spm.SentencePieceTrainer.Train(f'--input={corpus_file} --model_prefix={model_prefix} 'f'--vocab_size={vocab_size} --model_type={model_type}')def encode_sentencepiece(text, model_file):sp = spm.SentencePieceProcessor()sp.Load(model_file)return sp.EncodeAsPieces(text)

可视化建议:流程图,展示SentencePiece从原始文本到分词的处理过程。

5.3 SentencePiece的优缺点

  • 优点
    • 语言无关:无需预分词,直接处理原始文本。
    • 多算法支持:支持BPE、Unigram等。
    • 高效:C++实现,速度快。
  • 缺点
    • 依赖库:需要安装SentencePiece。

5.4 SentencePiece在模型中的应用

  • 多语言模型(如NLLB)
  • 生产系统

6. Byte-level BPE (BBPE)

6.1 BBPE的概述

Byte-level BPE (BBPE)是BPE的变体,在字节级别运行,初始词汇表包含所有256个字节 Byte-level BPE。它特别适合多语言模型。

6.2 BBPE的工作原理

  • 初始化:词汇表包含所有字节(0-255)。
  • 合并:类似BPE,基于字节对频率合并。
  • 分词:将文本转换为字节序列,然后应用BPE。
示例:BBPE分词
  • 文本“café”(UTF-8:[99, 97, 102, 233]):
    • 可能合并:[99, 97]→“ca”,[102, 233]→“fé”
    • 分词结果:["ca", "fé"]
伪代码:BBPE训练
def text_to_bytes(text):return list(text.encode('utf-8'))def train_bbpe(corpus, vocab_size):vocab = set(range(256))  # 所有字节byte_corpus = {''.join(map(chr, text_to_bytes(word))): freq for word, freq in corpus.items()}return train_bpe(byte_corpus, vocab_size)

可视化建议:表格,比较不同语言(如英语、法语)在BBPE下的token数量。

6.3 BBPE的优缺点

  • 优点
    • 无OOV:所有字节都包含。
    • 多语言支持:适合跨语言任务。
  • 缺点
    • 跨语言效率低:对非训练语言可能需要更多tokens。

6.4 BBPE在模型中的应用

  • 多语言模型(如Facebook AI的翻译模型)

7. 分词器比较

特征BPEWordPieceUnigramSentencePieceBBPE
初始词汇表字符字符所有子词依赖算法字节
合并标准频率互信息分数损失增加依赖算法频率
处理OOV是(无UNK)
语言独立性
应用于GPT, RoBERTaBERTXLNet多模型多语言模型

8. 实际应用中的考虑

  • 选择分词器
    • 单语言:BPE或WordPiece。
    • 多语言:BBPE或SentencePiece(Unigram)。
  • 优化
    • 调整词汇表大小以平衡性能和效率。
    • 使用子词正则化(如Unigram)提高鲁棒性。
  • 常见问题
    • 确保分词器与模型兼容。
    • 注意跨语言性能差异。

在这里插入图片描述


http://www.hkcw.cn/article/IbOPNBPwSX.shtml

相关文章

用户管理页面(解决toggleRowSelection在dialog用不了的隐患,包含el-table的plus版本的组件)

新增/编辑/删除/分配角色&#xff0c;图片上传在此文章分类下另一个文章 1.重点分配角色&#xff1a; <template><!-- 客户资料 --><div class"pageBox"><elPlusTable :tableData"tableData" :tablePage"tablePage" onSi…

构建基于深度学习的人体姿态估计系统 数据预处理到模型训练、评估和部署 _如何利用人体姿态识别估计数据集_数据进行人体姿态估计研究的建议Human3.6M

构建基于深度学习的人体姿态估计系统 数据预处理到模型训练、评估和部署 如何利用人体姿态识别估计数据集_数据进行人体姿态估计研究的建议__ _人体姿态估计数据集:human3.6m w文章内容及代码仅供参考 By. subject: SubjectS1 : Videos Segments Features Depth Scanner Poses…

PyTorch——非线性激活(5)

非线性激活函数的作用是让神经网络能够理解更复杂的模式和规律。如果没有非线性激活函数&#xff0c;神经网络就只能进行简单的加法和乘法运算&#xff0c;没法处理复杂的问题。 非线性变化的目的就是给我们的网络当中引入一些非线性特征 Relu 激活函数 Relu处理图像 # 导入必…

极智项目 | 基于PyQT+Whisper实现的语音识别软件设计

这是一个基于OpenAI的Whisper模型的语音识别应用程序&#xff0c;使用PyQt5构建了简洁直观的用户界面。该应用支持多语言识别&#xff0c;特别优化了中文识别体验。 项目下载&#xff1a;链接 功能特点 简洁现代的深色主题界面支持多语言识别&#xff08;中文、英语、日语等…

【大模型:知识图谱】--1.py2neo连接图数据库neo4j

【图数据库】--Neo4j 安装_neo4j安装-CSDN博客 需要打开图数据库Neo4j&#xff0c; neo4j console 目录 1.图数据库--连接 2.图数据库--操作 2.1.创建节点 2.2.删除节点 2.3.增改属性 2.4.建立关系 2.5.查询节点 2.6.查询关系 3.图数据库--实例 1.图数据库--连接 fr…

关于线缆行业设备数据采集异构问题的解决

通信线缆制造设备 异构设备协议情况 设备具体型号和关键参数数据传输协议拉丝机LW-1-6/560 塑料扁丝拉丝机&#xff08;螺杆120mm&#xff09;进料直径6.5mm→出料2mm 线速245m/min&#xff0c;功率30kWModbus RTU&#xff08;RS485总线&#xff09;对绞机QC-500C 绞弓转速0-…

电力设备故障预测网关技术方案——基于EFISH-SCB-RK3588的国产化替代实践

一、国产化替代战略背景 行业痛点分析 传统x86方案&#xff08;赛扬N100/N150&#xff09;存在单线程性能瓶颈&#xff08;SPECint2006仅15.2分&#xff09;进口芯片供应链风险&#xff08;Intel产品生命周期通常仅3-5年&#xff09;工业现场总线支持不足&#xff08;需外扩CA…

基于SpringBoot的“嗨玩旅游”网站设计与实现(源码+定制+开发)嗨玩旅游平台开发:景点展示与个性化推荐系统(SpringBoot)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

网络安全问题及对策研究

摘 要 网络安全问题一直是近年来社会乃至全世界十分关注的重要性问题&#xff0c;网络关乎着我们的生活&#xff0c;政治&#xff0c;经济等多个方面&#xff0c;致力解决网络安全问题以及给出行之有效的安全策略是网络安全领域的一大目标。 本论文简述了课题的开发背景&…

Modbus转Ethernet IP网关助力罗克韦尔PLC数据交互

在工业自动化领域&#xff0c;Modbus协议是一种广泛应用的串行通信协议&#xff0c;它定义了主站和从站之间的通信规则和数据格式。罗克韦尔PLC是一种可编程的逻辑控制器&#xff0c;通过Modbus协议实现与其他设备之间的数据交互。然而&#xff0c;随着以太网技术的普及和发展&…

SpringBoot 数据库导入导出 Xlsx文件的导入与导出 全量导出 数据库导出表格 数据处理 外部数据

介绍 poi-ooxml 是 Apache POI 项目中的一个库&#xff0c;专门用于处理 Microsoft Office 2007 及以后版本的文件&#xff0c;特别是 Excel 文件&#xff08;.xlsx 格式&#xff09;和 Word 文件&#xff08;.docx 格式&#xff09;。 在管理系统中需要对数据库的数据进行导…

EagleTrader采访|在市场中修行的交易之道与实战反思

在交易世界的洪流中&#xff0c;真正让人敬佩的不是一时的高收益&#xff0c;而是对规则的敬畏与长期自我修正的能力。来自EagleTrader的交易员罗秋林&#xff0c;正是这样一位在实战中历练出的“老兵”。 七八年时间&#xff0c;他从爆仓阴影走出&#xff0c;如今选择通过Eag…

OpenCV CUDA模块霍夫变换------在 GPU 上执行概率霍夫变换检测图像中的线段端点类cv::cuda::HoughSegmentDetector

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cuda::HoughSegmentDetector 是 OpenCV 的 CUDA 模块中一个非常重要的类&#xff0c;它用于在 GPU 上执行 概率霍夫变换&#xff08;Probabi…

MybatisPlus--核心功能--service接口

Service接口 基本用法 MyBatisPlus同时也提供了service接口&#xff0c;继承后一些基础的增删改查的service代码&#xff0c;也不需要去书写。 接口名为Iservice&#xff0c;而Iservice也继承了IRepository&#xff0c;这里提供的方法跟BaseMapper相比只多不少&#xff0c;整…

Silky-CTF: 0x02靶场

Silky-CTF: 0x02 来自 <Silky-CTF: 0x02 ~ VulnHub> 1&#xff0c;将两台虚拟机网络连接都改为NAT模式 2&#xff0c;攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.128&#xff0c;靶场IP192.168.23.131 3&#xff0c;对靶机进…

图片组件|纯血鸿蒙组件库AUI

摘要&#xff1a; 图片组件(A_Image)&#xff1a;可设置图片地址、图片宽度、图片高度、圆角类型及是否显示外框线。圆角类型支持普通圆角、圆形及无圆角。 一、组件调用方式 1.极简调用 只需要输入A_Image&#xff0c;然后给src&#xff08;图片地址&#xff09;属性赋值即可…

tGSSA-LSTM多输入回归|改进麻雀优化-长短期记忆神经网络|Matlab回归通用

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、方法原理介绍&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译…

【吾爱】逆向实战crackme160破解记录(二)

前言 最近在拿吾爱上的crackme程序练练手&#xff0c;发现论坛上已经有pk8900总结好的160个crackme&#xff0c;非常方便&#xff0c;而且有很多厉害的前辈已经写好经验贴和方法了&#xff0c;我这里只是做一下自己练习的记录&#xff0c;欢迎讨论学习&#xff0c;感谢吾爱论坛…

C# Onnx 动漫人物人脸检测

目录 效果 模型信息 项目 代码 下载 参考 效果 模型信息 Model Properties ------------------------- stride&#xff1a;32 names&#xff1a;{0: face} --------------------------------------------------------------- Inputs ------------------------- name&am…

使用cmd命令行创建数据库和表-简单步骤记录

前提&#xff1a; 已安装MySQL 步骤&#xff1a; 1.WinR&#xff0c;回车&#xff0c;输入cmd&#xff0c;回车 2.输入 mysql -u root -p 后&#xff0c;输入自己的密码&#xff0c;看到welcome等字样就是成功登录了MySQL 3.创建数据库 create database success; &#xff0…