《Advanced RAG》-02-揭开 PDF 解析的神秘面纱

news2025/7/8 12:46:49

摘要

PDF 文件是非结构化文档的代表,但从 PDF 文档中提取信息是一个具有挑战性的过程。

PDF 文件由一系列指令组成,这些指令指示 PDF 阅读器或打印机在屏幕或纸张上显示符号的位置和方式。与 HTML 和 docx 等文件格式不同,后者使用标记来组织不同的逻辑结构。

解析 PDF 文档的挑战在于准确提取整个页面的布局,并将内容(包括表格、标题、段落和图像)转化为文档的文本表示。

这一过程涉及处理文本提取中的不准确性、图像识别以及表格中行列关系的混淆。

文章观点

  1. 解析 PDF 文档的挑战在于准确提取整个页面的布局,并将内容转化为文档的文本表示。
  2. 解析 PDF 文档的方法包括基于规则的方法、基于深度学习模型的方法和基于多模态大型模型的方法。
    1. 基于规则的方法的限制是它将 PDF 中的字符序列序列化为一个单一的长序列,而不保留结构信息。
    2. 基于深度学习模型的方法可以准确识别整个文档的布局,包括表格和段落,但对象检测和 OCR 阶段可能比较耗时。
    3. 基于多模态大型模型的方法可以提取或总结关键信息,但需要检索相关图像(PDF 页面)并将其发送至 GPT4-V,以响应查询。

对于 RAG 来说,从文件中提取信息是一种不可避免的情况。确保从源文件中提取内容的有效性对于提高最终输出的质量至关重要。

在实施 RAG 时,如果在解析过程中信息提取不当,会导致对 PDF 文件所含信息的理解和利用受到限制。

Pasing 流程在 RAG 中的位置如图 1 所示:

在这里插入图片描述

在实际工作中,非结构化数据要比结构化数据丰富得多。如果不能对这些海量数据进行解析,就无法实现其巨大价值。

在非结构化数据中,PDF 文档占大多数。有效处理 PDF 文档对管理其他类型的非结构化文档也大有帮助。

本文主要介绍解析 PDF 文件的方法。它提供了有效解析 PDF 文档并尽可能提取有用信息的算法和建议。

解析 PDF 的挑战

PDF 文档是非结构化文档的代表,然而,从 PDF 文档中提取信息是一个具有挑战性的过程。

与其说 PDF 是一种数据格式,不如说它是印刷指令的集合更为准确。

PDF 文件由一系列指令组成,这些指令指示 PDF 阅读器或打印机在屏幕或纸张上显示符号的位置和方式。

这与 HTML 和 docx 等文件格式截然不同,后者使用<p><w:p><table><w:tbl>等标记来组织不同的逻辑结构,如图 2 所示:

在这里插入图片描述

**解析 PDF 文档的挑战在于准确提取整个页面的布局,并将内容(包括表格、标题、段落和图像)转化为文档的文本表示。**这一过程涉及处理文本提取中的不准确性、图像识别以及表格中行列关系的混淆。

如何解析 PDF 文档

一般来说,有三种解析 PDF 的方法:

  1. 基于规则的方法:根据文档的组织特征确定每个部分的样式和内容。
    1. 这种方法的通用性不强,因为 PDF 的类型和布局多种多样,不可能用预定义的规则涵盖所有类型和布局。
  2. 基于深度学习模型的方法:例如结合了物体检测和 OCR 模型的流行解决方案。
  3. 基于多模态大型模型在 PDF 文件中提取复杂结构或关键信息。

基于规则的方法

最有代表性的工具之一是 pypdf,它是一种广泛使用的基于规则的解析器。它是 LangChain 和 LlamaIndex 中解析 PDF 文件的标准方法。

下面是使用 pypdf 解析 "Attention Is All You Need"论文第 6 页的尝试。原始页面如图 3 所示。

在这里插入图片描述

代码如下

import PyPDF2
filename = "/Users/Florian/Downloads/1706.03762.pdf"
pdf_file = open(filename, 'rb')

reader = PyPDF2.PdfReader(pdf_file)

page_num = 5
page = reader.pages[page_num]
text = page.extract_text()

print('--------------------------------------------------')
print(text)

pdf_file.close()

执行的结果是(为简洁起见,省略其余部分):

