【LangChain】理论及应用实战(7):LCEL

news2025/3/18 5:39:32

文章目录

  • 一、LCEL简介
  • 二、LCEL示例
    • 2.1 一个简单的示例
    • 2.2 RAG Search
  • 三、LCEL下核心组件(Prompt+LLM)的实现
    • 3.1 单链结构
    • 3.2 使用Runnables来连接多链结构
      • 3.2.1 连接多链
      • 3.2.2 多链执行与结果合并
      • 3.2.3 查询SQL
    • 3.3 自定义输出解析器
  • 四、LCEL添加Memory
    • 4.1 短时记忆
    • 4.2 长时记忆
  • 五、LCEL:Agent核心组件
    • 5.1 第一个Agent
    • 5.2 Agent案例2

一、LCEL简介

LangChain 表达式语言(LangChain Expression Language,简称 LCEL)是 LangChain 框架中的一个核心组件,旨在提供一种简洁、灵活的方式来定义和操作语言模型的工作流。LCEL 允许开发者以声明式的方式构建复杂的语言模型应用,而无需编写大量的样板代码。

在这里插入图片描述

以下是 LCEL 的主要优势:

  1. 异步、批处理和流支持:采用LCEL构建的任何链都将自动、完全的支持同步、异步、批处理和流等能力。这使得可以在Jupyter中使用同步接口创建链变得很容易,然后将其作为异步流接口进行公开。
  2. Fallbacks:由于LLMs的非确定性,使得具备优雅地处理错误的能力变得很重要。通过LCEL,可以轻松地为任何链添加Fallbacks。
  3. 并行性:由于LLMs应用涉及(有时长期的)API调用,因此支持并行处理很重要。使用LCEL,任何可以并行处理的组件都会自动并行处理。
  4. 无缝集成LangSmith:使用LCEL,所有步骤都会自动记录到LangSmith中,可以最大限度的实现可观察性和可调试性。从而尽量避免因为越来越复杂的链,带来的维护困难。

LCEL包含了多个核心组件,如Prompt, ChatModel, LLM, OutputParser, Retriever, Tool。其为了方便自定义Chain,创造了Runnable协议。Runnable协议适用于大多数组件,是一个标准接口,可以轻松地自定义链并以标准方式调用它们。

我们来看看官网对 Runnable类 的定义:A unit of work that can be invoked, batched, streamed, transformed and composed.
Key Methods(关键方法):

  • invoke/ainvoke: Transforms a single input into an output.
  • batch/abatch: Efficiently transforms multiple inputs into outputs.
  • stream/astream: Streams output from a single input as it’s produced.
  • astream_log: Streams output and selected intermediate results from an input.

在这里插入图片描述

LCEL核心组件的运行流程:
在这里插入图片描述

二、LCEL示例

LCEL使用“|”运算符链接LangChain应用的各个组件。

2.1 一个简单的示例

from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_ollama import OllamaLLM

prompt = PromptTemplate.from_template("tell me a short joke about {topic}")
model = OllamaLLM(model="llama3.1:8b")
output_parser = StrOutputParser()

chain = prompt | model | output_parser  # LCEL语法

result = chain.invoke({"topic": "ice cream"})
print(result)

输出如下:

Why did the ice cream go to therapy?

Because it was feeling a little "melted" under pressure!

可以看到,基于LCEL语法形式来定义Chain,比之前我们复写基类的方式来自定义Chain简单了很多。

2.2 RAG Search

主要是实现以下功能:

  1. 建立向量数据
  2. 使用RAG增强

首先安装依赖包:

pip install --upgrade --quiet langchain langchain-openai faiss-cpu tiktoken

示例代码:

from langchain_community.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableLambda, RunnablePassthrough
from langchain_ollama import OllamaLLM, OllamaEmbeddings


vectorstore = FAISS.from_texts(
    texts=["harrison worked at London"],
    embedding=OllamaEmbeddings(model="nomic-embed-text:latest")
)
retriever = vectorstore.as_retriever()

