RAG优化技巧|7大挑战与解決方式|提高你的LLM能力

在当今快速发展的人工智能领域,大型语言模型(LLM)已经成为无处不在的技术,它们不仅改变了我们与机器交流的方式,还在各行各业中发挥着革命性的影响。

然而,尽管LLM + RAG的能力已经让人惊叹,但我们在使用RAG优化LLM的过程中,还是会遇到许多挑战和困难,包括但不限于检索器返回不准确或不相关的数据,并且基于错误或过时信息生成答案。因此本文旨在提出RAG常见的7大挑战,并附带各自相应的优化方案,期望能够帮助我们改善RAG。

下图展示了RAG系统的两个主要流程:检索和查询;红色方框代表可能会遇到的挑战点,主要有7项:

  1. Missing Content: 缺失內容
  2. Missed Top Ranked: 错误排序內容,导致正确答案沒有被成功 Retrieve
  3. Not in Context: 上限文限制,导致正确答案沒有被采用
  4. Wrong Format: 格式错误
  5. Incomplete: 回答不全面
  6. Not Extracted: 未能检索信息
  7. Incorrect Specificity: 不合适的详细回答

img

这些挑战不仅关系到系统的可用性和准确性,还直接影响到用户对技术的信任度。为了解决这些问题,以下是针对每个挑战的优化方案:

缺失内容(Missing Content)

RAG 系统面对的问题无法从现有文件中得到答案时,就会出现这种情况。在最佳情况下,我们希望 RAG 系统直接回答「我不知道」。然而,实际上RAG 系统常常会编造或错误回答问题。

针对这个问题,目前有两大解决策略:

1. 数据清理

俗话说"吃什么、吐什么"。原始数据质量对信息处理系统的准确性至关重要,若输入数据错误或矛盾,或者预处理步骤不当,则无论检索增强生成(RAG)系统有多先进,也无法从混乱数据中提取有价值信息。这意味着我们必须在数据源选择、数据清洗、预处理等环节投入资源和技术,以确保输入数据尽可能准确和一致。这个策略不仅适用于本文讨论的问题,也适用于所有数据处理流程中,数据质量始终是关键。

2. prompt 工程

在知识库缺乏相关信息、导致系统可能给出看似合理但实际上错误答案的情况下,使用提示工程是一个非常有帮助的解决方式。例如通过设定提示:“如果你对答案不确定,就直接告诉我你不知道”,如此可以鼓励模型采取更谨慎和诚实的回应态度,从而避免误导用户。虽然不能保证系统回答的绝对准确性,但通过这样的提示, 确实能提高回答品质。

未命中排名靠前的内容(Missed Top Ranked)

这个挑战主要在于“答案在文件中,但由于排名靠前而未能提供给用户”。理论上,检索系统会为每个文档分配一个排名,此排名将决定其在后续处理中的使用程度。然而,在实际操作中,受限于性能和资源,通常只有排名最高的前 K 个文档会被选取并展示给用户。这里的 K 是基于性能考虑的参数。

针对该问题,存在两种解决方式:

1. 调整参数以优化搜索效果

该部分提出了两个方面调整以增加 RAG 效率和准确性:chunk_size

如果要直接在 langchain 调整块大小,请使用以下代码:

python复制代码 from langchain.text_splitter import RecursiveCharacterTextSplitter
 
 text_splitter = RecursiveCharacterTextSplitter(chunk_size=100)
 all_splits = text_splitter.split_documents(PDF_data)

k 值涉及到检索器应该返回多少个答案,我们可以选择返回更多的答案,以确保正确答案不会被 LLM 忽略:

python复制代码 retriever = vectordb.as_retriever(search_kwargs={"k": 8})
 
 qa = RetrievalQA.from_chain_type(
     llm=llm, 
     chain_type="stuff", 
     retriever=retriever, 
     verbose=True
 )

2. 优化检索文档的排序

在将检索到的文件送到LLM前,先对文件进行最佳化排序,能大幅提升RAG系统的效能,因为初始排序无法反映件与查询的真实相关性。这系列的论文可以看Liu et al.2023,论文中指出,将最相似的文档放在开头或结尾时,效能通常最高,因为模型容易迷失在中间。