(py) Florian:~ Florian$ pip list | grep pypdf
pypdf                    3.17.4
pypdfium2                4.26.0

(py) Florian:~ Florian$ python /Users/Florian/Downloads/pypdf_test.py
--------------------------------------------------Table 1: Maximum path lengths, per-layer complexity and minimum number of sequential operations
for different layer types. nis the sequence length, dis the representation dimension, kis the kernel
size of convolutions and rthe size of the neighborhood in restricted self-attention.
Layer Type Complexity per Layer Sequential Maximum Path Length
Operations
Self-Attention O(n2·d) O(1) O(1)
Recurrent O(n·d2) O(n) O(n)
Convolutional O(k·n·d2) O(1) O(logk(n))
Self-Attention (restricted) O(r·n·d) O(1) O(n/r)
3.5 Positional Encoding
Since our model contains no recurrence and no convolution, in order for the model to make use of the
order of the sequence, we must inject some information about the relative or absolute position of the
tokens in the sequence. To this end, we add "positional encodings" to the input embeddings at the
bottoms of the encoder and decoder stacks. The positional encodings have the same dimension dmodel
as the embeddings, so that the two can be summed. There are many choices of positional encodings,
learned and fixed [9].
In this work, we use sine and cosine functions of different frequencies:
PE(pos,2i)=sin(pos/100002i/d model)
PE(pos,2i+1)=cos(pos/100002i/d model)
where posis the position and iis the dimension. That is, each dimension of the positional encoding
corresponds to a sinusoid. The wavelengths form a geometric progression from 2πto10000 ·2π. We
chose this function because we hypothesized it would allow the model to easily learn to attend by
relative positions, since for any fixed offset k,PEpos+kcan be represented as a linear function of
PEpos.
...
...
...

根据 PyPDF 的检测结果,可以发现它将 PDF 中的字符序列序列化为一个单一的长序列,而不保留结构信息。

换句话说,它将文档中的每一行都视为由换行符"\n "分隔的序列,从而无法准确识别段落或表格。

这种限制是基于规则的方法的固有特征。

基于深度学习模型的方法

这种方法的优点是能够准确识别整个文档的布局,包括表格和段落。它甚至可以理解表格内的结构。

这意味着它可以将文档划分为定义明确、完整的信息单元,同时保留预期的含义和结构。

但也存在一些局限性。对象检测和 OCR 阶段可能比较耗时

因此,建议使用 GPU 或其他加速设备,并采用多个进程和线程进行处理。

这种方法涉及对象检测和 OCR 模型,我已经测试了几个具有代表性的开源框架:

  • Unstructured:已集成到 langchain 中。在infer_table_structure=True 的情况下,高分辨率策略的表格识别效果很好。然而,fast策略由于没有使用对象检测模型,错误地识别了许多图像和表格,因此表现不佳。
  • Layout-parser:如果需要识别结构复杂的 PDF,建议使用最大的模型,这样准确率会更高,不过速度可能会稍慢一些。此外,Layout-parser 的模型似乎在过去两年中没有更新过。
  • PP-StructureV2:使用各种模型组合进行文档分析,性能高于平均水平。架构如图 4 所示:

在这里插入图片描述

除了开源工具外,还有像 ChatDOC 这样的付费工具,利用基于布局识别 + OCR 方法来解析 PDF 文档。

接下来,我们将介绍如何使用开源非结构化框架解析 PDF,解决三个关键难题。

挑战 1:如何从表格和图像中提取数据

这里,我们将以非结构化框架为例。检测到的表格数据可以直接导出为 HTML。相关代码如下:

from unstructured.partition.pdf import partition_pdf

filename = "/Users/Florian/Downloads/Attention_Is_All_You_Need.pdf"# infer_table_structure=True automatically selects hi_res strategy
elements = partition_pdf(filename=filename, infer_table_structure=True)
tables = [el for el in elements if el.category == "Table"]

print(tables[0].text)
print('--------------------------------------------------')
print(tables[0].metadata.text_as_html)

我跟踪了 partition_pdf 函数的内部流程。图 5 是基本流程图。

在这里插入图片描述

代码运行结果如下:

Layer Type Self-Attention Recurrent Convolutional Self-Attention (restricted) Complexity per Layer O(n2 · d) O(n · d2) O(k · n · d2) O(r · n · d) Sequential Maximum Path Length Operations O(1) O(n) O(1) O(1) O(1) O(n) O(logk(n)) O(n/r)
--------------------------------------------------
<table><thead><th>Layer Type</th><th>Complexity per Layer</th><th>Sequential Operations</th><th>Maximum Path Length</th></thead><tr><td>Self-Attention</td><td>O(n? - d)</td><td>O(1)</td><td>O(1)</td></tr><tr><td>Recurrent</td><td>O(n- d?)</td><td>O(n)</td><td>O(n)</td></tr><tr><td>Convolutional</td><td>O(k-n-d?)</td><td>O(1)</td><td>O(logy(n))</td></tr><tr><td>Self-Attention (restricted)</td><td>O(r-n-d)</td><td>ol)</td><td>O(n/r)</td></tr></table>

复制 HTML 标记并将其保存为 HTML 文件。然后使用 Chrome 浏览器打开,如图 6 所示:

在这里插入图片描述

可以看出,非结构化算法基本上恢复了整个表格。

挑战 2:如何重新排列检测到的区块?尤其是双栏 PDF。

在处理双栏 PDF 时,我们以论文 "BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding"为例。红色箭头表示阅读顺序:

在这里插入图片描述

确定布局后,非结构化框架会将每个页面划分为若干矩形块,如图 8 所示。

在这里插入图片描述

每个矩形块的详细信息可按以下格式获取:

