授权调用: 介绍 Transformers 智能体 2.0

简要概述

我们推出了 Transformers 智能体 2.0!

⇒ 🎁 在现有智能体类型的基础上,我们新增了两种能够 根据历史观察解决复杂任务的智能体

⇒ 💡 我们致力于让代码 清晰、模块化,并确保最终提示和工具等通用属性透明化

⇒ 🤝 我们加入了 分享功能,以促进社区智能体的发展。

⇒ 💪 全新的智能体框架性能卓越,使得 Llama-3-70B-Instruct 智能体在 GAIA 排行榜上超越了基于 GPT-4 的智能体!

🚀 快去体验,力争在 GAIA 排行榜上名列前茅!

什么是智能体?

大型语言模型 (LLMs) 能够处理广泛的任务,但它们通常在逻辑、计算和搜索等特定任务上表现不佳。当在这些它们表现不好的领域被提示时,它们经常无法生成正确的答案。

克服这种弱点的一种方法就是创建一个 智能体,它只是一个由 LLM 驱动的程序。智能体通过 工具 获得能力,帮助它执行动作。当智能体需要特定技能来解决特定问题时,它会依赖于工具箱中的适当工具。

因此,在解决问题时,如果智能体需要特定技能,它可以直接依赖于工具箱中的适当工具。

实验上,智能体框架通常表现非常好,在多个基准测试上达到了 SOTA。例如,看看 HumanEval 的最上面的提交: 它们就是智能体系统。

  • HumanEval 的最上面的提交https://paperswithcode.com/sota/code-generation-on-humaneval

Transformers 智能体方法

构建智能体的过程很复杂,需要高水平的清晰度和模块化设计。一年前,我们发布了 Transformers 智能体,现在我们正加倍努力实现我们的核心设计目标。

我们的框架力求实现:

  • 简化以提升清晰度: 我们将抽象减少到最低限度。简单的错误日志和可访问的属性让你轻松检查系统发生的情况,从而获得更多的清晰度。

  • 模块化设计: 我们更愿意提供构建模块,而不是一个完整、复杂的特性集。这样你可以自由选择最适合你的项目的构建模块。

    • 例如,由于任何智能体系统只是由 LLM 引擎驱动的载体,我们决定在概念上分离这两者,使你可以用任何底层 LLM 创建任何类型的智能体。

此外,我们还提供 分享功能,让你能在前人的基础上继续构建!

主要元素

  • Tool (工具): 这是一个类,允许你使用工具或实现一个新的工具。它主要由一个可调用的前向method 组成,执行工具动作,以及一些必要的属性: name (名称) 、descriptions (描述) 、inputs (输入) 和output_type (输出类型)。这些属性用于动态生成工具的使用手册,并将其插入到 LLM 的提示中。

  • Toolbox (工具箱): 这是一组工具,作为资源提供给智能体,用于解决特定任务。出于性能考虑,工具箱中的工具已经实例化并准备好使用。这是因为某些工具需要时间来初始化,所以通常更好的是重用现有的工具箱,只更换一个工具,而不是在每次智能体初始化时从头开始构建一组工具。

  • CodeAgent (代码智能体): 一个非常简单的智能体,其动作作为单个 Python 代码块生成。它将无法对先前的观察进行迭代。

  • ReactAgent (反应智能体): ReAct 智能体遵循一个循环: 思考 ⇒ 行动 ⇒ 观察直到解决任务。我们提出了两种 ReActAgent 类:

    • ReactCodeAgent (反应代码智能体) 将其动作作为 Python 代码块生成。

    • ReactJsonAgent (反应 JSON 智能体) 将其动作作为 JSON 代码块生成。

查看 文档 了解如何使用每个组件!

  • 文档链接https://hf.co/docs/transformers/en/main_classes/agent

智能体在底层是如何工作的?

本质上,智能体的作用是“允许 LLM 使用工具”。智能体有一个关键的 agent.run() 方法,该方法:

  • 在一个 特定提示 中向你的 LLM 提供关于工具使用的信息。这样,LLM 可以选择运行工具来解决任务。

  • 解析 来自 LLM 输出的工具调用 (可以通过代码、JSON 格式或任何其他格式)。

  • 执行 调用。

  • 如果智能体被设计为对先前的输出进行迭代,它会 保留 先前的工具调用和观察的记忆。这个记忆可以根据你希望它持续的时间长短而变得更加或更少细致。

