LangChain:模型 I/O 封裝使用解析和感觸

目錄

模型 API:LLM vs. ChatModel

OpenAI 模型封裝

多輪對話 Session 封裝

換個國產模型

模型的輸入與輸出

Prompt 模板封裝

PromptTemplate

ChatPromptTemplate

MessagesPlaceholder

從文件加載 Prompt 模板

TXT模板

Yaml模板

Json模板

輸出封裝 OutputParser

?編輯Pydantic (JSON) Parser

Auto-Fixing Parser

總結

關鍵點提取

使用感觸


????????本文將繼續延續Langchain專欄文章,本文將講解Langchain的模型 I/O 封裝。Langchain將不同的模型,統一封裝成一個接口,方便更換模型而不用重構代碼。

? ? ? ? 對Langchain能做什么暫時還不了解的話可以移步先看這篇文章

直通車:LangChain:大模型框架的深度解析與應用探索-CSDN博客

模型 API:LLM vs. ChatModel

pip install --upgrade langchain # 安裝最新版本
pip install --upgrade langchain-openai # v0.1.0新增的底包

OpenAI 模型封裝

? ? ? ? 最基本的調度封裝

from langchain_openai import ChatOpenAIllm = ChatOpenAI(model="gpt-3.5-turbo")  # 默認是gpt-3.5-turbo
response = llm.invoke("你是誰")
print(response.content)

多輪對話 Session 封裝

# 加載 .env 到環境變量
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())from langchain_openai import ChatOpenAIllm = ChatOpenAI()  # 默認是gpt-3.5-turbofrom langchain.schema import (AIMessage, #等價于OpenAI接口中的assistant roleHumanMessage, #等價于OpenAI接口中的user roleSystemMessage #等價于OpenAI接口中的system role
)
messages = [SystemMessage(content="從現在開始你叫AI助手-小京。"),HumanMessage(content="我是CSDN的一名博主,我叫Muller"),AIMessage(content="歡迎!"),HumanMessage(content="我是誰")
]
response = llm.invoke(messages)
print(response.content)

通過模型封裝,實現不同模型的統一接口調用

????????SystemMessage 描述你的大模型角色、功能、作用等等;

????????HumanMessage 用戶輸入的內容?

????????AIMessage 大模型回答

? ? ? ? 通過這個Message數組就能表示一個摘要,原生的Openai通過一個json數組,每一輪都一個任務一個content來去表示一個對話上下文,那么在langchain的框架下,可以通過它定義的結構來去表示一個對話。然后呢,我們還是把這個對話通過invoke接口來傳給大模型,就實現了這一種多輪對話的交互。

????????和Openai一樣,對話歷史還是需要我們自行進行管理的 ,具體langchain這個框架下需要如何管理對話歷史后面再詳細講解。也就是說它不會自動幫我們填充里面的信息,例如你不附上content,它返回的實際上就是一個ai message ,如果你要維護這一個上下文的話,那你就需要將這個ai message填到數組里去發起下輪,就是這么一個邏輯。

換個國產模型

pip install qianfan
# 加載 .env 到環境變量
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())# 其它模型分裝在 langchain_community 底包中
from langchain_community.chat_models import QianfanChatEndpoint
from langchain.schema import HumanMessage
import os
qianfan = QianfanChatEndpoint(qianfan_ak=os.getenv('ERNIE_CLIENT_ID'),qianfan_sk=os.getenv('ERNIE_CLIENT_SECRET')
)messages = [HumanMessage(content="你是誰")
]response = qianfan.invoke(messages)
print(response.content)

????????通過這么一個簡單的例子就能體會到模型的封裝的一個好處就是不同的模型我都用統一的接口去調用,如果都是openai我就不用管你是3.5還是4,我都統一用這個接口,甚至我換一個模型,還是這樣一個結構去調用,我接口是不用變的。

模型的輸入與輸出

Prompt 模板封裝

PromptTemplate

? ? ? ? 對一段文字生成了一個提示詞模板。提供了一個函數將字符串轉成一個模板。

from langchain.prompts import PromptTemplate
print("====模板====")
template = PromptTemplate.from_template("幫我解釋一下這個成語:{idiom}")
print(template)
print("====提示詞====")
print(template.format(idiom='繁花似錦'))