template = """Answer the question based only on the following context:
{context}

Question: {question}
"""

prompt = ChatPromptTemplate.from_template(template)

model = OllamaLLM(model="llama3.1:8b")

chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | model
    | StrOutputParser()
)

result = chain.invoke("where did harrison work?")
print(result)

输出如下:

London.

【RunnablePassthrough 介绍】,来自官网:https://python.langchain.com/api_reference/core/runnables/langchain_core.runnables.passthrough.RunnablePassthrough.html

  • Runnable to passthrough inputs unchanged or with additional keys. This Runnable behaves almost like the identity function, except that it can be configured to add additional keys to the output, if the input is a dict.
  • 翻译一下:RunnablePassthrough 可运行以不改变输入或使用其他键传递输入。这个Runnable的行为几乎类似于identity函数,除了如果输入是dict,它可以被配置为向输出添加额外的键。

我们对上面的代码做个简单的解释:

  • chain.invoke("where did harrison work?") :该函数接收到了变量 question = "where did harrison work?"
  • "question": RunnablePassthrough():使用变量 question 为 key,所以它的 value 接收到了 question 的取值,也就是 "where did harrison work?"

我们现在要求其用指定的语言回答我们的问题,可以对上面的代码进行修改,加入 language 相关的代码。如下:

from operator import itemgetter
from langchain_community.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableLambda, RunnablePassthrough
from langchain_ollama import OllamaLLM, OllamaEmbeddings


vectorstore = FAISS.from_texts(
    texts=["harrison worked at London"],
    embedding=OllamaEmbeddings(model="nomic-embed-text:latest")
)
retriever = vectorstore.as_retriever()

template = """Answer the question based only on the following context:
{context}

Question: {question}

Answer in the following language: {language}
"""

prompt = ChatPromptTemplate.from_template(template)

model = OllamaLLM(model="llama3.1:8b")

chain = (
    {
        "context": itemgetter("question") | retriever,
        "question": itemgetter("question"),
        "language": itemgetter("language"),
    }
    | prompt
    | model
    | StrOutputParser()
)

result = chain.invoke({"question": "where did harrison work?", "language": "Chinese"})
print(result)

输出如下:

伦敦

三、LCEL下核心组件(Prompt+LLM)的实现

基本构成:PromptTemplate / ChatPromptTemplate -> LLM / ChatModel -> OutputParser

3.1 单链结构

(1)一个简单的样例

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

prompt = ChatPromptTemplate.from_template("给我讲一个关于{topic}的笑话")
model = ChatOpenAI(
    temperature=0,
    model="gpt-3.5-turbo",
)

chain = prompt | model
print(chain.invoke({"topic": "狗熊"}))

输出如下:

有一只狗熊想去参加聚会,但他不知道自己应该穿什么衣服。于是,他问了邻居老猫:“喂,我要去参加聚会了,哪种服装比较适合呢?”老猫一脸严肃地说:“我不清楚,但是你最好不要穿那件黄色的衬衣,因为它太显眼了。”

(2)自定义停止输出符

# 自定义停止输出符为\n
chain = prompt | model.bind(stop=["\n"])
print(chain.invoke({"topic": "狗熊"}))

按照上述代码,输出在遇到换行符\n时就会停止输出。

【.bind 函数介绍】,来自官网:https://python.langchain.com/api_reference/core/runnables/langchain_core.runnables.passthrough.RunnablePassthrough.html

  • Bind arguments to a Runnable, returning a new Runnable. Useful when a Runnable in a chain requires an argument that is not in the output of the previous Runnable or included in the user input…
  • 翻译一下:将参数绑定到Runnable,返回一个新的Runnable。当链中的Runnable需要一个不在前一个Runnable的输出中或包含在用户输入中的参数时,这很有用。

(3)兼容OpenAI函数调用形式