52b0d096585b2724c4fe0147568550d5.png

关于智能体的更多一般背景信息,你可以阅读 Lilian Weng 的 这篇优秀博客,或者阅读我们之前的博客,关于使用 LangChain 构建 智能体。

  • 博客地址https://lilianweng.github.io/posts/2023-06-23-agent/

  • 智能体https://hf.co/blog/open-source-llms-as-agents

要深入了解我们的包,请查看 智能体文档。

  • 智能体文档https://hf.co/docs/transformers/en/transformers_agents

示例用例

为了获得此功能的早期访问权限,请首先从其 main 分支安装 transformers :

pip install "git+https://github.com/huggingface/transformers.git#egg=transformers[agents]"

智能体 2.0 将在 v4.41.0 版本中发布,预计将于五月中旬上线。

自我修正的检索增强生成

快速定义: 检索增强生成 (RAG) 是“使用 LLM 回答用户查询,但基于从知识库检索到的信息来回答”。与使用普通或微调的 LLM 相比,它有许多优点: 举几个例子,它允许基于真实事实来回答问题,减少虚构,它允许向 LLM 提供特定领域的知识,并且可以细粒度地控制对知识库信息的访问。

假设我们想要执行 RAG,并且某些参数必须动态生成。例如,根据用户查询,我们可能想要将搜索限制在知识库的特定子集,或者我们可能想要调整检索到的文档数量。难题是: 如何根据用户查询动态调整这些参数?嗯,我们可以通过让我们的智能体访问这些参数来实现!

让我们设置这个系统。

安装以下依赖项:

pip install langchain sentence-transformers faiss-cpu

我们首先加载一个想要在其上执行 RAG 的知识库: 这个数据集是许多 huggingface 包的文档页面汇编,以 markdown 格式存储。

import datasets
knowledge_base = datasets.load_dataset("m-ric/huggingface_doc", split="train")

现在我们通过处理数据集并将其存储到向量数据库中来准备知识库,以便检索器使用。我们将使用 LangChain,因为它具有用于向量数据库的优秀工具:

from langchain.docstore.document import Document
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain_community.embeddings import HuggingFaceEmbeddings

source_docs = [
    Document(
        page_content=doc["text"], metadata={"source": doc["source"].split("/")[1]}
    ) for doc in knowledge_base
]

docs_processed = RecursiveCharacterTextSplitter(chunk_size=500).split_documents(source_docs)[:1000]

embedding_model = HuggingFaceEmbeddings("thenlper/gte-small")
vectordb = FAISS.from_documents(
    documents=docs_processed,
    embedding=embedding_model
)

现在我们已经准备好了数据库,让我们构建一个基于它回答用户查询的 RAG 系统!

我们希望我们的系统根据查询仅从最相关的信息来源中选择。

我们的文档页面来自以下来源:

>>> all_sources = list(set([doc.metadata["source"] for doc in docs_processed]))
>>> print(all_sources)

['blog', 'optimum', 'datasets-server', 'datasets', 'transformers', 'course',
'gradio', 'diffusers', 'evaluate', 'deep-rl-class', 'peft',
'hf-endpoints-documentation', 'pytorch-image-models', 'hub-docs']

我们如何根据用户查询选择相关的来源?

👉 让我们构建一个 RAG 系统作为智能体,它将自由选择其信息来源!

我们创建一个检索工具,智能体可以使用它选择的参数来调用:

import json
from transformers.agents import Tool
from langchain_core.vectorstores import VectorStore

class RetrieverTool(Tool):
    name = "retriever"
    description = "Retrieves some documents from the knowledge base that have the closest embeddings to the input query."
    inputs = {
        "query": {
            "type": "text",
            "description": "The query to perform. This should be semantically close to your target documents. Use the affirmative form rather than a question.",
        },
        "source": {
            "type": "text",
            "description": ""
        },
    }
    output_type = "text"
    
    def __init__(self, vectordb: VectorStore, all_sources: str, **kwargs):
        super().__init__(**kwargs)
        self.vectordb = vectordb
        self.inputs["source"]["description"] = (
         f"The source of the documents to search, as a str representation of a list. Possible values in the list are: {all_sources}. If this argument is not provided, all sources will be searched."
       )

    def forward(self, query: str, source: str = None) -> str:
        assert isinstance(query, str), "Your search query must be a string"

        if source:
            if isinstance(source, str) and "[" not in str(source): # if the source is not representing a list
                source = [source]
            source = json.loads(str(source).replace("'", '"'))

        docs = self.vectordb.similarity_search(query, filter=({"source": source} if source else None), k=3)

        if len(docs) == 0:
            return "No documents found with this filtering. Try removing the source filter."
        return "Retrieved documents:\n\n" + "\n===Document===\n".join(
            [doc.page_content for doc in docs]
        )

