大模型参数高效微调技术原理综述(四)-Prompt Tuning

news2024/9/23 2:24:26

紧接着Stanford的Prefix Tuning论文,Google迅速发表了Prompt Tuning技术论文。Google声称该技术比Prefix Tuning更易上手且成本更低,因此该技术随后也成为了微调技术中的一个重要分支。

本文解读论文**《The Power of Scale for Parameter-Efficient Prompt Tuning》**,与大家共同感受Prompt Tuning技术的奇妙之处。

image-20240403122759085

Prompt的分类

这个分类非常重要,大量的论文都会提到软提示,希望认真阅读!

硬提示/离散提示(Hard Prompt/Discrete Prompt)

硬提示就是指人为设计上面提到的Prompt。硬提示一般需要模型在这个域上有比较多的经验,并且使用前需要知道这个模型的底层是什么样的。否则,硬提示的性能一般会比Fine-tuning的SOTA差很多。

根据2021年的两份研究,硬提示有两个性质:

  • 人类认为不错的硬提示对于LM来说不一定是一个好的硬提示,这个性质被称为硬提示的sub-optimal(次优)性。
  • 硬提示的选择对于预训练模型的影响非常大。

这两个性质可以在如下例子中显现得淋漓尽致:

发现问题了吗?其实最上面在我们看来是最简单的完形填空(也就意味着我们认为最上面的性能最强),但是实际上计算机认为最下面才是最好的完形填空,而且几乎差了一倍的性能!

软提示/连续提示(Soft Prompt/Continuous Prompt)

就是因为硬提示存在这样的问题,2020年,科学家提出了软提示。软提示与硬提示恰好相反,把Prompt的生成本身作为一个任务进行学习,相当于把Prompt的生成从人类一个一个尝试(离散)变换成机器自己进行学习、尝试(连续)。

由于需要机器自己学习,软提示不可避免地往模型内引入了新的参数。这里就又出来一个问题:如何参数有效地学习软提示?目前的研究热点有:

  • P-tuning:将prompt变成token,用BiLSTM进行学习。
  • P-tuning:使用混合的prompt初始化策略(如CLInit和SelectInit)。
  • Prefix-tuning:对于不同模型,将prompt注入输入的不同位置。原理图如下:

  • Soft Prompts:使用组合法,例如mixture-of-experts。

Prompt Tuning(论文:The Power of Scale for Parameter-Efficient Prompt Tuning),该方法可以看作是 Prefix Tuning 的简化版本,它给每个任务定义了自己的Prompt,然后拼接到数据上作为输入,但只在输入层加入prompt tokens,并且不需要加入 MLP 进行调整来解决难训练的问题。

从Prompt到Prompt Tuning:让机器学习写Prompt

了解了软提示后,Prompt Tuning就非常好理解了。

所谓Prompt Tuning,就是在Prompt中插入一段task-specific的可以tune的prompt token。

由于这个token对于每个任务都是不同的,所以可以帮助机器识别任务到底是什么。又因为机器自己学习(tune)这个prompt token,所以这个token对于机器会有非常好的效果。

1.Abstract(摘要)

首先我们看一下论文摘要,快速理解论文的核心内容

  • 问题Prompt TuningPrefix Tuning一样,都是以任务为中心的思路解决问题。

    • 以任务为中心:它们都在试图解决FFT针对不同的下游任务都需产生一个新的微调后大模型而导致的成本效率问题。
  • 解决方案:论文提出的Prompt Tuning,也是一种使用Soft Prompt(软提示)进行迁移学习的方法。统一不同下游任务的训练数据格式,并将这些不同下游任务的训练数据汇总成一个乱序的数据集,微调预训练模型,最终获得一个能处理不同下游任务的大模型。

  • 实验效果

    • 在小参数规模的T5上,Prompt Tuning略差于FFT性能。
    • 在中参数规模的T5上,Prompt Tuning快速接近于FFT性能。
    • 在大参数规模的T5上,Prompt Tuning与FFT性能持平。
    • 因此,Prompt Tuning在大参数规模的模型上,更具成本效率优势。