functions = [
    {
        "name": "joke",
        "description": "讲笑话",
        "parameters": {
            "type": "object",
            "properties": {
                "setup": {"type": "string", "description": "笑话的开头"},
                "punchline": {
                    "type": "string",
                    "description": "爆梗的结尾",
                },
            },
            "required": ["setup", "punchline"],
        },
    }
]

chain = prompt | model.bind(function_call={"name": "joke"}, functions=functions)
chain.invoke({"topic": "西瓜"})

(4)输出解析器

StrOutputParser :使用 StrOutputParser 输出解析器后,输出为 str 格式。

from langchain_core.output_parsers import StrOutputParser

chain = prompt | model | StrOutputParser()
print(chain.invoke({"topic": "狗熊"}))

【StrOutputParser 介绍】,来自官网:https://python.langchain.com/api_reference/core/output_parsers/langchain_core.output_parsers.string.StrOutputParser.html

  • OutputParser that parses LLMResult into the top likely string.
  • 翻译一下:OutputParser将LLMResult解析为字符串的形式。

(5)与函数调用混合使用

from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser

chain = (
    prompt
    | model.bind(function_call={"name": "joke"})
    | JsonOutputFunctionsParser(key_name="setup")
)

print(chain.invoke({"topic": "狗熊"}))

这里,用 JsonOutputParser输出解析器后,输出为 json 格式。其中,key_name 可以指定输出的字段。

JsonOutputParser:Parse the output of an LLM call to a JSON object.

3.2 使用Runnables来连接多链结构

3.2.1 连接多链

from operator import itemgetter  # 获取可迭代对象中指定索引或键对应的元素
from langchain.schema import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_ollama import OllamaLLM

prompt1 = ChatPromptTemplate.from_template("{person}来自于哪个城市?")
prompt2 = ChatPromptTemplate.from_template(
    "{city}属于哪个省?用{language}来回答"
)

model = OllamaLLM(model="llama3.1:8b")

chain1 = prompt1 | model | StrOutputParser()

chain2 = (
    {"city": chain1, "language": itemgetter("language")}  # 获取invoke中的language
    | prompt2
    | model
    | StrOutputParser()
)

我们先来看看 chain1 的输出:

result = chain1.invoke({"person": "马化腾"})
print(result)
马化腾来自深圳。

chain1的输出会被当成chain2的输入,最后得到 chain2 的输出:

result = chain2.invoke({"person": "马化腾", "language": "中文"})
print(result)
马化腾来自于中国广东省深圳市。属于广东省。

3.2.2 多链执行与结果合并

用户的输入会在多个分支分别处理,最后合并结果。

唯物辩证链,给出示例代码:

from operator import itemgetter  # 获取可迭代对象中指定索引或键对应的元素
from langchain.schema import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_ollama import OllamaLLM


model = OllamaLLM(model="llama3.1:8b")

planner = (
    ChatPromptTemplate.from_template("生成一个关于{input}的论点")
    | model
    | StrOutputParser()
    | {"base_response": RunnablePassthrough()}
)

arguments_for = (
    ChatPromptTemplate.from_template("列出以下内容的优点或积极方面: {base_response}")
    | model
    | StrOutputParser()
)

arguments_against = (
    ChatPromptTemplate.from_template("列出以下内容的缺点或消极方面: {base_response}")
    | model
    | StrOutputParser()
)

final_responder = (
    ChatPromptTemplate.from_messages(
        [
            ("ai", "{original_response}"),
            ("human", "积极:\n{results_1}\n\n消极:\n{results_2}"),
            ("system", "根据评论生成最终的回复"),
        ]
    )
    | model
    | StrOutputParser()
)

chain = (
    planner
    | {
        "results_1": arguments_for,
        "results_2": arguments_against,
        "original_response": itemgetter("base_response"),
    }
    | final_responder
)

print(chain.invoke({"input": "生孩子"}))