现在创建一个利用这个工具的智能体就很简单了!

智能体在初始化时需要以下参数:

  • tools : 智能体将能够调用的工具列表。

  • llm_engine : 驱动智能体的 LLM。

我们的 llm_engine 必须是一个可调用的对象,它接受一个 messages 列表作为输入并返回文本。它还需要接受一个 stop_sequences 参数,指示何时停止生成。为了方便起见,我们直接使用包中提供的 HfEngine 类来获取一个调用我们的 Inference API 的 LLM 引擎。

  • messageshttps://hf.co/docs/transformers/main/chat_templating

  • Inference APIhttps://hf.co/docs/api-inference/en/index

from transformers.agents import HfEngine, ReactJsonAgent

llm_engine = HfEngine("meta-llama/Meta-Llama-3-70B-Instruct")

agent = ReactJsonAgent(
    tools=[RetrieverTool(vectordb, all_sources)],
    llm_engine=llm_engine
)

agent_output = agent.run("Please show me a LORA finetuning script")

print("Final output:")
print(agent_output)

由于我们将智能体初始化为 ReactJsonAgent ,它已经自动获得了一个默认的系统提示,告诉 LLM 引擎逐步处理并生成工具调用作为 JSON 代码块 (根据需要,你可以替换此提示模板)。

然后,当它的 .run() 方法被启动时,智能体会负责调用 LLM 引擎,解析工具调用的 JSON 代码块并执行这些工具调用,所有这些都在一个循环中进行,只有在提供最终答案时才会结束。

我们得到以下输出:

Calling tool: retriever with arguments: {'query': 'LORA finetuning script', 'source': "['transformers', 'datasets-server', 'datasets']"}
Calling tool: retriever with arguments: {'query': 'LORA finetuning script'}
Calling tool: retriever with arguments: {'query': 'LORA finetuning script example', 'source': "['transformers', 'datasets-server', 'datasets']"}
Calling tool: retriever with arguments: {'query': 'LORA finetuning script example'}
Calling tool: final_answer with arguments: {'answer': 'Here is an example of a LORA finetuning script: https://github.com/huggingface/diffusers/blob/dd9a5caf61f04d11c0fa9f3947b69ab0010c9a0f/examples/text_to_image/train_text_to_image_lora.py#L371'}

Final output:
Here is an example of a LORA finetuning script: https://github.com/huggingface/diffusers/blob/dd9a5caf61f04d11c0fa9f3947b69ab0010c9a0f/examples/text_to_image/train_text_to_image_lora.py#L371

我们可以看到自我修正的实际效果: 智能体最初尝试限制来源,但由于缺乏相应的文档,它最终没有限制任何来源。

我们可以通过检查第二步的日志中的 llm 输出来验证这一点: print(agent.logs[2]['llm_output'])

Thought: I'll try to retrieve some documents related to LORA finetuning scripts from the entire knowledge base, without any source filtering.

Action:
{
  "action": "retriever",
  "action_input": {"query": "LORA finetuning script"}
}

使用简单的多智能体设置 🤝 进行高效的网页浏览

在这个例子中,我们想要构建一个智能体并在 GAIA 基准测试上对其进行测试 (Mialon et al. 2023)。GAIA 是一个非常困难的基准测试,大多数问题需要使用不同的工具进行多个步骤的推理。一个特别困难的要求是拥有一个强大的网络浏览器,能够导航到具有特定约束条件的页面: 使用网站的内部导航发现页面,按时间选择特定的文章 …

  • Mialon et al. 2023https://hf.co/papers/2311.12983

网页浏览需要深入到子页面并滚动大量不必要的文本标记,这对于解决更高级别的任务是不必要的。我们将网页浏览的子任务分配给一个专业的网页浏览智能体。我们为其提供了一些浏览网页的工具和一个特定的提示 (查看仓库以找到特定的实现)。

定义这些工具超出了本文的范围: 但是你可以在 仓库 中找到特定的实现。

  • 仓库地址https://github.com/aymeric-roucher/agent_reasoning_benchmark