[
LayoutElement(bbox=Rectangle(x1=851.1539916992188, y1=181.15073777777613, x2=1467.844970703125, y2=587.8204599999975), text='These approaches have been generalized to coarser granularities, such as sentence embed- dings (Kiros et al., 2015; Logeswaran and Lee, 2018) or paragraph embeddings (Le and Mikolov, 2014). To train sentence representations, prior work has used objectives to rank candidate next sentences (Jernite et al., 2017; Logeswaran and Lee, 2018), left-to-right generation of next sen- tence words given a representation of the previous sentence (Kiros et al., 2015), or denoising auto- encoder derived objectives (Hill et al., 2016). ', source=<Source.YOLOX: 'yolox'>, type='Text', prob=0.9519357085227966, image_path=None, parent=None), 
LayoutElement(bbox=Rectangle(x1=196.5296173095703, y1=181.1507377777777, x2=815.468994140625, y2=512.548237777777), text='word based only on its context. Unlike left-to- right language model pre-training, the MLM ob- jective enables the representation to fuse the left and the right context, which allows us to pre- In addi- train a deep bidirectional Transformer. tion to the masked language model, we also use a “next sentence prediction” task that jointly pre- trains text-pair representations. The contributions of our paper are as follows: ', source=<Source.YOLOX: 'yolox'>, type='Text', prob=0.9517233967781067, image_path=None, parent=None), 
LayoutElement(bbox=Rectangle(x1=200.22352600097656, y1=539.1451822222216, x2=825.0242919921875, y2=870.542682222221), text='• We demonstrate the importance of bidirectional pre-training for language representations. Un- like Radford et al. (2018), which uses unidirec- tional language models for pre-training, BERT uses masked language models to enable pre- trained deep bidirectional representations. This is also in contrast to Peters et al. (2018a), which uses a shallow concatenation of independently trained left-to-right and right-to-left LMs. ', source=<Source.YOLOX: 'yolox'>, type='List-item', prob=0.9414362907409668, image_path=None, parent=None), 
LayoutElement(bbox=Rectangle(x1=851.8727416992188, y1=599.8257377777753, x2=1468.0499267578125, y2=1420.4982377777742), text='ELMo and its predecessor (Peters et al., 2017, 2018a) generalize traditional word embedding re- search along a different dimension. They extract context-sensitive features from a left-to-right and a right-to-left language model. The contextual rep- resentation of each token is the concatenation of the left-to-right and right-to-left representations. When integrating contextual word embeddings with existing task-specific architectures, ELMo advances the state of the art for several major NLP benchmarks (Peters et al., 2018a) including ques- tion answering (Rajpurkar et al., 2016), sentiment analysis (Socher et al., 2013), and named entity recognition (Tjong Kim Sang and De Meulder, 2003). Melamud et al. (2016) proposed learning contextual representations through a task to pre- dict a single word from both left and right context using LSTMs. Similar to ELMo, their model is feature-based and not deeply bidirectional. Fedus et al. (2018) shows that the cloze task can be used to improve the robustness of text generation mod- els. ', source=<Source.YOLOX: 'yolox'>, type='Text', prob=0.938507616519928, image_path=None, parent=None), 
LayoutElement(bbox=Rectangle(x1=199.3734130859375, y1=900.5257377777765, x2=824.69873046875, y2=1156.648237777776), text='• We show that pre-trained representations reduce the need for many heavily-engineered task- specific architectures. BERT is the first fine- tuning based representation model that achieves state-of-the-art performance on a large suite of sentence-level and token-level tasks, outper- forming many task-specific architectures. ', source=<Source.YOLOX: 'yolox'>, type='List-item', prob=0.9461237788200378, image_path=None, parent=None), 
LayoutElement(bbox=Rectangle(x1=195.5695343017578, y1=1185.526123046875, x2=815.9393920898438, y2=1330.3272705078125), text='• BERT advances the state of the art for eleven NLP tasks. The code and pre-trained mod- els are available at https://github.com/ google-research/bert. ', source=<Source.YOLOX: 'yolox'>, type='List-item', prob=0.9213815927505493, image_path=None, parent=None), 
LayoutElement(bbox=Rectangle(x1=195.33956909179688, y1=1360.7886962890625, x2=447.47264000000007, y2=1397.038330078125), text='2 Related Work ', source=<Source.YOLOX: 'yolox'>, type='Section-header', prob=0.8663332462310791, image_path=None, parent=None), 
LayoutElement(bbox=Rectangle(x1=197.7477264404297, y1=1419.3353271484375, x2=817.3308715820312, y2=1527.54443359375), text='There is a long history of pre-training general lan- guage representations, and we briefly review the most widely-used approaches in this section. ', source=<Source.YOLOX: 'yolox'>, type='Text', prob=0.928022563457489, image_path=None, parent=None), 
LayoutElement(bbox=Rectangle(x1=851.0028686523438, y1=1468.341394166663, x2=1420.4693603515625, y2=1498.6444497222187), text='2.2 Unsupervised Fine-tuning Approaches ', source=<Source.YOLOX: 'yolox'>, type='Section-header', prob=0.8346447348594666, image_path=None, parent=None), 
LayoutElement(bbox=Rectangle(x1=853.5444444444446, y1=1526.3701822222185, x2=1470.989990234375, y2=1669.5843488888852), text='As with the feature-based approaches, the first works in this direction only pre-trained word em- (Col- bedding parameters from unlabeled text lobert and Weston, 2008). ', source=<Source.YOLOX: 'yolox'>, type='Text', prob=0.9344717860221863, image_path=None, parent=None), 
LayoutElement(bbox=Rectangle(x1=200.00000000000009, y1=1556.2037353515625, x2=799.1743774414062, y2=1588.031982421875), text='2.1 Unsupervised Feature-based Approaches ', source=<Source.YOLOX: 'yolox'>, type='Section-header', prob=0.8317819237709045, image_path=None, parent=None), 
LayoutElement(bbox=Rectangle(x1=198.64227294921875, y1=1606.3146266666645, x2=815.2886352539062, y2=2125.895459999998), text='Learning widely applicable representations of words has been an active area of research for decades, including non-neural (Brown et al., 1992; Ando and Zhang, 2005; Blitzer et al., 2006) and neural (Mikolov et al., 2013; Pennington et al., 2014) methods. Pre-trained word embeddings are an integral part of modern NLP systems, of- fering significant improvements over embeddings learned from scratch (Turian et al., 2010). To pre- train word embedding vectors, left-to-right lan- guage modeling objectives have been used (Mnih and Hinton, 2009), as well as objectives to dis- criminate correct from incorrect words in left and right context (Mikolov et al., 2013). ', source=<Source.YOLOX: 'yolox'>, type='Text', prob=0.9450697302818298, image_path=None, parent=None), 
LayoutElement(bbox=Rectangle(x1=853.4905395507812, y1=1681.5868488888855, x2=1467.8729248046875, y2=2125.8954599999965), text='More recently, sentence or document encoders which produce contextual token representations have been pre-trained from unlabeled text and fine-tuned for a supervised downstream task (Dai and Le, 2015; Howard and Ruder, 2018; Radford et al., 2018). The advantage of these approaches is that few parameters need to be learned from scratch. At least partly due to this advantage, OpenAI GPT (Radford et al., 2018) achieved pre- viously state-of-the-art results on many sentence- level tasks from the GLUE benchmark (Wang language model- Left-to-right et al., 2018a). ', source=<Source.YOLOX: 'yolox'>, type='Text', prob=0.9476840496063232, image_path=None, parent=None)
]