输出如下:

女性生育孩子是一项艰难但美好的经历。她们承担着创造生命和将其带养大的责任,这需要付出巨大努力和牺牲,但也带来深厚的母爱感激和成就感。

女士,作为一个母亲,您一定会有很多不同的体验。但是,无论您是否在育儿中遇到挑战或困难,都应该庆幸自己有了孩子。因为生育孩子不仅给您带来了爱、责任和快乐,也让您有机会培养孩子,并为他们提供安全的家庭环境。

当然,育儿也会带来一些不容易改变的负担,如身体疼痛、情绪波动、生活方式的改变等。然而,您也可以从育儿中体验到成就感和责任感,不仅是为您的孩子提供照顾,还有通过育儿来发现自己的能力和潜力。

最终,女性生育孩子是一项充满挑战和责任的经历,但也是一个带来深厚母爱感激和成就感的机会。

用户的输入会在多个分支分别处理,最后合并结果。

3.2.3 查询SQL

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser

from langchain_community.utilities import SQLDatabase

template = """Based on the table schema below, write a SQL query that would answer the user's question:
{schema}

Question: 
"""

prompt = ChatPromptTemplate.from_template(template)

db = SQLDatabase.from_uri("sqlite:///Chinook.db")

model = ChatOpenAI(
    model="gpt-4",
    temperature=0,
)


def get_schema(_):
    return db.get_table_info()


sql_response = (
    RunnablePassthrough.assign(schema=get_schema)
    | prompt
    | model.bind(stop=["\nSQLResult:"])
    | StrOutputParser()
)

sql_response.invoke({"question": "How many artists are there?"})

输出如下:

SELECT COUNT(*) FROM Artist;

可以看到上面示例中输出的是 SQL 查询语句,并没有给出自然语言的结果。下面我们将代码进行一个简单的改造:

template = """Based on the table schema below, write a SQL query that would answer the user's question:
{schema}

Question: {question}
SQL Query: {query}
SQL Response: {response}
"""

prompt_response = ChatPromptTemplate.from_template(template)
full_chain = (
    RunnablePassthrough.assign(query=sql_response).assign(
        schema=get_schema,
        response=lambda x: db.run(x["query"]),
    )
    | prompt_response
    | model
)
full_chain.invoke({"question": "How many artists are there?"})

输出如下:

There are 275 artists.

3.3 自定义输出解析器

Python编程助手,此处省略。感兴趣的同学可以查看原资料。

四、LCEL添加Memory

4.1 短时记忆

  • 基于 ConversationBufferMemory
from operator import itemgetter
from langchain.memory import ConversationBufferMemory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnableLambda, RunnablePassthrough
from langchain_openai import ChatOpenAI

model = ChatOpenAI()
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "你是一个乐于助人的机器人"),
        MessagesPlaceholder(variable_name="history"),
        ("human", "{input}"),
    ]
)

memory = ConversationBufferMemory(return_messages=True)

chain = (
    RunnablePassthrough.assign(
        history=RunnableLambda(memory.load_memory_variables) | itemgetter("history")
    )
    | prompt
    | model
)

inputs = {"input": "你好我是Mary"}
response = chain.invoke(inputs)

# 保存记忆
memory.save_context(inputs, {'output': response.content})
memory.load_memory_variables({})

4.2 长时记忆

  • 基于 Redis
from langchain_community.chat_message_histories import RedisChatMessageHistory
from langchain_community.chat_models import ChatOpenAI
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory

# 基于Redis保存记忆
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "你是一个擅长{ability}的助手"),
        MessagesPlaceholder(variable_name="history"),
        ("human", "{question}"),
    ]
)

chain = prompt | ChatOpenAI(model="gpt-4-1106-preview", temperature=0)

chain_with_history = RunnableWithMessageHistory(
    chain,
    # 使用redis存储聊天记录
    lambda session_id: RedisChatMessageHistory(session_id, url="redis://localhost:6397/0"),
    input_messages_key="question",
    history_messages_key="history",
)