image-20240403092613314

2.Introduction(介绍)

  • 背景技术1:论文中提到的Prompt Design可以理解为大家耳熟能详的提示词及提示词工程

    • 经过工程实践,大家都知道提示词工程有一定的效果,但效果远不及FFT。为什么呢?论文中总结了提示词工程的两个短板:the discrete space of words(离散空间的单词)requires human involvement(人类的投入)
    • the discrete space of words(离散空间的单词):提示词工程中的提示词是数学意义上的离散,大语言模型不能很好地学习其隐含的特征。隐含特征不是提示词内容本身的显式特征,而是诸如提示词的句式、问法、潜台词等隐式特征。业界针对提取离散空间词汇也提出了一些算法(如:a search algorithm over the discrete space of words),但效果也非常限。
    • requires human involvement(人类的投入):提示词工程依赖有经验的提示词工程师,针对不同下游任务设计提示词,工作量巨大,并且对大模型推理能力的提升又极其有限。
  • 背景技术2:论文中提到的Model TuningModel Tuning(Multi Task),可以理解为FFT

    • Model Tuing(Multi Task)Model Tuning(Multi Task)是针对每个下游任务都微调出一个大模型,而Model Tuning是将N个下游任务都微调到一个大模型中。
  • Prompt Tuning的核心思想

    • 统一下游任务的数据格式:论文中提到an additional k tunable tokens per downstream task to be prepended to the input text,就是为了达成统一下游任务的数据格式。如:['[CLS]’, ‘中’, ‘国’, ‘的’, ‘春’, ‘节’, ‘是’, ‘[MASK]’, ‘[MASK]’, ‘。’, ‘[SEP]']。
    • 合并下游任务的数据集合:当我们统一了下游任务的数据格式,就可以将这些下游任务数据集合混合在一起。
    • LLM具备学习数据集合隐式特征的能力:论文假设LLM是具备学习上述数据格式隐式特征的能力,并通过实验验证了这个假设。
    • Prompt Tuning的本质:该技术的本质是LLM的核心能力之一就是提特征。如果特征很明显,LLM就可以低成本提取。如果特征很隐晦,LLM无法低成本提取、甚至无法提取,Prompt Tuning就是改变数据集,将隐式特征转为显式特征。

image-20240403101321581

  • 实验效果
    • 在小规模T5模型上,提示词工程效果最差、FFT效果最好、Promp Tuning效果中等。
    • 在大规模T5模型上,Promp Tuing效果与FFT持平。
    • 因此,在大规模模型上,Promp Tuning具备巨大的成本优势。

image-20240403101305842

3.Design Decisions(实验设计)

(1)下游任务数据格式归一化的理论基础

论文的实验对象是T5,因为T5有一个有趣的观点:

  • Following the “text-to-text” approach of T5 (Raffelet al., 2020), we cast all tasks as text generation:所有的下游任务都可以等效于文本生成。这个观点就可以支撑Prompt Tuning将所有下游任务的训练数据格式统一起来。
  • 如:翻译下游任务,可以将训练数据构造为:“translate English to German: hello world!”
  • 如:摘要下游任务,可以将训练数据构造为:“summarize: xxxxxxxxxxxxxxxxxxx”

image-20240403112458776

(2)问题建模