? ? ? ? ?模板包含兩個元素,一個是模板內容,另一個是模板內代填的變量給提取出來。

====模板====
input_variables=['idiom'] template='幫我解釋一下這個成語:{idiom}'
====提示詞====
#幫我解釋一下這個成語:繁花似錦

ChatPromptTemplate

? ? ? ? 提供了把一個多輪對話上下文整個變成一個多輪模板的形式,用模板表示的對話上下文。

# 加載 .env 到環境變量
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())from langchain.prompts import ChatPromptTemplate
from langchain.prompts.chat import SystemMessagePromptTemplate, HumanMessagePromptTemplate
from langchain_openai.chat_models import ChatOpenAI# 定義聊天提示詞
template = ChatPromptTemplate.from_messages([SystemMessagePromptTemplate.from_template("你是一名{subject}老師,你的名字叫{name}"),HumanMessagePromptTemplate.from_template("{query}"),]
)llm = ChatOpenAI()
# 生成大模型輸入
prompt = template.format_messages(subject="語文",name="muller",query="告訴我你是誰,然后幫我解釋一下這個成語:繁花似錦")response = llm.invoke(prompt)
print(response.content)
#你好,我是一名語文老師,名叫Muller。#繁花似錦是一個形容詞成語,用來形容景色美麗、繁華盛開的樣子。其中,“繁花”指的是許多花朵,而“似#錦”則表示美麗多彩、如錦繡般的樣子。
#這個成語常用來形容春天或夏天花朵盛開的景象,也可以用來形容其他美麗的景色或事物。它表達了繁花##絢爛的美麗,給人以愉悅和喜悅的感覺。

MessagesPlaceholder

? ? ? ? 通過MessagesPlaceholder把多輪對話整個變成模板,它的作用就是解決逐輪對話寫入麻煩的問題,例如上述代碼,需要不斷在from_messages填充多個元素表示多輪對話,當歷史對話發生變化需重新填充,因為對話歷史本身就是一個Message List,那么就可以直接把message List填寫到對話的中間,如下列代碼MessagesPlaceholder(variable_name="歷史對話") 留了一個多輪的占位符? ,給該占位符取了一個名字為:“歷史對話”。

# 加載 .env 到環境變量
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())from langchain.prompts import (ChatPromptTemplate,MessagesPlaceholder,
)
from langchain.prompts.chat import  HumanMessagePromptTemplate
from langchain_openai.chat_models import ChatOpenAI
llm = ChatOpenAI()# 定義一個用戶對話模板
human_message_template = HumanMessagePromptTemplate.from_template("幫我解釋一下這個成語: {idiom}.")# 定義當前聊天提示詞,傳參 歷史聊天記錄和用戶對話模板
chat_prompt = ChatPromptTemplate.from_messages(# variable_name 是 message placeholder 在模板中的變量名# 用于在賦值時使用[MessagesPlaceholder(variable_name="歷史對話"), human_message_template]
)#定義大模型角色說明,AI、Human、System
from langchain_core.messages import AIMessage, HumanMessage,SystemMessage#大模型角色說明
system_message = SystemMessage(content="你是一名語文老師,你的名字叫muller")
#用戶對話1
human_message = HumanMessage(content="告訴我你是誰?")
#大模型回答1
ai_message = AIMessage(content="我是一名語文老師,名叫Muller")# 生成大模型輸入
messages = chat_prompt.format_prompt(# 對 "conversation" 和 "language" 賦值歷史對話=[system_message,human_message, ai_message], idiom="繁花似錦"
)print(messages.to_messages())result = llm.invoke(messages)
print(result.content)# 繁花似錦是一個形容詞成語,用來形容景色美麗、繁華盛開的樣子。其中,“繁花”指的是許多花朵,而# “似錦”則表示美麗多彩、如錦繡般的樣子。# 這個成語常用來形容春天或夏天花朵盛開的景象,也可以用來形容其他美麗的景色或事物。它表達了繁花# 絢爛的美麗,給人以愉悅和喜悅的感覺。

從文件加載 Prompt 模板

? ? ? ? 我們在開發模式可以通過在代碼中通過字符串定義模板,但實際生產中則需要將代碼和prompt進行分離,這樣便于整個項目的管理。Langchain也提供了像SK一樣的能力,可以支持加載一個文件為Prompt模板,例如Txt加載方式是將字符串放到了txt文件中。?

