【LangChain系列】2. 一文全览LangChain数据连接模块:从文档加载到向量检索RAG,理论+实战+细节

本文学习 LangChain 中的 数据连接(Retrieval) 模块。该模块提供文档加载、切分,向量存储、检索等操作的封装。最后,结合RAG基本流程,我们将利用LangChain实现RAG的基本流程。

0. 模块介绍

在前面文章中我们已经讲了大模型存在的缺陷:数据不实时,缺少垂直领域数据和私域数据等。解决这些缺陷的主要方法是通过检索增强生成(RAG)。首先检索外部数据,然后在执行生成步骤时将其传递给LLM。

LangChain为RAG应用程序提供了从简单到复杂的所有构建块,本文要学习的数据连接(Retrieval)模块包括与检索步骤相关的所有内容,例如数据的获取、切分、向量化、向量存储、向量检索等模块(见下图)。

在这里插入图片描述

1. Document loaders 文档加载模块

LangChain封装了一系列类型的文档加载模块,例如PDF、CSV、HTML、JSON、Markdown、File Directory等。下面以PDF文件夹在为例看一下用法,其它类型的文档加载的用法都类似。

1.1 加载本地文件

LangChain加载PDF文件使用的是pypdf,先安装:

python
复制代码
pip install pypdf

加载代码示例:

python
复制代码
from langchain_community.document_loaders import PyPDFLoader

loader = PyPDFLoader("D:\GitHub\LEARN_LLM\RAG\如何向 ChatGPT 提问以获得高质量答案:提示技巧工程完全指南.pdf")
pages = loader.load_and_split()

print(f"第0页:\n{pages[0]}") ## 也可通过 pages[0].page_content只获取本页内容

看下运行结果:pypdf将PDF分成了一个数组,数组中的每个元素包含本页内容、文件路径和名称以及所在页码。

在这里插入图片描述

1.2 加载在线PDF文件

LangChain竟然也能加载在线的PDF文件。

1.2.1 可能需要的环境配置

在开始之前,你可能需要安装以下的Python包:

python
复制代码
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple unstructured
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pdf2image
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple unstructured-inference
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pikepdf

除了Python包,还需要下载 nltk_data,这东西非常大,下载起来非常慢。所以们可以事先下好,放到固定的位置。 在这里插入图片描述

  • 下载地址:github.com/nltk/nltk_d…
  • 下载完后,将其中的packages文件夹内的全部内容拷贝到固定位置,例如上面的 C:\Users\xxx\AppData\Roaming\nltk_data
1.2.2 示例代码
python
复制代码
from langchain_community.document_loaders import OnlinePDFLoader

loader = OnlinePDFLoader("https://arxiv.org/pdf/2302.03803.pdf")
data = loader.load()
print(data)

运行结果:

在这里插入图片描述

2. Text Splitting 文档切分模块

LangChain提供了许多不同类型的文本切分器,具体见下表:

名称分割依据添加元数据描述
Recursive用户定义字符列表递归地分割文本。递归地分割文本的目的是试图保持相关的文本片段相邻。这是开始分割文本的推荐方法。
HTMLHTML特定字符基于HTML特定字符分割文本。特别地,这会添加关于该片段来自何处的相关信息(基于HTML)。
MarkdownMarkdown特定字符基于Markdown特定字符分割文本。特别地,这会添加关于该片段来自何处的相关信息(基于Markdown)。
Code代码(Python、JS)特定字符基于编程语言特定字符分割文本。可选择15种不同的语言。
Token标记基于标记分割文本。有几种不同的标记计量方法。
Character用户定义字符基于用户定义字符分割文本。这是比较简单的方法之一。
[Experimental] Semantic Chunker句子首先基于句子分割文本。然后,如果相邻的句子在语义上足够相似,则合并它们。

这里以Recursive为例展示用法。RecursiveCharacterTextSplitter是LangChain对这种文档切分方式的封装,里面的几个重点参数:

  • chunk_size:每个切块的token数量
  • chunk_overlap:相邻两个切块之间重复的token数量
python
复制代码
from langchain_community.document_loaders import PyPDFLoader

loader = PyPDFLoader("D:\GitHub\LEARN_LLM\RAG\如何向 ChatGPT 提问以获得高质量答案:提示技巧工程完全指南.pdf")
pages = loader.load_and_split()
print(f"第0页:\n{pages[0].page_content}")