from transformers.agents import ReactJsonAgent, HfEngine

WEB_TOOLS = [
    SearchInformationTool(),
    NavigationalSearchTool(),
    VisitTool(),
    DownloadTool(),
    PageUpTool(),
    PageDownTool(),
    FinderTool(),
    FindNextTool(),
]

websurfer_llm_engine = HfEngine(
    model="CohereForAI/c4ai-command-r-plus"
) # 我们选择 Command-R+ 因为它具有很高的上下文长度

websurfer_agent = ReactJsonAgent(
    tools=WEB_TOOLS,
    llm_engine=websurfer_llm_engine,
)

为了允许更高层次的任务解决智能体调用这个智能体,我们可以简单地将其封装在另一个工具中:

class SearchTool(Tool):
    name = "ask_search_agent"
    description = "A search agent that will browse the internet to answer a question. Use it to gather informations, not for problem-solving."

    inputs = {
        "question": {
            "description": "Your question, as a natural language sentence. You are talking to an agent, so provide them with as much context as possible.",
            "type": "text",
        }
    }
    output_type = "text"

    def forward(self, question: str) -> str:
        return websurfer_agent.run(question)

然后我们使用这个搜索工具初始化任务解决智能体:

from transformers.agents import ReactCodeAgent

llm_engine = HfEngine(model="meta-llama/Meta-Llama-3-70B-Instruct")
react_agent_hf = ReactCodeAgent(
    tools=[SearchTool()],
    llm_engine=llm_engine,
)

让我们做这个任务:

使用 Marisa Alviar-Agnew 和 Henry Agnew 根据 CK-12 许可在 LibreText 的《初级化学》材料中提供的密度数据,编译日期为 2023 年 8 月 21 日。我有一加仑的蜂蜜和一加仑的蛋黄酱,温度为 25 摄氏度。我每次从一加仑蜂蜜中取出一杯蜂蜜。我要取出多少次一杯蜂蜜,才能使蜂蜜的重量低于蛋黄酱?假设容器本身的重量相同。

Thought: I will use the 'ask_search_agent' tool to find the density of honey and mayonnaise at 25C.
==== Agent is executing the code below:
density_honey = ask_search_agent(question="What is the density of honey at 25C?")
print("Density of honey:", density_honey)
density_mayo = ask_search_agent(question="What is the density of mayonnaise at 25C?")
print("Density of mayo:", density_mayo)
===
Observation:
Density of honey: The density of honey is around 1.38-1.45kg/L at 20C. Although I couldn't find information specific to 25C, minor temperature differences are unlikely to affect the density that much, so it's likely to remain within this range.
Density of mayo: The density of mayonnaise at 25°C is 0.910 g/cm³.

===== New step =====
Thought: I will convert the density of mayonnaise from g/cm³ to kg/L and then calculate the initial weights of the honey and mayonnaise in a gallon. After that, I will calculate the weight of honey after removing one cup at a time until it weighs less than the mayonnaise.
==== Agent is executing the code below:
density_honey = 1.42 # taking the average of the range
density_mayo = 0.910 # converting g/cm³ to kg/L
density_mayo = density_mayo * 1000 / 1000 # conversion

gallon_to_liters = 3.785 # conversion factor
initial_honey_weight = density_honey * gallon_to_liters
initial_mayo_weight = density_mayo * gallon_to_liters

cup_to_liters = 0.236 # conversion factor
removed_honey_weight = cup_to_liters * density_honey
===
Observation:

===== New step =====
Thought: Now that I have the initial weights of honey and mayonnaise, I'll try to calculate the number of cups to remove from the honey to make it weigh less than the mayonnaise using a simple arithmetic operation.
==== Agent is executing the code below:
cups_removed = int((initial_honey_weight - initial_mayo_weight) / removed_honey_weight) + 1
print("Cups removed:", cups_removed)
final_answer(cups_removed)
===
>>> Final answer: 6

✅ 答案是 正确的

测试我们的智能体

让我们使用智能体框架进行一些基准测试,看看不同模型的表现!

以下实验的所有代码都可以在 这里 找到。

  • 实验代码仓库https://github.com/aymeric-roucher/agent_reasoning_benchmark

基准测试大型语言模型引擎

agents_reasoning_benchmark 是一个小型但强大的推理测试,用于评估智能体性能。这个基准测试已经在 我们之前的博客 中使用并进行了更详细的解释。

  • 我们之前的博客https://hf.co/blog/open-source-llms-as-agents