TXT模板

幫我解釋一下這個成語:{idiom}
from langchain.prompts import PromptTemplatetemplate = PromptTemplate.from_file("example_prompt_template.txt")
print("===Template===")
print(template)
print("===Prompt===")
print(template.format(topic='繁花似錦'))# ===Template===
# input_variables=['idiom'] template='幫我解釋一下這個成語:{idiom}'
#===Prompt===
# 幫我解釋一下這個成語:繁花似錦

Yaml模板

    _type: promptinput_variables:["subject", "idiom"]template: 你是一名{subject}老師,幫我解釋一下這個成語:{idiom}
from langchain.prompts import load_prompt
prompt = load_prompt("simple_prompt.yaml")
print(prompt.format(subject="語文", idiom="繁花似錦"))

Json模板

{"_type": "prompt","input_variables": ["idiom"],"template": "幫我解釋一下這個成語:{idiom}"
}
from langchain.prompts import load_prompt
prompt = load_prompt("simple_prompt.json")
print(prompt.format(subject="語文", idiom="繁花似錦"))

輸出封裝 OutputParser

????????自動把 LLM 輸出的字符串按指定格式加載,如果通過規定格式輸出,對程序解析有好處。

? ? ? ? LangChain 內置的 OutputParser 包括但不僅限于:

  • ListParser
  • DatetimeParser
  • EnumParser
  • JsonOutputParser
  • PydanticParser
  • XMLParser

詳細用例直通車:Output Parsers | 🦜?🔗 LangChain

Pydantic (JSON) Parser

? ? ? ? 我們可以使用python的Pydantic類,去定義一個特定的結構,且這個結構是帶含義描述的結構體,然后這個結構體我們可以從JSON結構中轉換成它,也可以將它轉換成JSON格式。而Langchain就是提供了解析Pydantic結構對象的能力。

? ? ? ? 打個比方有個日期類,日期有“年”、“月”、“日” 和 “公元前/公元后” 這四個字段組成。假設我們需要一個這個類的對象,那么我們就可以通過依據Pydantic類格式將它描述出來,然后用Langchain提供的Pydantic解析器讓大模型按這個格式輸出結果,然后用Parser從大模型的結果里去解析出這個對象來,后面就可以讓依據程序邏輯使用這個結構化的結果了。

? ? ? ? 具體例子如下:一般描述類屬性對象已具備基本能力,但如果你需要校驗對象值的合法性,就需要用到Pydantic的能力,即@validator和@staticmethod的注解內容。?