论文对问题进行了数学建模:

  • Prθ(Y|X):在不同下游任务的训练数据可归一化的前提下,大语言模型可被建模为Prθ(Y|X),X是用户输入的Tokens,Y是在X发生的概率下模型的输出。
  • Prompt Design的短板:提示词工程需要人类不断尝试寻找出合适提示词,这种不断尝试方法可能是人工寻找的,也可能采用了非可微的搜索方法(如:前文提到的a search algorithm over the discrete space of words)。
  • Prθ;θP (Y|[P; X]):这个公式表达了Prompt Tuning的核心思想——在训练数据中植入特殊Token,大模型除了学习训练数据中的显式特征外,还能学习Prompt形式训练数据的隐式特征。对于Prompt隐式特征的学习最终影响的不是预训练模型的参数θ,而是在修正θP。
  • [Pe; Xe] ∈ R(p+n)×e:Prompt中的普通标记被大模型嵌入后得到Xe(e是向量空间的维度),Prompt中的特殊标记被大模型嵌入后得到Pe(e是向量空间的维度)。[Pe; Xe]则表示输入给大模型后续神经网络层的高维向量。训练的影响并不会修正Xe关联的模型参数,只会修正Pe关联的模型参数。

image-20240403115838249

image-20240403115900991

因此,实验的关注点如下:

  • Pe的初始值:和Prefix Tuning一样,都需要关注软提示的初始值,以提升训练速度和效果。
  • Pe的长度:和Prefix Tuning一样,也需要关注软提示的长度,以降低训练成本。
    • Prompt Tuning的参数成本=E*P:E是普通标记的向量维数,P是特殊标记的长度。

(3)如何消减特殊标记的影响

由于增加了特殊标记,大模型学习的内容就不再是原汁原味的"人类自然语言"了。这样就可能导致大模型无法用自然语言作答——这就好像你在训练大模型鸟语但又期待它能说人话、你在用中文教英语最后学会的是Chinglish。

论文中提出了**Span Corruption(跨度损失)**的概念:

  • Span Corruption(跨度损失):比如,训练数据Thank you [X] me to your party [Y] week, 、[Y]就是特殊标记,将这种特殊标记植入自然语言的目的是"问题模式等隐式特征的显性化”,但弊端就是让大语言模型学会了非人类的自然语言。
  • 论文提出了三种解决方法
    • Span Corruption法:啥都不做,任由大语言模型输出特殊标记,忽略这种影响。
    • Span Corruption+Sentinel法:在大语言模型中增加Sentinel,一定程度地降低这种影响。
    • LM Adaptation法:采用Raffel提出的一个小模型,纠正大语言模型输出特殊标记的倾向,最终输出纯粹的自然语言。

image-20240403115956245

4.Experiments(实验结果)

4.1.实验结果

论文阐述了详细的实验过程、实验数据,最终的实验结果如前文所述:

  • 在小规模T5模型上,提示词工程效果最差、FFT效果最好、Promp Tuning效果中等。
  • 在大规模T5模型上,Promp Tuing效果与FFT持平。

image-20240403120117025

  • 当模型规模逐渐变大,Promp Tuning涉及的参数相较于Prefix Tuning更少,但微调效果持平,因此Prompt Tuning具备巨大的成本优势

image-20240403120213717

4.2.重要发现

论文在前述实验结果下,有如下重要发现:

论文从可解释性方面发现了语义聚合现象,进一步证明了Prompt形式的数据更有利于大语言模型学习其隐式特征:

  • 语义聚合现象:观测被大语言模型嵌入后的特殊标记和普通标记,可以发现出现了物以类聚的现象:
    • 如:Technology / technology / Technologies / technological / technologies相关的训练数据,向量相似度发生了语义聚合。
    • 语义聚合的出现,说明了大语言模型学习到了Prompt形式的训练数据中的隐式特征,因此可以举一反三地处理为见过的下游任务相关输入。

论文还证明了Prompt Ensembling(提示集成能力)

  • 基于Prompt Tuning的技术思想,可以做到数据格式统一、不同下游任务的训练数据混合训练,进而达到”一个大模型支持多种不同下游任务"。
  • 这种思想可以在超大规模的模型上极大地降低训练成本、使用成本。

image-20240403101321581