其中,(x1, y1) 是左上顶点的坐标,(x2, y2) 是右下顶点的坐标:

 (x_1, y_1) ---------------
            |             |
            |             |
            |             |
            ---------- (x_2, y_2)

此时,你可以选择调整页面的阅读顺序。Unstructured 自带排序算法,但我发现在处理双栏情况时,排序结果并不令人满意。

因此,有必要设计一种算法。最简单的方法是先按左上顶点的横坐标排序,如果横坐标相同,再按纵坐标排序。其伪代码如下:

layout.sort(key=lambda z: (z.bbox.x1, z.bbox.y1, z.bbox.x2, z.bbox.y2))

不过,我发现,即使是同一列中的图块,其横坐标也可能存在变化。

如图 9 所示,紫色线块的横坐标 bbox.x1 实际上更靠左。排序时,它的位置会在绿色线块之前,这显然违反了阅读顺序。

在这里插入图片描述

在这种情况下,一种可能的算法如下:

  • 首先,对所有左上角的 x 坐标 x1 排序,可以得到 x1_min
  • 然后,将所有右下角的 x 坐标 x2 排序,就可以得到 x2_max
  • 接下来,确定页面中心线的 x 坐标为
x1_min = min([el.bbox.x1 for el in layout])
x2_max = max([el.bbox.x2 for el in layout])
mid_line_x_coordinate = (x2_max + x1_min) /  2

接下来,如果 bbox.x1 < mid_line_x_coordinate,则该图块被归类为左列的一部分。否则,它将被视为右列的一部分。

分类完成后,根据 Y 坐标对列中的每个区块进行排序。最后,将右列连接到左列的右边。

left_column = []
right_column = []
for el in layout:
    if el.bbox.x1 < mid_line_x_coordinate:
        left_column.append(el)
    else:
        right_column.append(el)

left_column.sort(key = lambda z: z.bbox.y1)
right_column.sort(key = lambda z: z.bbox.y1)
sorted_layout = left_column + right_column

值得一提的是,这一改进也与单栏 PDF 兼容。

挑战 3:如何提取多级标题

提取标题(包括多级标题)的目的是提高 LLM 答案的准确性。

例如,如果用户想知道图 9 中第 2.1 节的大意,只要准确提取出第 2.1 节的标题,并将其与相关内容一起作为上下文发送给 LLM,最终答案的准确率就会大大提高。

该算法仍然依赖于图 9 所示的布局块。我们可以提取 type=‘Section-header’ 的图块,并计算高度差(bbox.y2 - bbox.y1)。高度差最大的区块对应一级标题,其次是二级标题,然后是三级标题。

基于多模态大模型的 PDF 复杂结构定标

在多模态模型大行其道之后,使用多模态模型来解析表格也成为可能。在这方面有几种选择:

  1. 检索相关图像(PDF 页面)并将其发送至 GPT4-V,以响应查询。
  2. 将每个 PDF 页面视为图像,让 GPT4-V 对每个页面进行图像推理。为图像推理建立文本向量存储索引。根据图像推理向量存储查询答案。
  3. 使用表格转换器从检索到的图像中裁剪表格信息,然后将这些裁剪后的图像发送到 GPT4-V 进行查询响应。
  4. 对裁剪后的表格图像进行 OCR 识别,并将数据发送到 GPT4/ GPT-3.5 以回答查询。

经过测试,确定第三种方法最为有效。

此外,我们还可以使用多模态模型从图像(PDF 文件可轻松转换为图像)中提取或总结关键信息。

结论

一般来说,非结构化文档具有高度灵活性,需要各种解析技术。然而,对于使用哪种方法最佳,目前还没有达成共识。

在这种情况下,建议选择一种最适合您项目需要的方法。建议根据不同类型的 PDF 应用特定的处理方法。例如,论文、书籍和财务报表可能会根据其特点进行独特的设计。