langchain中,我们可以使用langchain原生的Long-Context ReorderCohere Reranker来实现,请参考官方文件。

2.1 Long-Context Reorder

python复制代码 retriever = vectordb.as_retriever(search_kwargs={"k": 8})
 query = "What can you tell me about the Celtics?"
 
 # 按相关度分数排序获取相关文档
 docs = retriever.get_relevant_documents(query)
 
 # 重新排序文件:
 # 列表中不太相关的文件将排在中间位置。开始/结尾处的相关要素。
 reordering = LongContextReorder()
 reordered_docs = reordering.transform_documents(docs)
 
 # 确认前后共有4份相关文件。
 print(reordered_docs)

2.2 Cohere Reranker

python复制代码 from langchain.retrievers import ContextualCompressionRetriever
 from langchain.retrievers.document_compressors import CohereRerank
 from langchain_community.llms import Cohere
 
 retriever = vectordb.as_retriever(search_kwargs={"k": 8})
 query = "What can you tell me about the Celtics?"
 
 # 按相关性得分排序以获取相关文件
 docs = retriever.get_relevant_documents(query)
 
 # 使用Cohere重新排名端点来对返回的结果进行重新排名
 llm = Cohere(temperature=0)
 compressor = CohereRerank()
 compression_retriever = ContextualCompressionRetriever(
     base_compressor=compressor, base_retriever=retriever
 )
 
 compressed_docs = compression_retriever.get_relevant_documents(
     "What did the president say about Ketanji Jackson Brown"
 )
 pretty_print_docs(compressed_docs)

Not in Context(上下文限制)

论文有提到:「答案所在的文档虽从数据库中检索出来,但并未包含在生成答案的上下文中。」这种情况通常发生在返回的文档太多,需透过一个整合过程来提取答案的情境。 为了解决这个问题,扩大上下文的处理范围是一种方式,此外也建议可以尝试以下方法:

1.调整检索策略

Langchain中提供许多检索的方法,确保我们在RAG中能拿到最符合问题的文件,详细的列表可以参考官网,其中包含:

  1. Vectorstore
  2. ParentDocument
  3. Multi Vector
  4. Self Query
  5. Contextual Compression
  6. Time-Weighted Vectorstore
  7. Multi-Query Retriever
  8. Ensemble
  9. Long-Context Reorder

这些策略为我们提供了一种灵活多样的方式,能够根据不同的检索需求和应用场景进行调整,以此提升检索过程中的准确性和效率。

2. 微调 embedding

Fine-tuning 嵌入模型针对特定任务是提高检索准确性的有效方法。如果我们的 embedding model 是开源的,可以使用 LlamaIndex 功能进行实现。与 Langchian 相比,LlamaIndex 是为了检索数据而优化的软件包,在这方面提供了详细教程,而 Langchian 则没有相应功能。

以下示范如何设置微调框架、执行微调操作并获取经过微调的模型,也可参考官方文档。

python复制代码 finetune_engine = SentenceTransformersFinetuneEngine(
     train_dataset,
     model_id="BAAI/bge-small-en",
     model_output_path="test_model",
     val_dataset=val_dataset,
 )
 
 finetune_engine.finetune()
 
 embed_model = finetune_engine.get_finetuned_model()

格式错误

当我们使用prompt要求LLM以特定格式(如表格或列表)提取信息,但却被LLM忽略时,可以尝试以下3种解决策略:

1. 改进prompt

我们可以采用以下策略来改进 prompt,解决这个问题:

A.明确说明指令

B.简化请求并使用关键字

C.提供示例

D.采用迭代提示,提出后续问题

2. 输出解析器

输出解析器负责获取LLM的输出,并将其转换为更合适的格式,因此当我们希望使用LLM生成任何形式的结构化数据时,这非常有用。它主要在以下方面帮助确保获得期望的输出:

A. 为任何提示/查询提供格式化指令

B. 对大语言模型的输出进行 解析

Langchain提供了许多不同类型Output Parsers的流接口,以下是示范代码,具体细节请参阅官方文档。