在工程实践方面,论文也给出了Prompt长度、Prompt初始值的相关推荐:

  • Prompt长度的影响

    • 在中小参数规模的模型上,Prompt长度越长,提示效果越好,但过犹不及(实验长度的临界值是150)——超过了一定的阈值,就会出现推理性能下降。
    • 在大参数规模的模型上,Prompt长度反而没有什么影响了。
  • Prompt的初始值选择的影响:随机初始化Prompt的效果远差于用下游任务相关联提示词做初始值的效果。

image-20240403121146629

最后,论文还通过消融实验,补充了消减Span Corruption的建议:

  • LM Adaptation:在中小规模模型上,采用LM Adaptation,对大语言模型的纠正效果更好。LM Adaptation增加步数会达到更好的纠正效果。
  • 在大规模模型上,Span Corruption的影响也可以忽略不计了。

image-20240403121223051

4.3 示例代码

第一步,引进必要的库,如:Prompt Tuning 配置类 PromptTuningConfig

from peft import get_peft_config, get_peft_model, PromptTuningInit, PromptTuningConfig, TaskType, PeftType

第二步,创建 Prompt Tuning 微调方法对应的配置。

peft_config = PromptTuningConfig(
    task_type=TaskType.CAUSAL_LM,
    prompt_tuning_init=PromptTuningInit.TEXT,
    num_virtual_tokens=8,
    prompt_tuning_init_text="Classify if the tweet is a complaint or not:",
    tokenizer_name_or_path=model_name_or_path,
)

参数说明:

  • prompt_tuning_init:提示嵌入的初始化方法。PEFT支持文本(TEXT)和随机(RANDOM)初始化。在原理篇中提到过 Prompt token 的初始化方法和长度对于模型性能有影响。与随机初始化和使用样本词汇表初始化相比,Prompt Tuning 采用类标签初始化模型的效果更好。不过随着模型参数规模的提升,这种gap最终会消失。因此,如果需要使用类标签和样本词汇表初始化需指定为TEXT。
  • prompt_tuning_init_text:用于初始化提示嵌入的文本,在使用文本(TEXT)初始化方法时使用。
  • task_type:指定任务类型。如:条件生成任务(SEQ_2_SEQ_LM),因果语言建模(CAUSAL_LM)等。
  • num_virtual_tokens:指定虚拟Token数。在原理篇中,提到过提示虚拟 Token 的长度在20左右时的表现已经不错(超过20之后,提升Prompt token长度,对模型的性能提升不明显了);同样的,这个gap也会随着模型参数规模的提升而减小(即对于超大规模模型而言,即使提示虚拟 Token 长度很短,对性能也不会有太大的影响)。

第三步,通过调用 get_peft_model 方法包装基础的 Transformer 模型。

model = AutoModelForCausalLM.from_pretrained(model_name_or_path)
model = get_peft_model(model, peft_config)
model.print_trainable_parameters()

通过 print_trainable_parameters 方法可以查看可训练参数的数量(仅为8,192)以及占比(仅为0.00146%)。

trainable params: 8,192 || all params: 559,222,784 || trainable%: 0.0014648902430985358

Prompt Tuning 模型类结构如下所示:

PeftModelForCausalLM(
  (base_model): BloomForCausalLM(
    (transformer): BloomModel(
      (word_embeddings): Embedding(250880, 1024)
      (word_embeddings_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)
      (h): ModuleList(
        ...
      )
      (ln_f): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)
    )
    (lm_head): Linear(in_features=1024, out_features=250880, bias=False)
  )
  (prompt_encoder): ModuleDict(
    (default): PromptEmbedding(
      (embedding): Embedding(8, 1024)
    )
  )
  (word_embeddings): Embedding(250880, 1024)
)

从模型类结构可以看到,Prompt Tuning 只在输入层加入 prompt virtual tokens,其他地方均没有变化,具体可查看 PromptEmbedding 的源码。