# 每次调用都会保存聊天记录,需要有对应的session_id
chain_with_history.invoke(
    {
        "ability": "历史", 
        "question": "中国建都时间最长的城市是哪个?"
    },
    config={
        "configurable": {"session_id": "Mary"}
    }
)

这里,我们使用了RunnableWithMessageHistory 实现了基于Redis 实现Memory的长时记忆。

五、LCEL:Agent核心组件

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

5.1 第一个Agent

使用 create_openai_functions_agent 函数直接定义一个简单的 OpenAI 风格的agent,示例代码:

from langchain_openai import ChatOpenAI
from langchain import hub
from langchain.agents import load_tools
from langchain.agents import create_openai_functions_agent  # 不同的agent有不同的创建方式
from langchain.agents import AgentExecutor

# 创建LLM
llm = ChatOpenAI(model_name="gpt-4", temperature=0)

# 定义agent的prompt
# https://smith.langchain.com/hub/hwchase17/openai-functions-agent
prompt = hub.pull("hwchase17/openai-functions-agent")

# 定义工具,加载预制的工具,注意有的工具需要提供LLM
tools = load_tools(["llm-math"], llm=llm)

# 创建agent
agent = create_openai_functions_agent(llm, tools, prompt)

# 定义agent的执行器,这里注意与老版本的不同
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

agent_executor.invoke({"input": "你好"})

5.2 Agent案例2

实现如下功能:

  • 中间步骤处理
  • 提示词
  • 模型配置(停止符必要的话)
  • 输出解析器
from langchain import hub
from langchain.agents import AgentExecutor, tool
from langchain.agents.output_parsers import XMLAgentOutputParser
from langchain_openai import ChatOpenAI


# 配置模型
model = ChatOpenAI(
    model="gpt-4-1106-preview",
    temperature=0,
)


# 使用工具
@tool
def search(query: str) -> str:
    """ 当需要了解最新的天气的时候,才会使用这个工具。 """
    return "晴朗, 32摄氏度, 无风"


tool_list = [search]

# 提示词模板
# https://smith.langchain.com/hub
# Get the prompt to use - you can modify this!
prompt = hub.pull("hwchase17/xml-agent-convo")


def convert_intermediate_steps(intermediate_steps):
    log = ""
    for action, observation in intermediate_steps:
        log += (
            f"<tool>{action.tool}</tool><tool_input>{action.tool_input}"
            f"></tool_input><observation>{observation}</observation>"
        )
    return log


# 将工具列表插入模板中
def convert_tools(tools):
    return "\n".join([f"{tool.name}: {tool.description}" for tool in tools])


# 定义agent
agent = (
    {
        "input": lambda x: x["input"],
        "agent_scratchpad": lambda x: convert_intermediate_steps(x["intermediate_steps"])
    },
    prompt.partial(tools=convert_tools(tool_list)),
    model.bind(stop=["</tool_input>", "</final_answer>"]),
    XMLAgentOutputParser()
)

# 执行agent
agent_executor = AgentExecutor(agent=agent, tools=tool_list, verbose=True)
result = agent_executor.invoke({"input": "北京今天的天气如何?"})
print(result)

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

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

相关文章

ai本地化 部署常用Ollama软件

现在用最简单的方式介绍一下 Ollama 的作用和用法&#xff1a; Ollama 是什么&#xff1f; Ollama 是一个让你能在自己电脑上免费运行大型语言模型&#xff08;比如 Llama 3、Mistral 等&#xff09;的工具。 相当于你本地电脑上有一个类似 ChatGPT 的 AI&#xff0c;但完全…

vllm部署QwQ32B(Q4_K_M)