python复制代码 from langchain.output_parsers import PydanticOutputParser
 from langchain.prompts import PromptTemplate
 from langchain_core.pydantic_v1 import BaseModel, Field, validator
 from langchain_openai import OpenAI
 
 model = OpenAI(model_name="gpt-3.5-turbo-instruct", temperature=0.0)
 
 
 # 定义您想要的数据结构。
 class Joke(BaseModel):
     setup: str = Field(description="question to set up a joke")
     punchline: str = Field(description="answer to resolve the joke")
 
     # 可以通过 Pydantic 轻松添加自定义验证逻辑。
     @validator("setup")
     def question_ends_with_question_mark(cls, field):
         if field[-1] != "?":
             raise ValueError("Badly formed question!")
         return field
 
 
 # 设置一个解析器 + 将指令注入到提示模板中。
 parser = PydanticOutputParser(pydantic_object=Joke)
 
 prompt = PromptTemplate(
     template="Answer the user query.\n{format_instructions}\n{query}\n",
     input_variables=["query"],
     partial_variables={"format_instructions": parser.get_format_instructions()},
 )
 
 # And a query intended to prompt a language model to populate the data structure.
 prompt_and_model = prompt | model
 output = prompt_and_model.invoke({"query": "Tell me a joke."})
 parser.invoke(output)

3. Pydantic parser

Pydantic 是一个多功能框架,它能够将输入的文本字符串转化为结构化的Pydantic物件。Langchain有提供此功能,归类在Output Parsers中,以下是示范code,可以参考官方文件。

python复制代码 from typing import List
 
 from langchain.output_parsers import PydanticOutputParser
 from langchain.prompts import PromptTemplate
 from langchain_core.pydantic_v1 import BaseModel, Field, validator
 from langchain_openai import ChatOpenAI
 
 model = ChatOpenAI(temperature=0)
 
 # 定义你期望的数据结构。
 class Joke(BaseModel):
     setup: str = Field(description="question to set up a joke")
     punchline: str = Field(description="answer to resolve the joke")
 
     # 可以很容易地使用 Pydantic 添加自定义验证逻辑。
     @validator("setup")
     def question_ends_with_question_mark(cls, field):
         if field[-1] != "?":
             raise ValueError("Badly formed question!")
         return field
 
 
 # 一个用来促使语言模型填充数据结构的查询意图。
 joke_query = "Tell me a joke."
 
 # 设置一个解析器+将指令注入到提示模板中。
 parser = PydanticOutputParser(pydantic_object=Joke)
 
 prompt = PromptTemplate(
     template="Answer the user query.\n{format_instructions}\n{query}\n",
     input_variables=["query"],
     partial_variables={"format_instructions": parser.get_format_instructions()},
 )
 
 chain = prompt | model | parser
 
 chain.invoke({"query": joke_query})

回答不完整

有时候 LLM 的回答并不完全错误,但会遗漏了一些细节。这些细节虽然在上下文中有所体现,但并未被充分呈现出来。例如,如果有人询问“文档A、B和C主要讨论了哪些方面?”对于每个文档分别提问可能会更加适合,这样可以确保获得更详细的答案。

查询转换

提高 RAG 系统效能的一个策略是添加一层查询理解层,也就是在实际进行检索前,先进行一系列的 Query Rewriting。具体而言,我们可以采用以下四种转换方法:

1.1 路由:在不改变原始查询的基础上,识别并导向相关的工具子集,并将这些工具确定为处理该查询的首选。

1.2 查询重写:在保留选定工具的同时,通过多种方式重构查询语句,以便跨相同的工具集进行应用。

1.3 子问题:将原查询拆解为若干个更小的问题,每个问题都针对特定的工具进程定向,这些工具是根据它们的元数据来选择。

1.4 ReAct 代理选择器:根据原始查询判断最适用的工作,并为在该工作上运行而特别构造了查询。

Llamaindex已经为这个问题整理出了一系列方便操作的功能,请查看官方文件;而Langchain的大部分功能则散落在Templates中,例如HyDE的实现和论文内容。以下是使用Langchain进行HyDE的示例:

python复制代码 from langchain.llms import OpenAI
 from langchain.embeddings import OpenAIEmbeddings
 from langchain.chains import LLMChain, HypotheticalDocumentEmbedder
 from langchain.prompts import PromptTemplate
 
 base_embeddings = OpenAIEmbeddings()
 llm = OpenAI()
 
 # Load with `web_search` prompt
 embeddings = HypotheticalDocumentEmbedder.from_llm(llm, base_embeddings, "web_search")
 
 # 现在我们可以将其用作任何嵌入类!
 result = embeddings.embed_query("Where is the Taj Mahal?")

Not Extracted(未能检索信息)

RAG系统面对众多信息时,往往难以准确提取出所需的答案,关键信息的遗漏降低了回答的质量。研究显示,这种情况通常发生在上下文中存在过多干扰或矛盾信息时。 以下是针对这一问题提出的三种解决策略:

1. 数据清洗

数据的质量直接影响到检索的效果,这个痛点再次突显了优质数据的重要性。在责备你的 RAG 系统之前,请确保你已经投入足够的精力去清洗数据。

2. 信息压缩

提示信息压缩技术在长上下文场景下,首次由 LongLLMLingua 研究项目提出,并已在 LlamaIndex 中得到应用,相对 Langchain 的资源则较零散。现在,我们可以将 LongLLMLingua 作为节点后处理器来实施,这一步会在检索后对上下文进行压缩,然后再送入 LLM 处理。

img

以下是在 LlamaIndex 中使用 LongLLMLingua 的示范,其他细节可以参考官方文件:

python复制代码 from llama_index.query_engine import RetrieverQueryEngine
 from llama_index.response_synthesizers import CompactAndRefine
 from llama_index.postprocessor import LongLLMLinguaPostprocessor
 from llama_index.schema import QueryBundle
 
 node_postprocessor = LongLLMLinguaPostprocessor(
     instruction_str="Given the context, please answer the final question",
     target_token=300,
     rank_method="longllmlingua",
     additional_compress_kwargs={
         "condition_compare": True,
         "condition_in_question": "after",
         "context_budget": "+100",
         "reorder_context": "sort",  # enable document reorder
     },
 )
 
 retrieved_nodes = retriever.retrieve(query_str)
 synthesizer = CompactAndRefine()
 
 ## 梳理 RetrieverQueryEngine 中的步骤,以确保清晰易懂。
 ## 后处理(压缩),合成
 new_retrieved_nodes = node_postprocessor.postprocess_nodes(
     retrieved_nodes, query_bundle=QueryBundle(query_str=query_str)
 )
 
 print("\n\n".join([n.get_content() for n in new_retrieved_nodes]))
 
 response = synthesizer.synthesize(query_str, new_retrieved_nodes)

3. LongContextReorder

这在第二个挑战,Missed Top Ranked中有提到,为了解决LLM在文件中间会有「迷失」的问题,它通过重新排序检索到的节点来优化处理,特别适用于需要处理大量顶级结果的情形。细节示范可以参考上面的内容。

不正确的具体性(Incorrect Specificity)

有时,LLM 的回答可能不够详细或具体,用户可能需要进行多次追问才能得到清晰的解答。这些答案可能过于笼统,无法有效满足用户的实际需求。

因此,我们需要采取更高级的检索策略来寻找解决方案。

当我们发现回答缺乏期望的详细程度时,通过优化检索策略可以显著提升信息获取的准确性。LlamaIndex 提供了许多高级检索技巧,而Langchain 在这方面资源较少。以下是一些在 LlamaIndex 中能够有效缓解此类问题的高级检索技巧:

  • Auto Merging Retriever
  • Metadata Replacement + Node Sentence Window
  • Recursive Retriever

总结