这个想法是,你为智能体使用的工具选择可以极大地改变某些任务的性能。因此,这个基准测试限制了使用的工具集为一个计算器和一个非常基础的搜索工具。我们从几个数据集中挑选了问题,这些问题只能使用这两个工具来解决:

  • 来自 HotpotQA 的 30 个问题 (Yang et al., 2018),用于测试搜索工具的使用。

  • 来自 GSM8K 的 40 个问题 (Cobbe et al., 2021),用于测试计算器工具的使用。

  • 来自 GAIA 的 20 个问题 (Mialon et al., 2023),用于测试使用这两个工具解决困难问题的能力。

  • HotpotQAhttps://hf.co/datasets/hotpot_qa

  • Yang et al., 2018https://hf.co/papers/1809.09600

  • GSM8Khttps://hf.co/datasets/gsm8k

  • Cobbe et al., 2021https://hf.co/papers/2110.14168

  • GAIAhttps://hf.co/datasets/gaia-benchmark/GAIA

  • Mialon et al., 2023https://hf.co/papers/2311.12983

在这里,我们尝试了三种不同的引擎: Mixtral-8x7B, Llama-3-70B-Instruct,和 GPT-4 Turbo。

  • Mixtral-8x7Bhttps://hf.co/mistralai/Mixtral-8x7B-Instruct-v0.1

  • Llama-3-70B-Instructhttps://hf.co/meta-llama/Meta-Llama-3-70B-Instruct

  • GPT-4 Turbohttps://platform.openai.com/docs/models

323fd4bf75e1f603d30ce289452113d0.png

结果在上方显示 - 为了提高精度,我们显示了两轮完整运行的平均值。我们还测试了 Command-R+ 和 Mixtral-8x22B,但由于清晰度原因,这里没有显示。

  • Command-R+https://hf.co/CohereForAI/c4ai-command-r-plus

  • Mixtral-8x22Bhttps://hf.co/mistralai/Mixtral-8x22B-Instruct-v0.1

Llama-3-70B-Instruct 在开源模型中领先: 它与 GPT-4 相当,尤其在与 ReactCodeAgent 的结合中表现出色,得益于 Llama 3 强大的编码性能!

💡 比较基于 JSON 和基于代码的 React 智能体很有趣: 对于像 Mixtral-8x7B 这样较弱的 LLM 引擎,基于代码的智能体不如基于 JSON 的智能体表现好,因为 LLM 引擎经常无法生成好的代码。但随着更强大的模型作为引擎,基于代码的版本表现尤为出色: 在我们的经验中,基于代码的版本甚至在使用 Llama-3-70B-Instruct 时超越了基于 JSON 的版本。因此,我们使用基于代码的版本进行下一个挑战: 在完整的 GAIA 基准测试上进行测试。

使用多模态智能体刷 GAIA 排行榜

GAIA (Mialon et al., 2023) 是一个非常困难的基准测试: 在上面的 agent_reasoning_benchmark 中可以看到,即使我们挑选了可以使用两种基本工具解决的任务,模型也几乎没有达到 50% 的表现。

  • GAIAhttps://hf.co/datasets/gaia-benchmark/GAIA

  • Mialon et al., 2023https://hf.co/papers/2311.12983

现在我们想要在完整的测试集上获得分数,不再挑选问题。因此,我们需要覆盖所有模态,这导致我们使用这些特定的工具:

  • SearchTool : 如上所述的网页浏览器。

  • TextInspectorTool : 将文档作为文本文件打开并返回其内容。

  • SpeechToTextTool : 将音频文件转录为文本。我们使用基于 distil-whisper 的默认工具。

  • VisualQATool : 分析图像的视觉内容。对于这些,我们使用全新的 Idefics2-8b-chatty!

  • distil-whisperhttps://hf.co/distil-whisper/distil-large-v3

  • Idefics2-8b-chattyhttps://hf.co/HuggingFaceM4/idefics2-8b-chatty

我们首先初始化这些工具 (更多细节,请检查 仓库 中的代码)。

  • 仓库https://github.com/aymeric-roucher/agent_reasoning_benchmark

然后我们初始化我们的智能体:

from transformers.agents import ReactCodeAgent, HfEngine

TASK_SOLVING_TOOLBOX = [
    SearchTool(),
    VisualQATool(),
    SpeechToTextTool(),
    TextInspectorTool(),
]