class PromptEmbedding(torch.nn.Module):
    def __init__(self, config, word_embeddings):
        super().__init__()

        total_virtual_tokens = config.num_virtual_tokens * config.num_transformer_submodules
        # 初始化 embedding 层
        self.embedding = torch.nn.Embedding(total_virtual_tokens, config.token_dim)
        
        # 如果使用文本进行初始化,执行如下逻辑,PromptTuningConfig 配置类需要传入初始化文本。
        if config.prompt_tuning_init == PromptTuningInit.TEXT:
            from transformers import AutoTokenizer

            tokenizer = AutoTokenizer.from_pretrained(config.tokenizer_name_or_path)
            init_text = config.prompt_tuning_init_text
            init_token_ids = tokenizer(init_text)["input_ids"]
            # Trim or iterate until num_text_tokens matches total_virtual_tokens
            num_text_tokens = len(init_token_ids)
            if num_text_tokens > total_virtual_tokens:
                init_token_ids = init_token_ids[:total_virtual_tokens]
            elif num_text_tokens < total_virtual_tokens:
                num_reps = math.ceil(total_virtual_tokens / num_text_tokens)
                init_token_ids = init_token_ids * num_reps
            init_token_ids = init_token_ids[:total_virtual_tokens]

            word_embedding_weights = word_embeddings(torch.LongTensor(init_token_ids)).detach().clone()
            word_embedding_weights = word_embedding_weights.to(torch.float32)
            # 初始化embedding层的权重
            self.embedding.weight = torch.nn.Parameter(word_embedding_weights)

    def forward(self, indices):
        # Just get embeddings
        prompt_embeddings = self.embedding(indices)
        return prompt_embeddings

第四步,模型训练的其余部分均无需更改,当模型训练完成之后,保存高效微调部分的模型权重以供模型推理即可。

peft_model_id = f"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}"
model.save_pretrained(peft_model_id)

输出的模型权重文件如下所示:

/data/nfs/llm/model/bloomz-560m_PROMPT_TUNING_CAUSAL_LM
├── [ 500]  adapter_config.json
├── [ 33K]  adapter_model.bin
└── [ 111]  README.md

0 directories, 3 files

注意:这里只会保存经过训练的增量 PEFT 权重。其中,adapter_config.json 为 Prompt Tuning 配置文件;adapter_model.bin 为 Prompt Tuning 权重文件。

第五步,加载微调后的权重文件进行推理。

from peft import PeftModel, PeftConfig

peft_model_id = f"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}"

# 加载PEFT配置
config = PeftConfig.from_pretrained(peft_model_id)

# 加载基础模型
model = AutoModelForCausalLM.from_pretrained(config.base_model_name_or_path)
# 加载PEFT模型
model = PeftModel.from_pretrained(model, peft_model_id)

# Tokenizer编码
inputs = tokenizer(f'{text_column} : {dataset["test"][i]["Tweet text"]} Label : ', return_tensors="pt")

# 模型推理
outputs = model.generate(
        input_ids=inputs["input_ids"], 
        attention_mask=inputs["attention_mask"], 
        max_new_tokens=10, 
        eos_token_id=3
    )

# Tokenizer 解码
print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True))

至此,我们完成了Prompt Tuning的训练及推理。

5.总结

从上述论文解读中,我们收获了如下技术观点:

  • Prompt Tuning的价值:追求一套预训练模型,搞定多个下游任务。
  • Prompt Tuning的核心思想:通过归一化不同下游任务的训练数据,并将隐式特征显性化,帮助大语言模型学习。
  • Prefix Tuning的工程实践经验
    • Prompt形式的训练数据有助于LLM学习隐式特征。
    • 采用Prompt Tuning可用一套模型搞定多个下游任务。
    • 对于大规模参数的模型,Prompt长度和初始化影响很小。
    • 对于中小规模参数的模型,Prompt长度和初始值可参考Prefix Tuning的实践。

论文链接:https://arxiv.org/pdf/2104.08691.pdf

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

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

相关文章

Java类加载器双亲委托模型概述