from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=200,
    chunk_overlap=100,
    length_function=len,
    add_start_index=True,
)

paragraphs = text_splitter.create_documents([pages[0].page_content])
for para in paragraphs:
    print(para.page_content)
    print('-------')

以上示例程序将chunk_overlap设置为100,看下运行效果,可以看到上一个chunk和下一个chunk会有一部分的信息重合,这样做的原因是尽可能地保证两个chunk之间的上下文关系

image.png

LangChain虽然提供了文本加载和分割模块的封装,但很明显,想要用在实际的项目中,还远远不够,需要在此基础上做非常细致的策略兜底或干脆自己实现一套符合自己实际需求的文档加载和分割器。

这里提供了一个可视化展示文本如何分割的工具,感兴趣的可以看下。

工具网址:chunkviz.up.railway.app/

image.png

3. Text embedding models 文本向量化模型封装

LangChain对一些文本向量化模型的接口做了封装,例如OpenAI, Cohere, Hugging Face等。 向量化模型的封装提供了两种接口,一种针对文档的向量化embed_documents,一种针对句子的向量化embed_query

示例代码:

  • 文档的向量化embed_documents,接收的参数是字符串数组
python
复制代码
from langchain_openai import OpenAIEmbeddings

embeddings_model = OpenAIEmbeddings()  ## OpenAI文本向量化模型接口的封装

embeddings = embeddings_model.embed_documents(
    [
        "Hi there!",
        "Oh, hello!",
        "What's your name?",
        "My friends call me World",
        "Hello World!"
    ]
)
len(embeddings), len(embeddings[0])

##运行结果 (5, 1536)
  • 句子的向量化embed_query,接收的参数是字符串
python
复制代码
embedded_query = embeddings_model.embed_query("What was the name mentioned in the conversation?")
embedded_query[:5]

## 运行结果:
## [0.0053587136790156364,
##  -0.0004999046213924885,
##  0.038883671164512634,
##  -0.003001077566295862,
##  -0.00900818221271038]

4. Vector stores 向量存储(数据库)

将文本向量化之后,下一步就是进行向量的存储。 这部分包含两块:一是向量的存储。二是向量的查询。

官方提供了三种开源、免费的可用于本地机器的向量数据库示例(chroma、FAISS、 Lance)。因为我在之前RAG的文章中用的chroma数据库,所以这里还是以这个数据库为例。

安装:

python
复制代码
pip install chromadb

创建向量数据库,灌入数据from_documents

python
复制代码
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
db = Chroma.from_documents(paragraphs, OpenAIEmbeddings()) ## 一行代码搞定

查询similarity_search

python
复制代码
query = "什么是角色提示?"
docs = db.similarity_search(query) ## 一行代码搞定
for doc in docs:
    print(f"{doc.page_content}\n-------\n")

运行结果:

image.png

它也接受传入一个向量来进行向量检索similarity_search_by_vector。以下是代码示例。在以下代码中可能体现的价值不是很大,但是在实际项目中,如果出现只知道向量值,不知道具体文字的情况,这个接口就有用了。

python
复制代码
embedding_vector = OpenAIEmbeddings().embed_query(query)
docs = db.similarity_search_by_vector(embedding_vector)
print(docs[0].page_content)

5. Retrievers 检索器

检索器是在给定非结构化查询的情况下返回相关文本的接口。它比Vector stores更通用。检索器不需要能够存储文档,只需要返回(或检索)文档即可。Vector stores可以用作检索器的主干,但也有其他类型的检索器。检索器接受字符串查询作为输入,并返回文档列表作为输出

LangChain检索器提供的检索类型如下:

名称索引类型使用LLM何时使用描述
VectorstoreVectorstore刚开始接触,想快速简单的入门这是最简单的方法,也是最容易入门的方法。它涉及为每个文本片段创建向量。
ParentDocumentVectorstore + 文档存储如果您的页面有许多较小的独立信息片段,最好单独索引,但最好一起检索。这涉及为每个文档索引多个片段。然后找到在嵌入空间中最相似的片段,但检索整个父文档并返回(而不是单个片段)。
Multi VectorVectorstore + 文档存储有时在索引过程中如果您能够从文档中提取比文本本身更相关的信息。这涉及为每个文档创建多个向量。每个向量可以以多种方式创建 - 例如,文本摘要和假设性问题。
Self QueryVectorstore如果用户提出的问题更适合根据元数据而不是文本相似性来获取文档回答。这使用LLM将用户输入转换为两件事:(1)语义查找的字符串,(2)与之配套的元数据过滤器。这很有用,因为通常问题是关于文档的元数据(而不是内容本身)。
Contextual Compression任意有时如果您发现检索到的文档包含太多不相关信息,并且干扰了LLM。这在另一个检索器之上放置了后处理步骤,并仅从检索到的文档中提取最相关的信息。这可以使用嵌入或LLM完成。
Time-Weighted VectorstoreVectorstore如果您的文档有时间戳,并且您想检索最近的文档。这根据语义相似性(与常规向量检索相同)和时间权重(查看索引文档的时间戳)检索文档。
Multi-Query Retriever任意如果用户提出的问题复杂,并且需要多个独立信息片段来回应。这使用LLM从原始查询生成多个查询。当原始查询需要有关多个主题的信息片段才能正确回答时,这很有用。通过生成多个查询,我们可以为每个查询获取文档。
Ensemble任意如果您有多个检索方法并希望尝试将它们组合起来。这从多个检索器中获取文档,然后将它们组合在一起。
Long-Context Reorder任意如果您使用长上下文模型,并且注意到它没有关注检索到的文档中的中间信息。这从基础检索器中获取文档,然后重新排序文档,使最相似的文档靠近开头和结尾。这很有用,因为长上下文模型有时不关注上下文窗口中间的信息。

表中的每个检索类型都可以单独拿出来学习和研究。本文先大体了解都有哪些类型,以Vectorstore类型的检索为例简单使用(功能与Vectorstore中的查询一样):

python
复制代码
retriever = db.as_retriever()
docs = retriever.get_relevant_documents("什么是角色提示?")
for doc in docs:
    print(f"{doc.page_content}\n-------\n")
  • as_retriever:生成检索器实例
  • get_relevant_documents获取相关文本

as_retriever可指定使用的检索类型,同时也可指定一些其它参数,例如:

  • 指定一个相似度阈值为0.5,只有相似度超过这个值才会召回
python
复制代码
retriever = db.as_retriever(
    search_type="similarity_score_threshold", search_kwargs={"score_threshold": 0.5}
)
  • 指定检索几个文本片段:topK
python
复制代码
retriever = db.as_retriever(search_kwargs={"k": 1})

6. Indexing

这块还没用到,先看下概念和作用。总的来说,这块是帮助用户省钱的,帮助用户减少重复的文档向量化和灌入,帮助用户定制化的删除一些冲突内容或无用内容。

6.1 概念和用途

索引API允许您将任何来源的文档加载到向量存储中并保持同步。具体来说,它有助于:

  • 避免将重复的内容写入向量数据库
  • 避免重写未更改的内容
  • 避免在未更改的内容上重新计算向量

6.2 工作原理

LangChain索引使用记录管理器(RecordManager)来跟踪文档写入向量数据库的情况。为内容编制索引时,会为每个文档计算哈希值,并将以下信息存储在记录管理器中:

  • 文档哈希(页面内容和元数据的哈希)
  • 写入时间
  • 源id – 每个文档都应该在其元数据中包含信息,以便我们确定该文档的最终来源

6.3 Deletion modes

该模块还提供了 Deletion modes。它的应用场景是:将文档索引到向量数据库时,可能会删除数据库中的一些现有文档。在某些情况下,您可能希望删除与正在编制索引的新文档来源相同的现有文档。在其他情况下,您可能希望批量删除所有现有文档。索引API删除模式帮助你进行自定义删除。

7. 总结,用LangChain实现RAG流程

请先阅读前置文章,了解RAG基本流程和LangChain的Prompt模板:

  • 【AI大模型应用开发】3. RAG初探 - 动手实现一个最简单的RAG应用
  • 【AI大模型应用开发】【LangChain系列】1. 全面学习LangChain输入输出I/O模块:理论介绍+实战示例+细节注释

以上,我们学习了LangChain数据连接模块的所有内容。下面,我们将所有流程串起来,用LangChain实现一下RAG流程。