# 定義Pydantic結構
from langchain_core.pydantic_v1 import BaseModel, Field, validator
from typing import List, Dict# 定義你的輸出對象class Date(BaseModel):year: int = Field(description="Year")month: int = Field(description="Month")day: int = Field(description="Day")era: str = Field(description="BC or AD")# ----- 可選機制 --------# 你可以添加自定義的校驗機制@validator('month')def valid_month(cls, field):if field <= 0 or field > 12:raise ValueError("月份必須在1-12之間")return field@validator('day')def valid_day(cls, field):if field <= 0 or field > 31:raise ValueError("日期必須在1-31日之間")return field@validator('day', pre=True, always=True)def valid_date(cls, day, values):year = values.get('year')month = values.get('month')# 確保年份和月份都已經提供if year is None or month is None:return day  # 無法驗證日期,因為沒有年份和月份# 檢查日期是否有效if month == 2:if cls.is_leap_year(year) and day > 29:raise ValueError("閏年2月最多有29天")elif not cls.is_leap_year(year) and day > 28:raise ValueError("非閏年2月最多有28天")elif month in [4, 6, 9, 11] and day > 30:raise ValueError(f"{month}月最多有30天")return day@staticmethoddef is_leap_year(year):if year % 400 == 0 or (year % 4 == 0 and year % 100 != 0):return Truereturn False
#使用Pydantic
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAIfrom langchain.output_parsers import PydanticOutputParsermodel_name = 'gpt-3.5-turbo'
temperature = 0
model = ChatOpenAI(model_name=model_name, temperature=temperature)# 根據Pydantic對象的定義,構造一個OutputParser
parser = PydanticOutputParser(pydantic_object=Date)template = """提取用戶輸入中的日期。
{format_instructions}
用戶輸入:
{query}"""prompt = PromptTemplate(template=template,input_variables=["query"],# 直接從OutputParser中獲取輸出描述,并對模板的變量預先賦值partial_variables={"format_instructions": parser.get_format_instructions()}
)print("====Format Instruction=====")
print(parser.get_format_instructions())query = "2024年五月1日即將實施的《非銀行支付機構監督管理條例》,將非銀行支付機構及其業務活動進一步納入法治化軌道進行監管。"
model_input = prompt.format_prompt(query=query)print("====Prompt=====")
print(model_input.to_string())output = model(model_input.to_messages())
print("====模型原始輸出=====")
print(output)
print("====Parse后的輸出=====")
date = parser.parse(output.content)
print(date)
====Format Instruction=====
The output should be formatted as a JSON instance that conforms to the JSON schema below.As an example, for the schema {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]}
the object {"foo": ["bar", "baz"]} is a well-formatted instance of the schema. The object {"properties": {"foo": ["bar", "baz"]}} is not well-formatted.Here is the output schema:
```
{"properties": {"year": {"title": "Year", "description": "Year", "type": "integer"}, "month": {"title": "Month", "description": "Month", "type": "integer"}, "day": {"title": "Day", "description": "Day", "type": "integer"}, "era": {"title": "Era", "description": "BC or AD", "type": "string"}}, "required": ["year", "month", "day", "era"]}
```
====Prompt=====
提取用戶輸入中的日期。
The output should be formatted as a JSON instance that conforms to the JSON schema below.As an example, for the schema {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]}
the object {"foo": ["bar", "baz"]} is a well-formatted instance of the schema. The object {"properties": {"foo": ["bar", "baz"]}} is not well-formatted.Here is the output schema:
```
{"properties": {"year": {"title": "Year", "description": "Year", "type": "integer"}, "month": {"title": "Month", "description": "Month", "type": "integer"}, "day": {"title": "Day", "description": "Day", "type": "integer"}, "era": {"title": "Era", "description": "BC or AD", "type": "string"}}, "required": ["year", "month", "day", "era"]}
```
用戶輸入:
2024年五月1日即將實施的《非銀行支付機構監督管理條例》,將非銀行支付機構及其業務活動進一步納入法治化軌道進行監管。====模型原始輸出=====
content='{"year": 2024, "month": 5, "day": 1, "era": "AD"}'
====Parse后的輸出=====
year=2024 month=5 day=1 era='AD'

Auto-Fixing Parser

????????Openai不一定保證百分之百每一次結果輸出的格式你要的能一模一樣,例如返回的內容都是中文或json格式錯誤等問題,所以大模型輸出的結果本身存在一定的不確定性,那就導致如果格式錯了,那么OutputParser解析會失敗,為了失敗了能夠再次嘗試去自動修復這個格式上的錯誤,重新解析,Langchain還提供了Auto-Fixing Paser。

? ? ? ? 核心它完成了大模型輸出的結果是錯的,導致解析失敗時,它會嘗試修改格式再做一次自動的解析。定義這塊功能需要將原始的Parser給它,同時還需要給它大模型對象。