react_agent_hf = ReactCodeAgent(
    tools=TASK_SOLVING_TOOLBOX,
    llm_engine=HfEngine(model="meta-llama/Meta-Llama-3-70B-Instruct"),
    memory_verbose=True,
)

在完成 165 个问题所需的一段时间后,我们提交了我们的结果到 GAIA 排行榜,然后…… 🥁🥁🥁

  • GAIA 排行榜https://hf.co/spaces/gaia-benchmark/leaderboard

91a2820dc2372c85af8c232471677e87.png

⇒ 我们的智能体排名第四: 它超过了许多基于 GPT-4 的智能体,现在已成为开源类别中的领先竞争者!

总结

在接下来的几个月里,我们将继续改进这个包。我们已经在我们开发路线图中确定了几个令人兴奋的路径:

  • 更多的智能体共享选项: 目前你可以从 Hub 推送或加载工具,我们将实现推送/加载智能体。

  • 更好的工具,特别是用于图像处理。

  • 长期记忆管理。

  • 多智能体协作。

👉 去尝试一下 Transformers 智能体! 我们期待着收到你的反馈和你的想法。

让我们一起用更多的开源模型刷排行榜登顶!🚀


英文原文: https://hf.co/blog/agents

原文作者: Aymeric Roucher, Lysandre, Pedro Cuenca

译者: innovation64

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

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

相关文章

PPT大珩助手新功能-生成迷宫

大珩助手是一款功能丰富的办公软件插件,它主要分为两个版本:PPT大珩助手和Word大珩助手。这两个版本都旨在提高用户在处理演示文稿和文档时的效率。 PPT大珩助手 这是一款专门为Microsoft PowerPoint设计的插件。它提供了多种功能,例如素材…

深入理解Kubernetes的调度核心思想