类加载器的双亲委派模型 模型图 加载原理 双亲委派模型的工作过程是&#xff1a;如果一个类加载器收到了类加载的请求&#xff0c;它首先不会自己去尝试加载这个类&#xff0c;而是把这个请求委派给父类加载器去完成&#xff0c;每一个层次的类加载器都是如此&#xff0c;因此所…

C/C++逆向:寻找mian函数(其他编译配置特征)

在上篇文章中写了在逆向中定位main函数几种方法&#xff0c;其中有一种方法是通过编译器特征定位 main 函数&#xff08;使用IDA分析简单demo程序获取特征&#xff0c;根据得到的特征可以定位相同编译器编译程序的main函数&#xff09;。在上一篇文章中我们提取了VS环境(VS2017…

【软件测试专栏】软件测试 — 概念篇

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;软件测试专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 软件测试 — 概念篇 关键词&#xff1a;软件需求、用户需求、开发…

从混乱到秩序:产品经理在需求变更中的关键角色

在软件开发过程中&#xff0c;需求是驱动整个项目的核心。需求的来源多种多样&#xff0c;包括客户、市场、领导等&#xff0c;产品经理的职责是将这些需求收集、整理并转化为可行的开发计划。本文将探讨需求的来源、产品经理的角色、软件开发中的挑战以及应对变化的策略。 需求…

Java小白一文讲清Java中集合相关的知识点(一)

集合 诞生缘由 数组 长度开始时必须指定&#xff0c;而且一旦指定&#xff0c;不能更改保存的必须为同一类型元素使用数组进行增/删元素所需要编写的代码–比较麻烦 Person[] pers new Person[1]; pers[0] new Person(); //此时增加新的Person对象呢&#xff1f; Person[…

【学习笔记】卫星通信NTN 3GPP标准化进展分析(一)-基本信息

一、引言&#xff1a; 本文来自3GPP Joern Krause, 3GPP MCC (May 14,2024) Non-Terrestrial Networks (NTN) (3gpp.org) 本文总结了NTN标准化进程以及后续的研究计划&#xff0c;是学习NTN协议的入门。 【学习笔记】卫星通信NTN 3GPP标准化进展分析&#xff08;一&#xf…

前端开发第二节课

HTML常用的标签 文本格式化标签 在网页中&#xff0c;有时需要为文字设置粗体、斜体或下划线等效果&#xff0c;这时就需要用到HTML中的文本格式化标签使文字以特殊的方式显示。 标签语义&#xff1a;突出重要性&#xff0c;比普通文字更重要。 加粗 <strong></st…

Spring框架;Spring中IOC简介及搭建;Spring中AOP简介;

一&#xff0c;Spring介绍 Spring 的全称&#xff1a; Spring Framework Spring是一个优秀的开源的轻量级的企业应用开发框架&#xff0c;是为了解决企业应用程序开发复杂性而创建的。它大大简化了java企业级开发的复杂性&#xff0c;提供了强大&#xff0c;稳定的功能&#xf…

XR-Frame 实现 始终朝向屏幕(相机)的面片与模型

wxml&#xff0c;xr-frame中plane平面默认是趴在场景中的&#xff0c;需要先绕x轴渲染90度&#xff0c; // 面片 <xr-node id"l" position"-3.0 0 0.0"><xr-mesh rotation"90 0 0" geometry"plane" uniforms"u_base…

浅析synchronized锁升级的原理与实现 2

本文内容是继我的上篇博客 浅析synchronized锁升级的原理与实现 1-CSDN博客 目录 各状态锁的升级场景 无锁 --> 轻量级锁 偏向锁 --> 轻量级锁 偏向锁 --> 重量级锁 轻量级锁 --> 重量级锁 总结 各状态锁的升级场景 下面我们结合代码看下各状态锁的升级场景。…

VL53L1CB TOF开发(2)----多区域扫描模式