# 加載 .env 到環境變量
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())from langchain_core.pydantic_v1 import BaseModel, Field, validator# 定義你的輸出對象
class Date(BaseModel):year: int = Field(description="Year")month: int = Field(description="Month")day: int = Field(description="Day")era: str = Field(description="BC or AD")# ----- 可選機制 --------# 你可以添加自定義的校驗機制@validator('month')def valid_month(cls, field):if field <= 0 or field > 12:raise ValueError("月份必須在1-12之間")return field@validator('day')def valid_day(cls, field):if field <= 0 or field > 31:raise ValueError("日期必須在1-31日之間")return field@validator('day', pre=True, always=True)def valid_date(cls, day, values):year = values.get('year')month = values.get('month')# 確保年份和月份都已經提供if year is None or month is None:return day  # 無法驗證日期,因為沒有年份和月份# 檢查日期是否有效if month == 2:if cls.is_leap_year(year) and day > 29:raise ValueError("閏年2月最多有29天")elif not cls.is_leap_year(year) and day > 28:raise ValueError("非閏年2月最多有28天")elif month in [4, 6, 9, 11] and day > 30:raise ValueError(f"{month}月最多有30天")return day@staticmethoddef is_leap_year(year):if year % 400 == 0 or (year % 4 == 0 and year % 100 != 0):return Truereturn Falsefrom langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAIfrom langchain.output_parsers import PydanticOutputParsermodel_name = 'gpt-3.5-turbo'
temperature = 0
model = ChatOpenAI(model_name=model_name, temperature=temperature)# 根據Pydantic對象的定義,構造一個OutputParser
parser = PydanticOutputParser(pydantic_object=Date)template = """提取用戶輸入中的日期。
{format_instructions}
用戶輸入:
{query}"""prompt = PromptTemplate(template=template,input_variables=["query"],# 直接從OutputParser中獲取輸出描述,并對模板的變量預先賦值partial_variables={"format_instructions": parser.get_format_instructions()}
)query = "2024年五月1日即將實施的《非銀行支付機構監督管理條例》,將非銀行支付機構及其業務活動進一步納入法治化軌道進行監管。"
model_input = prompt.format_prompt(query=query)output = model(model_input.to_messages())# 解決output輸出盡量可控
from langchain.output_parsers import OutputFixingParsernew_parser = OutputFixingParser.from_llm(parser=parser, llm=ChatOpenAI(model="gpt-3.5-turbo"))# 因為這個例子比較簡單,大模型比較難出錯,這里手動替換成錯誤值
output = output.content.replace("5", "五月")
print("===格式錯誤的Output===")
print(output)
try:date = parser.parse(output)
except Exception as e:print("===出現異常===")print(e)# 用OutputFixingParser自動修復并解析
date = new_parser.parse(output)
print("===重新解析結果===")
print(date)
===格式錯誤的Output===
{"year": 2024, "month": 五月, "day": 1, "era": "AD"}
===出現異常===
Failed to parse Date from completion {"year": 2024, "month": 五月, "day": 1, "era": "AD"}. Got: Expecting value: line 1 column 25 (char 24)
===重新解析結果===
year=2024 month=5 day=1 era='AD'

總結

關鍵點提取

本文關鍵內容提取:

????????1、LangChain 統一封裝了各種模型的調用接口,包括補全型和對話型兩種;
????????2、LangChain 提供了 PromptTemplate 類,可以自定義帶變量的模板;
????????3、LangChain 提供了一些列輸出解析器,用于將大模型的輸出解析成結構化對象;額外帶有自動修復功能;
????????4、模型屬于 LangChain 中較為優秀的部分;美中不足的是 OutputParser 自身的 Prompt 維護在代碼中,耦合度較高。

使用感觸

從這段時間接觸Langchain,從使用角度上感觸如下:

  • Langchain對大模型的封裝是可用的。對此結論的評價標準是假設即使不用Langchian的情況下,自己去設計一套應用,同樣對大模型調用接口上也進行一個類似抽象,自己是否能保證從chatgpt模型切到claude模型后不會造成代碼大規模的調整,在這個嘗試上我發現是Langchain可行的,并且所調整的代碼極少。
  • Langchain對于PromptTemplate的封裝在早期的確實很粗糙,但現在的版本基本達到可用狀態。不難看出從字符串加載、從文件加載,甚至嵌套方式加載目前都已具備了,所以PromptTemplate這個功能從個人而言并沒有發現特別大的弊端導致不推薦的情況,因此可以認為它也是一個可用的模塊,而且即使你不用Langchain來管理,你也可以來參考它這種模式,就是將Prompt和代碼分開來管理,以完成填槽的邏輯。
  • OutputParser情況卻沒有很理想,首先它是基本可用的,例如JsonParser這些基礎解析是可用的,但Auto-Fixing Parser則需要注意的就是它自己內部是有Prompt模板的。它的Prompt模板寫的如何,在你的這個業務中是否通用?是否未來對所有的模型都兼容?這些是需要酌情考慮使用的。在使用這些非代碼的功能,即不確定的功能的時候,需要注意的是不能因為模型變化了結果卻不是最優解的情況,例如當初是基于gpt4編寫生產好用,而更換到gpt5了它的這個模板就不是最優解了,或導致該功能就失效了。這里我更推薦的一個做法就是使用這些內置Prompt模板功能或不確定的代碼時候,強烈推薦能夠單獨將這部分Prompt抽出來管理,就是把Prompt抽出來去維護,哪怕真的要用它寫的功能也要拷貝出來單獨維護,這樣的好處在于未來你的模型換了,出現非最優解時,你能知道改哪里,好導致你不用梳理整個邏輯改整塊代碼。