不过,如果情况允许,最好还是选择基于深度学习或多模态的方法。这些方法可以有效地将文档分割成定义明确的完整信息单元,从而最大限度地保留文档的原意和结构。

本文为翻译,原文地址:https://pub.towardsai.net/advanced-rag-02-unveiling-pdf-parsing-b84ae866344e

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

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

相关文章

8月2日,贪心-买卖股票的最佳时期

大家好呀&#xff0c;今天我们看两道用贪心算法解的两道题&#xff0c;150道经典面试题中的买卖股票的最佳时期1和2。 1.买卖股票的最佳时期1 . - 力扣&#xff08;LeetCode&#xff09; 思路 对于这题&#xff0c;我们其实很容易想出暴力解&#xff0c;那就是从后往前找值&…

【文件系统】抽象磁盘的存储结构 CHS寻址法 | sector数组 | LAB数组

目录 1.为什么要抽象 2.逻辑抽象_版本1 2.1sector数组 ​2.2index转化CHS 3.逻辑抽象_版本2 3.1LBA数组 3.2LAB下标转化sector下标 文件其实就是在磁盘中占有几个扇区的问题❗文件是很多个sector的数组下标❗文件是有很多块构成的❗❗文件由很多扇区构成------>文件…

C语言刷题小记3

题目1 序列中删除指定数字 分析&#xff1a;本题要求我们来删除一个序列中指定的数字&#xff0c;这里大家要注意我们要删除的数字可能不止出现一次&#xff0c;所以我们需要用两个变量来进行处理&#xff0c;一个变量来遍历数组&#xff0c;一个变量来存储数组的位置&#xff…

H5 上使用腾讯位置服务选择收货信息

效果图 首先需要在腾讯位置服务上申请你自己的key&#xff0c;可参考地图选点组件 // 点击打开地图 backurl 是点击选中的位置点后&#xff0c;页面跳转至要返回的地址&#xff08;backurl&#xff09;&#xff0c;会将位置信息添加到回跳地址&#xff08;backurl&#xff0…

【威胁情报】新的 BingoMod Android 安卓恶意软件伪装成安全应用程序,清除数据

关注公众号网络研究观获取更多内容。 小心 BingoMod&#xff01;这种危险的 Android 恶意软件会窃取您的钱财、清除您的手机数据并控制您的设备。 了解如何保护自己免受这种阴险威胁。保持在线安全&#xff01; 计算机安全解决方案提供商 Cleafy 发现了一种狡猾的远程访问木…

PCIe总线-RK3588 PCIe RC初始化流程分析(十二)

1.简介 RK3588 PCIe RC的初始化涉及PCIe设备枚举、中断&#xff08;INTx、MSI、MSI-X&#xff09;配置、BAR配置、ATU配置、链路训练等&#xff0c;下面一一介绍。 2.初始化 当RC的模式为RK_PCIE_EP_TYPE时&#xff0c;平台驱动调用rk_add_pcie_port函数初始化RC&#xff0c…

如何将Maven子项目插入到Maven父项目中

Maven项目的融合具体方法&#xff1a; 1.在电脑本地磁盘拷贝Maven子项目&#xff1b; 2.用IDEA软件打开Maven父项目&#xff1b; 3.在IDEA中选中Maven父项目&#xff1b; 4.将复制好的的Maven子项目粘贴到Maven父项目中&#xff1b; 5.选中子项目的pom文件&#xff0c;右键选择…

apk反编译修改教程系列-----修改apk 解除软件限制功能 实例操作步骤解析_5【二十四】

解除apk功能 限制主要是一些app只有付费或者开通vip才可以使用所有功能。这些对于热爱反编译的你是不是比较愤慨,今天继续以一款app为大家来演示如何去除软件的限制功能。教程的目的主要是学习反编译的基础修改方法,了解app的修改步骤以及基础的入门修改常识。 反编译工具:…

无人机无人车固态锂电池技术详解

随着无人机和无人车技术的飞速发展&#xff0c;对高性能、高安全性电池的需求日益迫切。固态锂电池作为下一代电池技术的代表&#xff0c;正逐步从实验室走向市场&#xff0c;为无人机和无人车等应用领域带来革命性的变化。相比传统液态锂电池&#xff0c;固态锂电池在能量密度…

C++中的二维数组