python
复制代码
    ## 1. 文档加载
    from langchain.document_loaders import PyPDFLoader
    loader = PyPDFLoader("D:\GitHub\LEARN_LLM\RAG\如何向 ChatGPT 提问以获得高质量答案:提示技巧工程完全指南.pdf")
    pages = loader.load_and_split()
    
    ## 2. 文档切分
    from langchain.text_splitter import RecursiveCharacterTextSplitter
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=200,
        chunk_overlap=100,
        length_function=len,
        add_start_index=True,
    )
    paragraphs = []
    for page in pages:
        paragraphs.extend(text_splitter.create_documents([page.page_content]))
    
    ## 3. 文档向量化,向量数据库存储
    from langchain_openai import OpenAIEmbeddings
    from langchain_community.vectorstores import Chroma
    db = Chroma.from_documents(paragraphs, OpenAIEmbeddings())
    
    ## 4. 向量检索
    # query = "什么是角色提示?"
    # docs = db.similarity_search(query)
    # for doc in docs:
    #     print(f"{doc.page_content}\n-------\n")
    
    retriever = db.as_retriever()
    docs = retriever.get_relevant_documents("什么是角色提示?")
    for doc in docs:
        print(f"{doc.page_content}\n-------\n")
    
    ## 5. 组装Prompt模板
    import os
    # 加载 .env 到环境变量
    from dotenv import load_dotenv, find_dotenv
    _ = load_dotenv(find_dotenv())

    from langchain_openai import ChatOpenAI
    
    llm = ChatOpenAI() # 默认是gpt-3.5-turbo
    prompt_template = """
    你是一个问答机器人。
    你的任务是根据下述给定的已知信息回答用户问题。
    确保你的回复完全依据下述已知信息。不要编造答案。
    如果下述已知信息不足以回答用户的问题,请直接回复"我无法回答您的问题"。

    已知信息:
    {info}

    用户问:
    {question}

    请用中文回答用户问题。
    """

    from langchain.prompts import PromptTemplate
    template = PromptTemplate.from_template(prompt_template)
    prompt = template.format(info=docs[0].page_content, question='什么是角色提示?')
    ## 6. 调用LLM
    response = llm.invoke(prompt)
    print(response.content)  

运行结果:

在这里插入图片描述

如何学习大模型 AI ?

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

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

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

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

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

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

😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓

在这里插入图片描述