vllm部署QwQ32B(Q4_K_M) Ollama是一个轻量级的开源LLM推理框架&#xff0c;注重简单易用和本地部署&#xff0c;而VLLM是一个专注于高效推理的开源大型语言模型推理引擎&#xff0c;适合开发者在实际应用中集成和使用。两者的主要区别在于Ollama更注重为用户提供多种模型选择和…

企业内网监控软件的选型与应用:四款主流产品的深度剖析

在数字化办公的时代背景下&#xff0c;企业内部网络管理的重要性愈发显著。对于企业管理者而言&#xff0c;如何精准掌握员工工作状态&#xff0c;保障网络安全与工作效率&#xff0c;已成为亟待解决的关键问题。本文将深入剖析四款主流企业内网监控软件&#xff0c;探讨其功能…

Qt窗口控件之字体对话框QFontDialog

字体对话框QFontDialog QFontDialog 是 Qt 内置的字体对话框&#xff0c;用户能够在这里选择字体的样式、大小&#xff0c;设置加粗和下划线并将结果作为返回值返回。QFontDialog 最好使用其提供的静态函数实例化匿名对象&#xff0c;并获取返回值最为用户选择字体设置的结果。…

Qt QML实现视频帧提取

## 前言 视频帧率&#xff08;Frame Rate&#xff09;是指视频播放时每秒显示的画面帧数&#xff0c;通常用fps&#xff08;Frames Per Second&#xff09;来表示。视频是由一系列静止的图像帧组成的&#xff0c;而视频帧率则决定了这些图像帧在单位时间内播放的速度。较高的视…

在 Ubuntu 服务器上使用宝塔面板搭建博客

&#x1f4cc; 介绍 在本教程中&#xff0c;我们将介绍如何在 Ubuntu 服务器 上安装 宝塔面板&#xff0c;并使用 Nginx PHP MySQL 搭建一个博客&#xff08;如 WordPress&#xff09;。 主要步骤包括&#xff1a; 安装宝塔面板配置 Nginx PHP MySQL绑定域名与 SSL 证书…

有了大语言模型还需要 RAG 做什么

一、百炼平台简介 阿里云的百炼平台就像是一个超级智能的大厨房&#xff0c;专门为那些想要做出美味AI大餐的企业和个人厨师准备的。你不需要从头开始做每一道菜&#xff0c;因为这个厨房已经为你准备了很多预制食材&#xff08;预训练模型&#xff09;&#xff0c;你可以根据…

【从0到1搞懂大模型】RNN基础(4)

先说几个常用的可以下载数据集的地方 平台&#xff1a;kaggle&#xff08;https://www.kaggle.com/datasets&#xff09; 和鲸社区&#xff08;https://www.heywhale.com/home&#xff09; 阿里天池&#xff08;https://tianchi.aliyun.com/&#xff09; 其他&#xff1a;海量公…

【第K小数——可持久化权值线段树】

题目 代码 #include <bits/stdc.h> using namespace std;const int N 1e5 10;int a[N], b[N]; int n, m, len; int rt[N], idx; // idx 是点分配器struct node {int l, r;int s; } tr[N * 22];int getw(int x) {return lower_bound(b 1, b len 1, x) - b; }int bui…

本地部署Deep Seek-R1,搭建个人知识库——笔记

目录 一、本地部署 DeepSeek - R1 1&#xff1a;安装Ollama 2&#xff1a;部署DeepSeek - R1模型 3&#xff1a;安装Cherry Studio 二、构建私有知识库 一、本地部署 DeepSeek - R1 1&#xff1a;安装Ollama 1.打开Ollama下载安装 未科学上网&#xff0c;I 先打开迅雷再下…

【软考-架构】5.3、IPv6-网络规划-网络存储-补充考点

✨资料&文章更新✨ GitHub地址&#xff1a;https://github.com/tyronczt/system_architect 文章目录 IPv6网络规划与设计建筑物综合布线系统PDS&#x1f4af;考试真题第一题第二题 磁盘冗余阵列网络存储技术其他考点&#x1f4af;考试真题第一题第二题 IPv6 网络规划与设计…