本文探讨了使用 RAG 技术时可能面临的七大挑战,并针对每个挑战提出了具体的优化方案,以提升系统准确性和用户体验。

  • 缺失内容:解决方案包括数据清理和提示工程,确保输入数据的质量并引导模型更准确地回答问题。
  • 未识别出的最高排名:可通过调整检索参数和优化文件排序来解决,以确保向用户呈现最相关的信息。
  • 背景不足:扩大处理范围和调整检索策略至关重要,以包含更广泛的相关信息。
  • 格式错误:可以通过改进提示、使用输出解析器和 Pydantic 解析器实现,有助于按照用户期望的格式获取信息。
  • 不完整部分:可通过查询转换来解决,确保全面理解问题并作出回应。
  • 未提取部分:数据清洗、消息压缩和 LongContextReorder 是有效的解决策略。
  • 特定性不正确:可以通过更精细化的检索策略如 Auto Merging Retriever、元数据替换等技巧来解决问题,并进一步提高信息查找精度。

通过对 RAG 系统挑战的深入分析和优化,我们不仅可以提升LLM的准确性和可靠性,还能大幅提高用户对技术的信任度和满意度。

希望这篇能帮助我们改善我们的 RAG 系统。

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Salia PLCC cPH2 远程命令执行漏洞(CVE-2023-46359)

漏洞描述 Salia PLCC cPH2 v1.87.0 及更早版本中存在一个操作系统命令注入漏洞,该漏洞可能允许未经身份验证的远程攻击者通过传递给连接检查功能的特制参数在系统上执行任意命令。 产品界面 fofa语法 "Salia PLCC" POC GET /connectioncheck.php?ip1…

考研计组chap2数据的表示和运算

3一、进位计数制 1.r进制 第i位表示r进制的权为i 2.进制转换 (1)r->10 对应位置数*权值 (2)2 -> 16 or 8 每三位2进制数可表示1位16进制 每四位2进制数可表示1位16进制 so 分开之后转为16进制即可 eg:1…

iOS APP内存泄漏的问题

iOS APP内存泄漏是指应用程序不再使用内存,但内存却没有被释放,导致应用程序占用过多的内存,甚至崩溃。内存泄漏是iOS开发中常见的问题,会严重影响应用程序的性能和稳定性。北京木奇移动技术有限公司,专业的软件外包开…

【Java】BigDecimal类型——BigDecimal 为什么可以保证精度不丢失

目录 简介类介绍案例分析总结BigDecimal类型的使用场景MySQL中存储BigDecimal类型数据补充:BigDecimal类型使用时的注意事项BigDecimal类型的其他使用 简介 BigDecimal是Java中的一个类,用于处理大数运算。它提供了精确的数值计算,可以处理任…

PCB相关

PCB过孔过流能力计算软件: PCB过孔载流计算器EDA在线工具PCB联盟网 - Powered by Discuz! 孔径:过孔直径 温升:过孔温升标准 参考资料: PCB及钢网与嘉力创标准_嘉立创不支持盲埋孔-CSDN博客(待学习) PC…

openEuler系统中LVM逻辑卷的创建及扩容与缩容

1、背景说明 安装好openEuler操作系统后为其增加新的磁盘进行逻辑卷的扩容与缩容 本次测试使用VMware Workstation Pro虚拟机增加一个磁盘大小为500GB,虚机不关机直接加盘后,使用ls /dev/sd* 或者fdisk -l 发现没有新加的磁盘设备Disk /dev/sdb &#…

MAVEN-SNAPSHOT和RELEASE + 打包到远程仓库

一、快照版本SNAPSHOT和发布版本RELEASE区别 快照版本SNAPSHOT和发布版本RELEASE区别-CSDN博客 在使⽤maven过程中,我们在开发阶段经常性的会有很多公共库处于不稳定状态,随时需要修改并发布,可能⼀天就要发布⼀次,遇到bug时&am…

[面试题]Kafka

[面试题]Java【基础】[面试题]Java【虚拟机】[面试题]Java【并发】[面试题]Java【集合】[面试题]MySQL[面试题]Maven[面试题]Spring Boot[面试题]Spring Cloud[面试题]Spring MVC[面试题]Spring[面试题]MyBatis[面试题]Nginx[面试题]缓存[面试题]Redis[面试题]消息队列[面试题]…

git merge(3个模式) 与 git rebase 图文详解区别