VL53L1CB TOF开发.2--多区域扫描模式 概述视频教学样品申请源码下载硬件准备主要特点生成STM32CUBEMX串口配置IIC配置XSHUTGPIO1X-CUBE-TOF1堆栈设置函数说明初始化设置预设模式 (Preset mode)VL53L1_SetPresetModeVL53L1_SetDistanceMode时间预算单个ROI&#xff08;Single R…

从 Oracle 到 TiDB 丨数据库资源评估指南

原文来源&#xff1a; https://tidb.net/blog/5058e24f 本文作者&#xff1a;柳冬冬 导读 在当今技术飞速发展的时代&#xff0c;传统单机数据库正面临着前所未有的挑战。随着人工智能、云计算和大数据的崛起&#xff0c;企业对数据库的性能、可靠性和扩展性的需求日益增…

wordcloud兼figma的词云图片python生成

文章目录 一.Figma1.简介2.特点 二.代码构成1.详细代码2.word.py代码详解3.成果图 一.Figma 1.简介 Figma是一款全平台可使用的使用软件&#xff0c;和Sketch功能差不多&#xff1b;但是他可以在Mac&#xff0c;Windows PC&#xff0c;Linux计算机甚至Chromebook&#xff0c;…

中国各地级市-产业增加值、产业升级、产业结构高级化(2000-2021年)

产业增加值、产业升级和产业结构高级化是衡量地区经济发展水平的重要指标&#xff1a; 产业增加值&#xff1a;指在一定时期内&#xff0c;单位产值的增长部分&#xff0c;体现了产值、产量和增加值的综合增长能力。 产业升级&#xff1a;指通过技术进步和效率提升&#xff0c…

5.sklearn-朴素贝叶斯算法、决策树、随机森林

文章目录 环境配置&#xff08;必看&#xff09;头文件引用1.朴素贝叶斯算法代码运行结果优缺点 2.决策树代码运行结果决策树可视化图片优缺点 3.随机森林代码RandomForestClassifier()运行结果总结 环境配置&#xff08;必看&#xff09; Anaconda-创建虚拟环境的手把手教程相…

产品售后|基于SprinBoot+vue的产品售后管理​​​​​​​系统(源码+数据库+文档)

产品售后管理系统 目录 基于SprinBootvue的产品售后管理系统 一、前言 二、系统设计 三、系统功能设计 管理员模块实现 客户模块实现 受理人员模块实现 工程师模块实现 厂商模块实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、…

STM32外部中断(总结了易出现的BUG)

本文主要讲述了&#xff0c;本人在使用STM32F103C8T6做项目时&#xff0c;使用到按键触发外部中断时&#xff0c;发现无法触发外部中断。通过查看寄存器找出问题的过程&#xff0c;并总结了出现该问题的原因。 出现的问题 在使用STM32F103C8T6做一个矩阵键盘任务时&#xff0…

【学习笔记】卫星通信NTN 3GPP标准化进展分析(五)- 3GPP Release19 研究计划

一、引言&#xff1a; 本文来自3GPP Joern Krause, 3GPP MCC (May 14,2024) Non-Terrestrial Networks (NTN) (3gpp.org) 本文总结了NTN标准化进程以及后续的研究计划&#xff0c;是学习NTN协议的入门。 【学习笔记】卫星通信NTN 3GPP标准化进展分析&#xff08;一&#xff…

R语言报错 | object ‘integral‘ not found whilst loading name

1、报错背景 Registered S3 method overwritten by htmlwidgets:method from print.htmlwidget tools:rstudio Error: package or namespace load failed for ‘Seurat’:object integral not found whilst loading namespace spatstat.core 当我想library&…

RabbitMQ~架构、能力、AMQP、工作模式、高可用、死信队列了、事务机制了解

RabbitMQ RabbitMQ是使用Erlang编写的一个开源的消息中间件。它实现了AMQP(高级消息队列协议)&#xff0c;并支持其他消息传递协议&#xff1a;例如STOMP(简单文本定向消息协议)和MQTT(物联网协议)。 支持多种客户端如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、…