引言 C语言的二维数组可直接用【】【】建立&#xff0c;C的数组更多实用vector<int>表示&#xff0c;那二维数组如何表示呢&#xff1f; 表示法 解读 vector<int>的含义是。 申请了一个连续空间vector&#xff0c;里面的数据是一个个的int vector<vector&l…

Spring - 解析 统一数据格式返回以及统一异常处理

接上篇文章的统一数据格式返回… 文章目录 1. 统一异常处理1.1 使用 2. 统一数据返回和统一异处理是怎么实现的2.1 initHandleAdapters2.2 initHandleExceptionResolvers 1. 统一异常处理 1.1 使用 统一异常处理的两个关键的注解是ControllerAdvice ExceptionHandler Contro…

C++入门基本语法(2)

一、引用 1、基本概念与定义 引用不是新定义一个变量&#xff0c;而是给已存在的变量起一个别名&#xff0c;编译器不会为引用变量开辟内存空间&#xff0c;它和它所引用的变量公用同一块内存空间&#xff1b; 引用的写法&#xff1a;变量类型& 引用别名 变量&#xff…

第六周:机器学习

目录 摘要 Abstract 一、深度学习的优化算法 1、SGD 2、SGDM 3、Adagrad 4、RMSProp 5、Adam算法 二、分类器 三、卷积神经网络 总结 摘要 接着上周学习率在训练中的影响&#xff0c;本周对深度学习常见的几种优化算法做了总结&#xff0c;着重分析Adam算法的优缺…

太阳光强光照射实验在材料科学中的应用

强光照射实验方法 所谓的强光照射即使用人造太阳光模拟器设备模拟太阳光的真实光照环境。强光照射实验是一种在材料科学中常用的实验方法&#xff0c;主要用于研究材料在强烈光照条件下的稳定性、性能变化及其内在机制。实验通常涉及将材料置于特定波长和强度的光源下&#xff…

【vulnhub】DerpNStink靶机

靶机安装 下载地址&#xff1a;DerpNStink: 1 ~ VulnHub 信息收集 靶机IP扫描 nmap 192.168.93.0/24 端口扫描&#xff0c;开放21、22、80端口 nmap -A 192.168.93.158 -p- 目录扫描 dirsearch -u http://192.168.93.158 进行网址访问&#xff0c;页面上只有个单词DeRPn…

IJCAI 2024 | 时空数据(Spatial-Temporal)论文总结

2024 IJCAI&#xff08;International Joint Conference on Artificial Intelligence, 国际人工智能联合会议&#xff09;在2024年8月3日-9日在韩国济州岛举行。 本文总结了IJCAI2024有关时空数据(Spatial-temporal) 的相关论文&#xff0c;如有疏漏&#xff0c;欢迎大家补充。…

【微服务】springboot 整合 SA-Token 使用详解

目录 一、前言 二、认证与授权介绍 2.1 什么是认证 2.1.1 认证的目的 2.1.2 认证基本步骤 2.2 什么是授权 2.2.1 常用的授权模型 三、微服务中常用的认证安全框架 3.1 Spring Security 3.1.1 Spring Security 特点 3.2 JWT (JSON Web Tokens) 3.2.1 JWT特点 3.3 其…

鸿蒙笔记--Socket

这一节主要了解鸿蒙Socket通信&#xff0c;在鸿蒙系统中&#xff0c;Socket TCP通讯是一种常用的网络通信方式&#xff0c;它提供了可靠的、面向连接的数据传输服务。它主要用到ohos.net.socket这个库&#xff1b; 栗子: export default class SocketUtils {public static c…

跟《经济学人》学英文:2024年08月03日这期 How deep is Britain’s fiscal “black hole”?

How deep is Britain’s fiscal “black hole”? Rachel Reeves sets out her first big decisions as chancellor set out: 陈述&#xff0c;阐明 “Set out” 的意思是陈述、阐明或展示。在这个上下文中&#xff0c;指的是Rachel Reeves作为财政大臣阐明了她的第一个重要决…

数据结构(8):排序

1 排序的基本概念 稳定性&#xff01;&#xff01;&#xff01; 分类[内部、外部] 机械硬盘的读取是很慢的&#xff01;&#xff01;&#xff01; 总结 2 内部排序 2.1 插入排序 前面时 保存好的 是排好序的哦 一个一个检查&#xff01;然后放到改在的位置 只有小的时候换&am…