一、引言 Kubernetes(简称K8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用程序。在Kubernetes集群中,调度器是一个核心组件,它负责将Pod(Kubernetes中的最小部署单元)分配…

windows内存管理

一 windows系统的内存管理涉及哪些 1.1 虚拟内存管理机制 windows操作系统使用虚拟内存技术,将磁盘文件,通过映射对象(存储在物理内存)关联,映射到虚拟内存作为文件试图。即用户操作"虚拟内存中File View Objec…

【C语言】10.C语言指针(2)

文章目录 1.数组名的理解2.使用指针访问数组3.一维数组传参的本质4.冒泡排序算法步骤 5.二级指针6.指针数组7.指针数组模拟二维数组 1.数组名的理解 int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *p &arr[0];这里我们使用 &arr[0] 的方式拿到了数组第一个元素的地址&am…

Stable Diffusion【写实模型】:逼真,逼真,超级逼真的国产超写实摄影大模型万享XL

今天和大家分享的是一个国产万享系列中使用量最高的大模型:万享XL_超写实摄影,顾名思义,该大模型主要是面向写实摄影,一方面生成的图片人物皮肤纹理细节超级逼真,另一方面对于光影效果的处理也非常到位。对于万享XL超写实摄影大模…

数组单调栈-901. 股票价格跨度、leetcode

单调栈作为一种数据结构在求解类递增、递减方面的题目中有较为广泛的应用,在以往的leetcode中所见到的相关单调栈的题目均为单一元素,今天刷到901题目时,想到了将数组元素作为单调栈中元素的方法进行求解。 题目链接及描述 901. 股票价格跨…

秋招突击——算法打卡——5/27——复习{寻找特定中位数}——新做:{最长回文字串、Z 字形变换}

文章目录 复习——寻找特定中位数新作——最长回文子串个人思路分析实现代码参考学习和上述思路相同,枚举中心点字符串哈希二分 新作——Z 字形变换个人做法思路分析实现代码 参考解法分析总结 复习——寻找特定中位数 第一次的链接:寻找中位数本来以为…

Reactor模式Proactor模式

1.Reactor/Dispatcher模式 1.1 概述 Reactor模式下,服务端的构成为Reactor 处理资源池。其中,Reactor负责监听和分发事件,而处理资源池则负责处理事件。 该模式下的组合方案有下面几种(第三种几乎没有被实际应用): 1 * Reacto…

CRLF注入漏洞

1.CRLF注入漏洞原理 Nginx会将 $uri进行解码,导致传入%0a%0d即可引入换行符,造成CRLF注入漏洞。 执行xss语句 2.漏洞扩展 CRLF 指的是回车符(CR,ASCII 13,\r,%0d) 和换行符(LF,ASCII 10,\n&am…

栈 队列

目录 1.1栈的基本概念 1.1.1栈的定义 1.1.2栈的基本操作 1.2栈的顺序存储结构 1.2.1构造原理 1.2.2基本算法 1.3栈的链式存储结构 1.3.1构造原理 1.3.2基本算法 2.1队列的基本概念 2.1.1队列的定义 2.1.2队列的基本运算 2.2队列的顺序存储结构 2.2.1构造原理 2.2.1基…

C++ | Leetcode C++题解之第115题不同的子序列

题目&#xff1a; 题解&#xff1a; class Solution { public:int numDistinct(string s, string t) {int m s.length(), n t.length();if (m < n) {return 0;}vector<vector<unsigned long long>> dp(m 1, vector<unsigned long long>(n 1));for (i…

通过Zerossl给IP申请免费SSL证书, 实现https ip访问

参考通过Zerossl给IP申请免费SSL证书 | LogDicthttps://www.logdict.com/archives/tong-guo-zerosslgei-ipshen-qing-mian-fei-sslzheng-shu

软件系统开发标准流程文档(Word原件)

目的&#xff1a;规范系统开发流程&#xff0c;提高系统开发效率。 立项申请需求分析方案设计方案评审开发调整测试阶段系统培训试运行测试验收投入使用 所有文档过去进主页获取。 软件项目相关全套精华资料包获取方式①&#xff1a;点我获取 获取方式②&#xff1a;本文末个人…

【cocos creator 】生成六边形地图

想要生成一个六边形组成的地图 完整代码示例 以下是完整的代码示例&#xff0c;包含了注释来解释每一步&#xff1a; cc.Class({extends: cc.Component,properties: {hexPrefab: {default: null,type: cc.Prefab},mapWidth: 10, // 网格的宽度&#xff08;六边形的数量&am…

(delphi11最新学习资料) Object Pascal 学习笔记---第13章第4节 (内存管理和接口)

13.4 内存管理和接口 ​ 在第11章中&#xff0c;我介绍了接口的内存管理的关键要素。与对象不同&#xff0c;接口是受管理且具有引用计数。如我所提到的&#xff0c;接口引用会增加所引用对象的引用计数&#xff0c;但您可以声明接口引用为弱引用以禁用引用计数&#xff08;但…

Prometheus Operator创建告警规则并接入钉钉报警

prometheus之钉钉报警 前言1. 添加prometheus报警规则1.2 添加自定义报警规则文件 2. 配置钉钉报警2.2 部署dingding插件 3. 编写alertmanager配置文件 前言 在kubenetes上安装了kube-promethues&#xff08;包含Prometheus Operator&#xff09;,程序正常跑起来了&#xff0c…

Transformer详解(4)-前馈层残差连接层归一化

1、前馈层 前馈层接收自注意力层的输出作为输入。 from torch import nn import torch.nn.functional as Fclass FeedForward(nn.Module):def __init__(self, d_model512, d_ff2048, dropout0.1):super().__init__()# d_ff 默认设置为2048self.linear_1 nn.Linear(d_model,…

Python | Leetcode Python题解之第115题不同的子序列

题目&#xff1a; 题解&#xff1a; class Solution:def numDistinct(self, s: str, t: str) -> int:m, n len(s), len(t)if m < n:return 0dp [[0] * (n 1) for _ in range(m 1)]for i in range(m 1):dp[i][n] 1for i in range(m - 1, -1, -1):for j in range(n …

自适应容积卡尔曼滤波|(自适应CKF)的MATLAB源代码

介绍 容积卡尔曼滤波在理论上拥有比UKF更高的精度和稳定性&#xff0c;本自适应算法通过对观测残差的计算&#xff0c;在观测协方差R不准确或无法获得时&#xff0c;对R进行调节&#xff0c;以起到降低估计误差的作用。 模型 使用的是三维的非线性模型&#xff0c;经过适当修…

计算机网络导论

网络结构的演变 网状结构 最开始的网络&#xff0c;主机之间都是两两相连 好处 这样连接&#xff0c;好处是安全性比较高&#xff08;A与B之间的连线断了&#xff0c;可以绕一下C&#xff09;&#xff1b; 另外通信不需要互相等待&#xff08;没有中间交换设备&#xff0c;所…