????????

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/11046.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/11046.shtml
英文地址,請注明出處:http://en.pswp.cn/web/11046.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mediasoup源碼(一)編譯及部署

基本介紹 mediasoup是一個sfu架構的流媒體服務器&#xff0c;讀者可以根據需要選擇不同的編譯方式。如果只需要學習c流媒體傳輸部分&#xff0c;則選擇mediasoup&#xff0c;如果需要學習mediasoup整個demo&#xff0c;并做演示&#xff0c;則可以選擇mediasoup-demo&#xff…

is和==的關系

Python中is和的關系 is判斷兩個變量是不是指的是同一個內存地址&#xff0c;也就是通過id()函數判斷 判斷兩個變量的值是不是相同 a [1, 2, 3, 4] b [1, 2, 3, 4] print(id(a)) # 2298268712768 print(id(b)) # 2298269716992 print(a is b) # False print(a b) # Tr…

目標檢測標注工具Labelimg安裝與使用

目錄 一、安裝Labelimg與打開 二、使用 1、基本功能介紹 2、快捷鍵 3、狀態欄的工具 三、附錄 1、YOLO模式創建標簽的樣式 2、create ML模式創建標簽的樣式 3、PascalVOC模式創建標簽的樣式 一、安裝Labelimg與打開 labelimg是一款開源的數據標注工具&#xff0c;可以…

51基于單片機的溫室大棚系統設計

設計摘要&#xff1a; 本設計旨在基于51單片機和藍牙技術&#xff0c;實現一個功能完善的溫室大棚系統。該系統具備以下主要功能&#xff1a;首先&#xff0c;通過連接的顯示屏能夠實時地顯示當前的溫度和濕度信息&#xff0c;方便用戶了解溫室內的環境變化。其次&#xff0c;…

ctfshow web271--web273