fastapi+angular外卖系统

说明&#xff1a; fastapiangular外卖系统 1.美食分类&#xff08;粥&#xff0c;粉&#xff0c;面&#xff0c;炸鸡&#xff0c;炒菜&#xff0c;西餐&#xff0c;奶茶等等&#xff09; 2.商家列表 &#xff08;kfc&#xff0c;兰州拉面&#xff0c;湘菜馆&#xff0c;早餐店…

鸿蒙路由 HMRouter 配置及使用 三 全局拦截器使用

1、前期准备 简单封装一个用户首选项的工具类 import { preferences } from "kit.ArkData";// 用户首选项方法封装 export class Preferences {private myPreferences: preferences.Preferences | null null;// 初始化init(context: Context, options: preference…

计算机视觉——深入理解卷积神经网络与使用卷积神经网络创建图像分类算法

引言 卷积神经网络&#xff08;Convolutional Neural Networks&#xff0c;简称 CNNs&#xff09;是一种深度学习架构&#xff0c;专门用于处理具有网格结构的数据&#xff0c;如图像、视频等。它们在计算机视觉领域取得了巨大成功&#xff0c;成为图像分类、目标检测、图像分…

永磁同步电机无速度算法--拓展卡尔曼滤波器

一、原理介绍 以扩展卡尔曼滤波算法为基础&#xff0c;建立基于EKF算法的估算转子位置和转速的离散模型。 实时性是扩展卡尔曼滤波器的一种特征&#xff0c;所以它可实时跟踪系统的状态并进行有效的输出&#xff0c;同时&#xff0c;它可以减少干扰、抑制噪声&#xff0c;其效…

【CF】Day9——Codeforces Round 953 (Div. 2) BCD

B. New Bakery 题目&#xff1a; 思路&#xff1a; 被标签害了&#xff0c;用什么二分&#xff08; 很简单的思维题&#xff0c;首先如果a > b&#xff0c;那么全选a就行了&#xff0c;还搞啥活动 否则就选 b - a 天来搞活动&#xff0c;为什么&#xff1f; 首先如果我…

harmonyOS NEXT开发与前端开发深度对比分析

文章目录 1. 技术体系概览1.1 技术栈对比1.2 生态对比 2. 开发范式比较2.1 鸿蒙开发范式2.2 前端开发范式 3. 框架特性对比3.1 鸿蒙 Next 框架特性3.2 前端框架特性 4. 性能优化对比4.1 鸿蒙性能优化4.2 前端性能优化 5. 开发工具对比5.1 鸿蒙开发工具5.2 前端开发工具 6. 学习…

Unity小框架之单例模式基类

单例模式&#xff08;Singleton Pattern&#xff09;是一种常用的创建型设计模式&#xff0c;其核心目标是确保一个类只有一个实例&#xff0c;并提供一个全局访问点。它常用于需要控制资源访问、共享配置或管理全局状态的场景&#xff08;如数据库连接池、日志管理器、应用配置…

cesium 实现万级管网数据渲染,及pickImageryLayerFeatures原生方法改写

需求背景解决效果getFeatureInfo 需求背景 在用 geoserver 渲染图层时&#xff0c;会自动触发 GetFeatureInfo &#xff0c;与服务器通信&#xff0c;在万级海量数据渲染下&#xff0c;这个性能消耗就可以感受到了 需要考虑的点&#xff1a; 1.通过enablePickFeatures&#xf…

基于金融产品深度学习推荐算法详解【附源码】

深度学习算法说明 1、简介 神经网络协同过滤模型(NCF) 为了解决启发式推荐算法的问题&#xff0c;基于神经网络的协同过滤算法诞生了&#xff0c;神经网络的协同过滤算法可以 通过将用户和物品的特征向量作为输入&#xff0c;来预测用户对新物品的评分&#xff0c;从而解决…