第一阶段(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%免费

😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓

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

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

相关文章

ssm042在线云音乐系统的设计与实现+jsp

在线云音乐系统的设计与实现 摘 要 随着移动互联网时代的发展,网络的使用越来越普及,用户在获取和存储信息方面也会有激动人心的时刻。音乐也将慢慢融入人们的生活中。影响和改变我们的生活。随着当今各种流行音乐的流行,人们在日常生活中经…

MySQL 连接查询

目录 连接查询 命令格式: 内连接: 等值连接: 格式: 非等值连接: 格式: 外连接: 左连接: 格式: 结果: 右连接: 格式: 结果: 全外连…

D-LinkNAS 远程命令执行漏洞(CVE-2024-3273)RCE漏

声明: 本文仅用于技术交流,请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。 简介 D-LinkNAS是由D-Link公司制造的网络附加存储设备。…

01 SQL基础 -- 初识数据库与安装

一、初识数据库 数据库是将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合。该数据集合称为数据库(Database, DB)。用来管理数据库的计算机系统称为数据库管理系统(Database Management System, DBMS) 1.1 DBMS 的种类 DBMS 主要通过数据的保存格式…

公众号答疑集锦(4月)之IE,二维声纳,hypack处理内河多波束

1、Inertial Explorer这款软件怎么导出txt或csv格式的轨迹文件? 答:https://mp.weixin.qq.com/s/Rtl_3YJjDQblyVPLXjAmhA。 问:软件需要一个EGM96-World.wpg格式的文件,就是IE这家公司特有的文件格式。我登录他们官网&#xff0…

JAVAEE之Spring AOP

1. AOP概述 AOP是Spring框架的第⼆⼤核⼼(第⼀⼤核⼼是IoC) 1.1 什么是AOP? • Aspect Oriented Programming(⾯向切⾯编程) 什么是⾯向切⾯编程呢? 切⾯就是指某⼀类特定问题, 所以AOP也可以理解为⾯向特定⽅法编程. 什么是⾯向特定⽅法编…

OpenHarmony南向开发-Docker编译环境

Docker环境介绍 OpenHarmony为开发者提供了两种Docker环境,以帮助开发者快速完成复杂的开发环境准备工作。两种Docker环境及适用场景如下: 独立Docker环境:适用于直接基于Ubuntu、Windows操作系统平台进行版本编译的场景。 基于HPM的Docker…

宏定义(超级详细)

宏定义在编程里面也有十分重要的作用,下面我就来详细介绍一下: 宏的特点 宏主要特点是它在预编译的时候就会被数字或者代码字符替换掉。这样可以将一些重复的变量替换掉,方便我们进行修改,只需要修改宏定义就行了。 宏的几大类…

《一》Qt的概述

1.1 什么是Qt Qt是一个跨平台的C图形用户界面应用程序框架。它为应用程序开发者提供建立图形界面所需的所有功能。它是完全面向对象的,很容易扩展,并且允许真正的组件编程。 1.2 Qt的发展史 1991年 Qt最早由芬兰奇趣科技开发 1996年 进入商业领域&#x…

2024年mathorcup(妈妈杯)数学建模C题思路-物流网络分拣中心货量预测及人员排班

# 1 赛题 C 题 物流网络分拣中心货量预测及人员排班 电商物流网络在订单履约中由多个环节组成,图 ’ 是一个简化的物流 网络示意图。其中,分拣中心作为网络的中间环节,需要将包裹按照不同 流向进行分拣并发往下一个场地,最终使包裹…

matlab conv2

MATLAB卷积conv、conv2、convn详解-CSDN博客

全面学习SpringCloud框架指南

要深入学习Spring Cloud框架,你需要系统地掌握其核心组件和概念,并了解如何在实际项目中应用这些知识。以下是一些关键的学习点和相应的学习内容: 一共分为10个模块包括: 1、微服务架构基础: 理解微服务架构的概念和优势。 学习单体架构向微服务架构演进的过程。 掌握…

IE浏览器清理缓存工具

有些项目可能因为浏览器缓存导致使用异常,比如登陆异常。这里提供清除浏览器痕迹的工具,以IE浏览器为例,痕迹的默认存放位置为: C:\Users\Ro\AppData\Local\Microsoft\Windows\Temporary Internet Files 新建bat或者cmd批处理文件…

【LeetCode热题100】189. 轮转数组(数组)

一.题目要求 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 二.题目难度 中等 三.输入样例 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: …

【学习】企业做等保测评有何意义

等保测评是指对信息系统的安全性进行评估和保障的一种标准,其全称为“信息安全等级保护测评”。随着信息技术的不断发展和应用,信息安全问题越来越受到人们的关注。为了保障信息系统的安全,国家制定了一系列的安全等级保护标准,而…

【优选算法专栏】专题四:前缀和(二)

本专栏内容为:算法学习专栏,分为优选算法专栏,贪心算法专栏,动态规划专栏以及递归,搜索与回溯算法专栏四部分。 通过本专栏的深入学习,你可以了解并掌握算法。 💓博主csdn个人主页:小…

gitee上传出现git did not exit cleanly (exit code 1)的错误

在最后push的时候出现下面的结果: 出现这个错误的原因有好多种,目前介绍博主遇到的两种: 在第一次进行push操作的时候,需要输入用户名和密码,如果输入错误,则最后可能会出现上述报错 解决方法:…

智慧InSAR专题———模拟数据实现现实场景异常形变点识别(项目讲解)

续上篇 文章目录 (一项技术的复现,我们应该有打破砂锅问到底的态度,我找到了这篇文章的一些灵感来源,包括算法和编程以及专业知识等,对我而言也是受益匪浅)1. 数据准备1.1 A deep learning approach to de…

基于STM32F103单片机的时间同步项目

一、前言 本项目为前一个时间同步项目的更迭版本,由于之前的G031开发板没有外部晶振,从机守时能力几乎没有,5秒以上不同步从机时间就开始飞了。在考虑成本选型后,选择了带有外部有缘晶振的STM32F103C8T6最小单片机,来作为本次项目的开发平台。 G031时间同步链接: 基于ST…

mui和uniapp跳转外部链接

Hbuilder开发的app&#xff0c;会涉及到跳转H5页面 mui <!DOCTYPE html> <html><head><meta charset"utf-8"><meta name"viewport" content"initial-scale1.0, maximum-scale1.0, user-scalableno" /><link …