web271 laravel5.7反序列化漏洞 define(LARAVEL_START, microtime(true));/* |-------------------------------------------------------------------------- | Register The Auto Loader |-------------------------------------------------------------------------- | |…

mysql IF語句,模糊檢索

使用MySQL IF語句完成條件檢索 IF(expr1,expr2,expr3)&#xff0c;expr1如果滿足條件就用expr2&#xff0c;否則用expr3 SELECTa.*,count(*) AS stdSum FROMidb_std_power_engin_v1 a WHERE1 1 AND (IF( KV IS NOT NULL, a.NAME REGEXP KV, 1 1 ) ORIF( KV IS NOT NULL, …

凸優化理論學習二|凸函數及其相關概念

系列文章目錄 凸優化理論學習一|最優化及凸集的基本概念 文章目錄 系列文章目錄一、凸函數&#xff08;一&#xff09;凸集&#xff08;二&#xff09;凸函數的定義及舉例&#xff08;三&#xff09;凸函數的證明1、將凸函數限制在一條直線上2、判斷函數是否為凸函數的一階條件…

如何做筆記

鏈接&#xff1a; 程序員讀技術類書籍如何做筆記&#xff1f; - 知乎 我是如何寫好一篇技術博客的 - 簡書 技術博客&#xff0c;該寫些什么&#xff1f; - 知乎 前言 最近翻翻以前的博客和筆記&#xff0c;都覺得寫的不好。工作這么多年&#xff0c;其實一直都有想做成知識系列…

貝葉斯分類器詳解

1 概率論知識 1.1 先驗概率 先驗概率是基于背景常識或者歷史數據的統計得出的預判概率&#xff0c;一般只包含一個變量&#xff0c;例如P(A)&#xff0c;P(B)。 1.2 聯合概率 聯合概率指的是事件同時發生的概率&#xff0c;例如現在A,B兩個事件同時發生的概率&#xff0c;記…

Python: 獲取時間

from datetime import datetime, timedelta# 獲取當前時間 current_time datetime.now() print(f"current_time {current_time}")# 獲取時分秒部分 time current_time.time() print(f"time {time}")# 獲取當前時間,只要日期部分 current_date current…

華為交換機配置導出備份python腳本

一、腳本編寫思路 &#xff08;一&#xff09;針對設備型號 主要針對華為&#xff08;Huawei&#xff09;和華三&#xff08;H3C&#xff09;交換機設備的配置備份 &#xff08;二&#xff09;導出前預處理 1.在配置導出前&#xff0c;自動打開crt軟件或者MobaXterm軟件&am…

掌握MySQL執行計劃分析【Explain】

前言 MySQL是一個強大的關系型數據庫管理系統&#xff0c;其高效執行SQL查詢的能力是其核心價值之一。然而&#xff0c;當查詢變得復雜或者數據量急劇增長時&#xff0c;SQL查詢的性能問題往往成為我們不得不面對的挑戰。為了深入了解查詢的執行過程并找到性能瓶頸&#xff0c…

Modbus通訊協議初學

目錄 Modbus通訊協議初學什么是Modbus?Modbus用來做什么?4個種類的寄存器協議速記功能碼Modbus 報文幀示例解讀 Modbus通訊協議初學 什么是Modbus? 顧名思義,它是一個bus,即總線協議。比如串口協議、IIC協議、SPI都是通訊協議。你接觸到這種協議,相信你所處的行業是工業方…

如何自定義Linux命令

說明&#xff1a;本文介紹如何將自己常用的命令設置為自定義的命令&#xff0c;以下操作在阿里云服務器CentOS上進行。 修改配置文件 修改配置文件前&#xff0c;先敲下面的命令查看當前系統配置的shell版本 echo $SHELL或者 echo $0區別在于&#xff0c;$SHELL查看的是系統…

落雪音樂 超好用的桌面端音樂播放器

之前一直都是充某Q音樂的會員&#xff0c;突然不想氪金了&#xff0c;終于找到一個開源的音樂播放器&#xff0c;在此先給落雪無痕大佬跪了 太愛了 簡直白嫖怪的福音 話不多說&#xff0c;直接上操作&#xff1a;解壓密碼&#xff1a;www.1234f.com下載地址&#xff1a;極速云…

圖片批量管理邁入智能新時代:一鍵輸入關鍵詞,自動生成并保存驚艷圖片,輕松開啟創意之旅!

在數字化時代&#xff0c;圖片已成為我們表達創意、記錄生活、傳遞信息的重要工具。然而&#xff0c;隨著圖片數量的不斷增加&#xff0c;如何高效、便捷地管理這些圖片&#xff0c;卻成為了一個令人頭疼的問題。 第一步&#xff0c;進入首助編輯高手主頁面&#xff0c;在上方…

簡單的Python示例母親節的祝福

在Python中&#xff0c;我們通常不會直接編寫HTML源碼&#xff0c;但我們可以編寫一個Python腳本來生成或發送包含母親節祝福的HTML內容。以下是一個簡單的Python示例&#xff0c;它使用字符串拼接來創建一個簡單的HTML頁面&#xff0c;其中包含母親節的祝福。 # 定義一個包含…

【AMBA Bus ACE 總線 9.1 -- Non-cache Master 寫操作 詳細介紹】

請閱讀【AMBA Bus ACE 總線與Cache 專欄 】 歡迎學習:【嵌入式開發學習必備專欄】 文章目錄 Non-cache MasterACE 和系統級緩存一致性ACE 非緩存主控(Non-cacheable Master)Non-cache Master ARM的ACE(AXI Coherency Extension)是一種用于增強系統級緩存一致性的接口規范…

視頻封面一鍵提取:從指定時長中輕松獲取您想要的幀圖片

在數字媒體時代&#xff0c;視頻已成為人們獲取信息、娛樂和溝通的主要形式之一。而一個好的視頻封面&#xff0c;往往能夠吸引觀眾的眼球&#xff0c;增加視頻的點擊率和觀看量。然而&#xff0c;對于很多視頻創作者和編輯者來說&#xff0c;如何從視頻中快速、準確地提取出合…

Git知識點總結

目錄 1、版本控制 1.1什么是版本控制 1.2常見的版本控制工具 1.3版本控制分類 2、集中版本控制 SVN 3、分布式版本控制 Git 2、Git與SVN的主要區別 3、軟件下載 安裝&#xff1a;無腦下一步即可&#xff01;安裝完畢就可以使用了&#xff01; 4、啟動Git 4.1常用的Li…