目录 1 git merge1.1 模式一:fast-forward(–ff)1.2 模式二:non-Fast-forward(–no-ff)1.3 模式三:fast-forward only(–ff-only) 2 git rebase3 区别 1 git merge git merge有好几种不同的模式 默认情况下你直接使用 git merge 命令&#x…

怎么还有人不清楚H3C认证考试流程?给你整理得明明白白

最近不少人都在后台问H3CIE资格认证考试(全称:H3C认证路由交换互联网络专家),今天咱们就来聊一聊这个考试流程。第一次报考H3CIE-RS的考生需先参加新华三人才研学中心认可的H3CIE-RS认证培训。 H3C授权培训中心可在新华三官网查询…

迅为RK3568驱动教程第十八期-PWM

系统性PWM课程,完全掌握PWM。采用框架学习法,从基础知识、PWM子系统框架、API函数理论由面到点,逐个击破。通过SG90舵机,呼吸灯的控制把理论转为动手能力。最后从零实现输入捕获驱动程序,深入探究,体验一把…

Python爬虫小白入门(四)PhatomJS+Selenium篇下

一、前言 前文介绍了PhatomJS 和Selenium 的用法,工具准备完毕,我们来看看如何使用它们来改造我们之前写的小爬虫。 我们的目的是模拟页面下拉到底部,然后页面会刷出新的内容,每次会加载10张新图片。 大体思路是,用S…

list的特性及使用

1、list的介绍 1.list是序列容器,允许在序列的任何位置进行时间复杂度为o(1)的插入和删除操作,并且由双向迭代器。 2.list的底层是双链表,双链表不是物理上连续的储存空间,而是不同的地址空间通过next和prev指针连接成顺序表。 …

【每天学会一个渗透测试工具】AppScan安装及使用指南

🌝博客主页:泥菩萨 💖专栏:Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 https://www.hcl-software.com/appscan AppScan是一种综合型漏洞扫描工具,采用SaaS解决方案,它将所以…

【Tello无人机】使用Matlab完成控制器的设计—建模

模型辨识篇 在实际的无人机系统中,控制器的设计至关重要,它直接影响无人机的稳定性和响应能力。然而,要设计出高效、可靠的控制器,首先必须准确理解无人机的动态行为,这就需要通过收集输入输出数据来辨识其运动学模型。…

天池人脸识别项目复现

1 项目背景 #c 概述 项目的目的 图像分类是整个计算机视觉领域中最基础的任务,也是最重要的任务之⼀,最适合拿来进⾏学习实践。为了让新⼿们能够⼀次性体验⼀个⼯业级别的图像分类任务的完整流程,本次我们选择带领⼤家完成⼀个对图片中⼈脸进…

从0开始C++(二):类、对象、封装

目录 类&对象的概念 类的内容 对象的创建 ● 栈内存对象 ● 堆内存对象 封装 类&对象的概念 类和对象是一个比较抽象的概念,这里直接用一个实例方便理解。 类:类是一个抽象的概念,用来描述同一类对象的特点(比如&am…

从零开始如何学习人工智能?

说说我自己的情况:我接触AI的时候,是在研一。那个时候AlphaGo战胜围棋世界冠军李世石是大新闻,人工智能第一次出现我面前,当时就想搞清楚背后的原理以及这些技术有什么作用。 就开始找资料,看视频。随着了解的深入&am…

第 三 方 组 件 e l e m e n t - u i[Vue]

一、组件之间的传值 组件可以由内部的Data提供数据&#xff0c;也可以由父组件通过prop的方式传值。 兄弟组件之间可以通过Vuex等统一数据源提供数据共享 第一种 Movie.vue <template><div><h1>我才不要和你做朋友</h1></div></template&…

怎么为自己的VPS选择合适的CPU和RAM?

为网站选择VPS&#xff08;虚拟专用服务器&#xff09;与为家庭或办公室选择台式机或笔记本电脑没有什么不同。基本上&#xff0c;您要做的就是查看硬件配置并比较功能和价格。 然而&#xff0c;虽然您可能对个人计算机所需的资源类型有一个粗略的估计&#xff0c;但为服务器获…