如何使用 OCR 和 GPT-4o mini 轻松提取收据信息
利用 OCR 和强大的 GPT-4o 迷你模型对收据进行信息提取
利用 OCR 和强大的 GPT-4o 迷你模型对收据进行信息提取
欢迎来到雲闪世界。,我将向您展示如何从收据中提取信息,并提供收据的简单图像。首先,我们将利用 OCR 从收据中提取信息。然后,此信息将发送到 GPT-4o 迷你模型进行信息提取。我在这个项目中的目标是开发一个应用程序,只需拍摄收据图像并选择哪些物品属于哪个人,它就可以帮助朋友分摊账单。本文将重点介绍此目标的信息提取部分。
动机
例如,在去餐馆后,查看收据并计算每个人的份额是一件麻烦事。我多次遇到过这个问题,因此想要一个解决方案来使这个过程更有效。因此我想到了BillSplitter应用程序。这个想法是,用户可以拍摄收据的图像,应用程序将利用 OCR 和语言模型来处理收据并提取每个项目及其相应的价格,用户可以简单地选择哪个人应该为哪个项目付款。最终,用户会收到每个人欠款金额的概览。本文将介绍如何开发此应用程序的收据处理部分,而前端部分将留待另一篇文章。这意味着本文将假设您有一张收据的图像,目标是从收据中提取每个项目及其在列表中的相应价格。稍后,可以开发一个前端应用程序来利用我们将在本文中开发的内容。
从收据中提取文本
首先,可以使用 OCR 引擎提取收据中的文本。开源 OCR 引擎不计其数,但本项目将使用EasyOCR,因为它高效且易于使用。
首先,您必须导入所需的包:
import easyocr
import cv2
import matplotlib.pyplot as plt
import requests
import torch
import pytesseract
from PIL import Image
import json
import numpy as np
您可以使用 pip 安装。请注意,要在 GPU 上运行 EasyOCR(强烈推荐,因为它可以节省大量时间),我必须使用以下命令在 GPU 上明确安装 PyTorch:
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
我在 Windows 和 CUDA 11.8 上使用了它,但如果您使用其他操作系统或 CUDA 版本,正确的命令在PyTorch 网站上。
然后我拍了一些收据的图片。您可以使用自己的收据,但如果您不愿意,也可以使用我在Google Drive上的收据,这些收据来自挪威超市。我将包含收据图片的文件夹命名为ReceiptData,并使用以下命令将图片路径加载到变量中:
img_path1 = "ReceiptData/20231016_180324.jpg""ReceiptData/20231016_180324.jpg"
img_path2 = "ReceiptData/20231010_210904.jpg"
img_path3 = "ReceiptData/20231014_182753.jpg"
img_path4 = "ReceiptData/20230917_131726.jpg"
img_path5 = "ReceiptData/20231002_190427.jpg"
我还喜欢为我正在使用的收据设置一个变量,以便于阅读和轻松更改收据。
PATH_TO_USE = img_path2
要加载 EasyOCR,您可以使用下面的代码行。请注意,如果您正在阅读不同语言的文本,您可以将no更改为您想要的语言(例如en表示英语)。您可以在此网站上找到所有可用语言及其代码名称的列表。此外,如果您不使用 GPU,您可以设置 gpu=False。
reader = easyocr.Reader(['no'], gpu=True) # this needs to run only once to load the model into memory'no'], gpu=True) # this needs to run only once to load the model into memory
然后我读取图像,将其转换为灰度以提高 OCR 性能,并运行 OCR。此外,我还将 OCR 输出合并为一个字符串。
img = cv2.imread(PATH_TO_USE)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
result = reader.readtext(img, detail=0)0)result_string = ""
for ele in result:result_string += ele + " "
如果您想查看收据,您可以这样做:
cv2.namedWindow('img', cv2.WINDOW_NORMAL)'img', cv2.WINDOW_NORMAL)
cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
恭喜,您现在已经成功从收据中提取了文本。请注意,某些 OCR 输出可能看起来像是无意义的,例如,一张收据的 OCR 输出开头看起来像:Al rema 10@@ Salaskvittering REMA 1ooo GausdAL,这自然不是最佳的。发生这种情况的原因有很多,但主要原因是收据中的文本非常小,这使得 OCR 难以辨认出所有字符。不过,正如您将在本文后面看到的那样,OCR 足够有效,可以成功从收据中提取项目。但应该注意的是,提高 OCR 质量应该是未来工作的重点。
使用 GPT-4o mini 提取信息
我花了很多时间尝试使用 Python 逻辑、正则表达式和类似方法从收据中提取信息。然而,这些方法的问题在于它们难以处理 OCR 输出的各种输出。然而,像 GPT-4o mini 这样的大型语言模型彻底改变了这一过程,既能够处理不同的输入,又能输出结构化的响应。这使得大型语言模型非常适合我们想要在这里实现的任务,即从收据的 OCR 输出中提取商品和价格。在本文中,我将使用 GPT-4o mini,尽管在这种情况下也可以使用许多其他 LLM。
首先,你应该登录或创建一个OpenAI帐户。这将为你提供访问 OpenAI API 所需的 API 密钥。你还必须输入付款方式来支付 API 请求。我建议尽快对你的账户设置消费限额,因为人们很容易开始花很多钱。然而,在收据数据上使用 GPT-4o mini 相当便宜,你可以在OpenAI 的网站上全面了解定价。
然后,您应该安全地存储 API。有几种方法可以做到这一点,但我只需创建一个如下所示的 constants.py 文件:
OPEN_AI_API_KEY = "123123123""123123123"
然后,您可以使用以下代码将密钥导入到单独的文件中:
from constants import OPEN_AI_API_KEY
OPEN_AI_API_KEY = str(OPEN_AI_API_KEY)
assert OPEN_AI_API_KEY.startswith("sk-") and OPEN_AI_API_KEY.endswith("123")
client = OpenAI(api_key=OPEN_AI_API_KEY)
请记住替换断言中的两个字符串以匹配您的 API 密钥。此断言语句可确保您使用的是正确的 API 密钥。
然后,您可以创建一个 OpenAI 客户端来使用以下命令发出 API 请求:
from openai import OpenAI
import os
client = OpenAI(api_key=OPEN_AI_API_KEY)
您可以使用以下方式发送 API 请求:
MODEL = "gpt-4o-mini""gpt-4o-mini"def prompt_gpt(prompt):return client.chat.completions.create(model=MODEL,messages=[{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": prompt}]).choices[0].message.content
然后,我使用下面的代码创建一个提示。很难找到一个有效的提示,在处理这个问题时,我特别纠结于 GPT-4o mini 提供的过长的答案。为了解决这个问题,我添加了两个句子,只用列表来回答,没有其他内容,当然,这是物品和价格的清单。最后一部分很有趣,因为我在提示本身中包含了响应的开头,我读到这可以帮助避免 LLM 过长的解释,而在这种情况下,这是不希望的。
prompt = f"Given a string of text from an OCR of a receipt. Find each item and price in the receipt, and return with a list of tuples like this: [(item1, price1), (item2, price2), ...]. Only respond with the list, and nothing else. The string is: {result_string}""Given a string of text from an OCR of a receipt. Find each item and price in the receipt, and return with a list of tuples like this: [(item1, price1), (item2, price2), ...]. Only respond with the list, and nothing else. The string is: {result_string}"
prompt += " . Sure, here is the list of items and prices: "
然后你可以使用以下命令提示 GPT-4o mini:
response = prompt_gpt(prompt)
以下是我收到的一些回复示例:
# for image 'ReceiptData/20231010_210904.jpg'
[("KylLING HotwiNGS", "57,00"), ("Iskaffe Hocca", "18,90"), ("TORTILLACHIP ZINGY", "16,90"), ("SøTPOTeT FRIES", "37,00"), ("Creamy PEANøTTSHeR", "46,00"), ("GluTEn FReE TORT", "43,90"), ("DIP TEX MEX STyLE", "40,90")]# for image 'ReceiptData/20231016_180324.jpg'
[('RISTO HOZZA _ 2PK', 89.90), ('SUPERHEL T , GROYBRøP', 35.00), ('B#REPOSE', 25.00), ('Dr Oetker', 26.97)]# for image 'ReceiptData/20231002_190427.jpg'
[('TøRKEDE APRIKOSER', 29.90), ('MANDLER', 10.90), ('Couscous', 22.40), ('FISKEBURGER HYS8TO', 53.90), ('AVOCADO 2PK', 40.00), ('GRøNNKÅL', 0.00), ('BROKKOLI', 0.00), ('GULROT BEGER 75OGR', 3.00)]
审查结果
设置好所有代码以从收据中提取信息后,是时候检查一下该方法的效果了。我将使用定性方法,逐一查看一些收据,以判断信息提取的效果。我将检查上面显示的 3 张输出图像。
第一张收据
对于这张收据,您可以看到信息提取管道能够使用正确的流程提取所有项目。我认为这非常令人印象深刻,因为图像不是非常清晰,并且图像中有很多不属于收据的背景。不幸的是,物品名称中有一些拼写错误,但我认为在这种情况下这是可以接受的,因为您仍然可以轻松了解它是什么物品。
第二张收据
在这张收据上,信息提取管道遇到了困难。前两个商品和价格是正确的,但模型给出了bærepose的错误价格(发生这种情况是因为 OCR 无法为商品选择正确的价格),这让 LLM 感到困惑。收据商品部分的最后一行是第一件商品的折扣,LLM 无法理解,并错误地输出这是一件单独的商品。我认为这是可以接受的;但是,因为模型很难理解最后一行是另一件商品的折扣,而不是商品本身。
第三张收据
对于这张收据的前四项,管道表现非常好,但不幸的是,对于剩下的四项,管道却失败了。考虑到图像更清晰,背景噪音更少,这张收据应该比前两张收据更容易,但不幸的是,实际情况并非如此。我查看了这张收据的 OCR 输出,以了解错误来自何处。前四项的输出清晰正确,而模型突然对后四项失败,这表明不正确的 OCR 输出可能会给 GPT-4o mini 带来严重问题。
了解如何改进管道
为了改进管道,我们必须了解它的弱点。如前所述,问题似乎出在 OCR 上。为了进一步研究这个问题,我们将更深入地研究 OCR 输出。EasyOCR 中的 OCR 包含两个步骤。第一步称为文本检测,它检测图像中存在文本的区域。这是通过使用边界框标记带有文本的区域来完成的。第二步称为文本识别,给定一个包含文本的边界框,它将输出边界框中存在的文本。因此,本文中实现的信息提取管道的问题可能出在两个步骤之一上。
首先,我们研究文本识别,通过打印出 OCR 找到的边界框来实现。您可以使用以下代码执行此操作。首先,运行 OCR 并让函数也返回边界框(通过设置 detail=1 而不是像我们之前所做的那样设置 detail=0 来实现)
result2 = reader.readtext(img, detail=1)1)
然后,您可以使用以下命令打印出图像的边界框:
# Loop through the results and draw bounding boxes on the original image
for (bbox, text, prob) in result2:top_left = tuple(bbox[0])bottom_right = tuple(bbox[2])# Draw the bounding box on the original imagecv2.rectangle(img, top_left, bottom_right, (0, 255, 0), 2) # Green box with thickness 2# Optionally, put the recognized text on the original imagecv2.putText(img, text, (top_left[0], top_left[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)# Now resize the image to a smaller sizescale_percent = 20 # percent of original size
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
dim = (width, height)# Resize the image
resized_img = cv2.resize(img, dim, interpolation=cv2.INTER_AREA)# Save or display the resized image with bounding boxes
cv2.imwrite('output_image_with_boxes.jpg', resized_img)
cv2.imshow('Resized Image with Bounding Boxes', resized_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
对于第三张收据,返回了下面的收据。您可以看到模型很难读取最后四件商品的价格。这导致文本识别步骤表现不佳,进而导致 GPT-4o mini 难以对收据上的商品和价格做出准确的响应。
添加图片注释,不超过 140 字(可选)
如果对第二张收据重复上述步骤,就会发现同样的问题。
解决这个问题主要有两种方法。第一步是拍摄更清晰的收据照片,使 OCR 更容易读取文本。但是,我认为第三张收据的图像非常清晰,OCR 应该能够读取它。另一种主要方法是改进 OCR,要么使用不同的 OCR 引擎(例如,PaddleOCR、Tesseract或付费 OCR 服务,如AWS Textract),要么通过微调 OCR,正如我在关于微调 EasyOCR 的文本识别部分的文章中展示的那样。请注意,在从事这个项目时,我尝试了 PaddleOCR 和 Tesseract,它们的表现都比 EasyOCR 差。
最后,我还测试了 Amazon Textract 选项以查看其有效性。以下是第二张收据的结果,您可以看到 Amazon Textract 基本上完美地定位了所有文本,使其成为从收据中提取文本的非常有效的选项。在下一节中,我将在管道中实施 AWS Textract,以查看应用程序的运行情况。
添加图片注释,不超过 140 字(可选)
使用 Textract 测试改进的解决方案
为了了解从收据中提取信息的效果如何,我将使用 AWS Textract 而不是 EasyOCR 进行 OCR。通常,我更愿意在本地使用 OCR,因为这样我可以更好地控制流程,而且使用 AI 的乐趣之一就是自己处理模型,而不仅仅是调用 API。但是,我想看看付费 OCR API 服务在这种情况下的效果如何。使用 AWS Textract 需要设置一个 AWS 账户,以便拥有访问密钥来调用 Textract API。请注意,AWS 的初始设置可能有点繁琐,主要是出于安全原因,但我向您保证,正确设置它非常值得您花时间。这是因为您将学习如何设置 AWS(一种流行的云提供商),并确保密钥的安全,这是一项需要维护的重要做法,特别是如果您开发的应用程序有很多用户。我不会在这里提供有关设置帐户的教程,但 AWS 已经为这个过程编写了一些高质量的文档,并且那里还有大量关于该主题的其他文章。
Textract 服务也相当便宜,撰写本文时的价格为每月前 100 万页 1.5 美元/1000 页,每月超过 100 万页 0.6 美元/1000 页。如果您使用检测文档文本 API,您还可以通过 AWS 免费套餐每月获得 1000 页免费页面。
设置访问凭据后,您可以使用以下代码使用 Textract API。首先,导入一些内容。请注意,我将凭据存储在名为 constants.py 的单独文件中。
import boto3
from io import BytesIO
from constants import AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION
import os
然后,您必须创建一个客户端来调用 API。
def get_aws_textract_client():return boto3.client('textract',aws_access_key_id=AWS_ACCESS_KEY_ID,aws_secret_access_key=AWS_SECRET_ACCESS_KEY,region_name=AWS_REGION)
然后我使用以下函数来调用 API。
def get_textract_text_from_image(client, image_path):assert os.path.exists(image_path), f"Image file not found: {image_path}"with open(image_path, 'rb') as document:img = bytearray(document.read())# Call Amazon Textractresponse = client.detect_document_text(Document={'Bytes': img})return responsedef extract_text_from_response(response):result_string = ""for block in response["Blocks"]:if block["BlockType"] == "WORD" or block["BlockType"] == "LINE":result_string += block["Text"] + " "return result_string
我使用以下几行调用这两个函数
response = get_textract_text_from_image(client, PATH_TO_USE)
result_string = extract_text_from_response(response)
然后,我对第三张收据运行此操作,并使用提取的文本提示 GPT-4o mini,结果如下:
[('TORKEDE APRIKOSER', 29.90), ('MANDLER', 10.90), ('COUSCOUS', 22.40), ('FISKEBURGER HYS&TO', 53.90), ('AVOCADO 2PK 320G', 34.90), ('GRONNKAL 150G', 24.90), ('BROKKOLI', 24.90), ('GULROT BEGER 750GR', 24.90)]'TORKEDE APRIKOSER', 29.90), ('MANDLER', 10.90), ('COUSCOUS', 22.40), ('FISKEBURGER HYS&TO', 53.90), ('AVOCADO 2PK 320G', 34.90), ('GRONNKAL 150G', 24.90), ('BROKKOLI', 24.90), ('GULROT BEGER 750GR', 24.90)]
如您所见,AWS Textract 和 GPT-4o mini 可以从收据中提取所有价格正确的商品,但最后一项商品的价格不正确。我也对第二张收据进行了尝试,结果得到了以下响应:
[('RISTO. MOZZA. 2PK 15%', 89.90), ('SUPERHELT GROVBROD 15%', 35.00), ('BAREPOSE 80% RESIR 25%', 4.25), ('30% Dr. Oetker', -26.97)]'RISTO. MOZZA. 2PK 15%', 89.90), ('SUPERHELT GROVBROD 15%', 35.00), ('BAREPOSE 80% RESIR 25%', 4.25), ('30% Dr. Oetker', -26.97)]
在这种情况下,AWS Textract 和 GPT-4o mini 可以完美地提取所有商品和价格。请注意,GPT-4o mini 返回的最后一件商品的价格为负数,我认为这是可以接受的,应该在应用程序的前端处理。
结论
在本文中,我向您展示了如何开发信息提取管道以从收据中检索商品和价格。我们首先实施 EasyOCR 从收据中提取文本,然后使用 GPT-4o mini 根据 OCR 输出提供商品和价格。然后,我们检查了三张单独收据的结果。检查显示,管道对某些商品表现良好,提取了正确的商品和价格,尽管商品名称有一些拼写错误。但是,管道对其他商品完全失败,这主要归因于 OCR 错误。除了 EasyOCR,我还测试了 Tesseract OCR 和 PaddleOCR,它们并没有为本文中的三张收据提供更好的结果。AWS Textract 被设置为处理 OCR 错误,它提供的结果比 EasyOCR、Tesseract 和 PaddleOCR 好得多。使用 AWS Textract 和 GPT-4o mini 的组合,我们能够非常准确地从收据中导出商品和价格。
感谢关注雲闪世界。(Aws解决方案架构师vs开发人员&GCP解决方案架构师vs开发人员)
相关文章:

如何使用 OCR 和 GPT-4o mini 轻松提取收据信息
利用 OCR 和强大的 GPT-4o 迷你模型对收据进行信息提取 利用 OCR 和强大的 GPT-4o 迷你模型对收据进行信息提取 欢迎来到雲闪世界。,我将向您展示如何从收据中提取信息,并提供收据的简单图像。首先,我们将利用 OCR 从收据中提取信息。然后&a…...

go 事务
事务处理 首先启动事务时一定要做错误判断建议在启动事务之后马上写defer方法在defer方法内对err进行判断,如果全局中有err!nil就回滚全局中err都为nil则提交事务在提交事务之后我们可以定义一个钩子函数afterCommit,来统一处理事务提交后的逻辑。 示例…...

C,数据结构,多进程线程,网络编程面试题总结
目录 1.指针数组和数组指针 2.结构体字节对齐 3.Tcp和Udp的区别 4.同步通信和异步通信的区别 5.多线程理解 6.大小端验证 7.互斥锁相关问题 8.共享内存特点 9.c中的指针 10.Gcc编译 11.Socket的了解 12.Ip地址和子网掩码如何决定网卡所在的网段 13.数据结构中栈与…...

【Cesium学习】着色器详解【待进一步总结】
在Cesium中,drawCommand 和 CustomShader 是与渲染管线和自定义渲染效果相关的两个重要概念,但它们各自有不同的作用和应用场景。下面我将分别详解这两个概念。 drawCommand drawCommand 是 Cesium 渲染引擎内部使用的一个概念,它代表了单个…...

【3】静态路由(Static routing)
目录 一、有类路由和无类路由 二、路由的基本知识 三、配置 路由的组成: 四、特殊——默认路由 五、优点和缺点 六、实验 数据通信是双向的,路由器不同的接口属于不同的广播域和冲突域 一、有类路由和无类路由 有类路由:有ABC类别之…...

阿里声音项目Qwen2-Audio的部署安装,在服务器Ubuntu22.04系统——点动科技
阿里声音项目Qwen2-Audio的部署安装,在服务器Ubuntu22.04系统——点动科技 一、ubuntu22.04基本环境配置1.1 更换清华Ubuntu镜像源1.2 更新包列表:2. 安装英伟达显卡驱动2.1 使用wget在命令行下载驱动包2.2 更新软件列表和安装必要软件、依赖2.2 卸载原有…...

RAG(检索增强生成)
RAG (Retrieval-Augmented Generation) 是一种自然语言处理的模型架构,主要用于生成性任务,如文本生成、对话系统等。RAG 将检索和生成两个任务结合起来,以提高生成结果的质量和相关性。 RAG 模型的主要思想是通过检索阶段获取相关的上下文信…...

AcWing848有向图的拓扑排序
拓扑排序的流程: 插入(a,b),表示a->b的关系,调用add(a,b),每次吧b的入度1,d[b]; 然后调用topsort,返回1表示存在拓扑序列,返回0表示不存在拓扑序列。判断是否存在拓扑…...

猫咪掉毛很严重,家中猫毛该如何清理?快来看资深铲屎官经验分享
想必铲屎官们都见识过换毛季的威力。拿我家举例,养了一只长毛,一只短毛,打扫完不用半天,家里就能重新出现不少猫毛。严重的时候,每天都要扫地机器人扫三次,拖一次。 最近两天外出,回来给它们梳…...

Midjourney进阶-反推与优化提示词(案例实操)
Midjourney中提示词是关键,掌握提示词的技巧直接决定了生成作品的质量。 当你看到一张不错的图片,想要让Midjourney生成类似的图片,却不知道如何描述画面撰写提示词,这时候Midjourney的/describe指令,正是帮助你推…...

大公报发表欧科云链署名文章:发行港元稳定币,建Web3.0新生态
欧科云链研究院资深研究员蒋照生近日与香港科技大学副校长兼香港Web3.0协会首席科学顾问汪扬、零壹智库创始人兼CEO柏亮,在大公报发布联合署名文章 ——《Web3.0洞察 / 发行港元稳定币,建Web3.0新生态》,引发市场广泛讨论。 文章就香港稳定币…...

Mybatis的一些常用知识点(面试)
什么是MyBatis? Mybatis 是⼀个半 ORM(对象关系映射)框架,它内部封装了 JDBC。 它让开发者在开发时只需要关注 SQL 语句本身,不需要花费精⼒去处理加载驱动、创建连接等繁杂的过程 缺点: SQL语句的编写⼯作量较⼤ SQ…...

stm32—ADC
1. 什么是ADC 生活中我们经常会用到ADC这种器件,比如说,当我们在使用手机进行语音通信时,ADC器件会将我们的声信号转换为电信号 (模拟信号 ---> 数字信号) 模拟信号: 模拟信号是指用连续变化的物理量表示的信息,其信…...

【微信小程序】吐槽生态之云开发服务端能力不足
回想起来,笔者开发小程序的经历也有4年多了,以前因为技术积累接触不到比较深层次的东西,也不理解软件生态这个概念,现在开发小程序的过程中,越来越觉得很多生态微信的进步空间很大。 问题引入 比如说,在迭…...

AnimateDiff论文解读
GitHub - Kosinkadink/ComfyUI-AnimateDiff-Evolved: Improved AnimateDiff for ComfyUI and Advanced Sampling Support 视频编码 定义: 首先,将视频数据转换为一系列的潜变量代码(latent codes)。这是通过一个预训练的自动编码器(auto-encoder)来完成的。操作: …...

C/C++控制台贪吃蛇游戏的实现
🚀欢迎互三👉:程序猿方梓燚 💎💎 🚀关注博主,后期持续更新系列文章 🚀如果有错误感谢请大家批评指出,及时修改 🚀感谢大家点赞👍收藏⭐评论✍ 一、…...

Linux 升级安装 Weblogic-补丁!
版本: RedHat 6.5 Weblogic 10.3.6.0 ----------------------------------------------------------------- 1.查看当前 weblogic 补丁版本 cd /weblogic/utils/bsu/ ./bsu.sh -prod_dir/weblogic/wlserver_10.3/ -statusapplied -verbose -view 2.卸载旧补丁…...

苍鹰来啦!快来看呀!NGO-BiTCN-BiGRU-Attention北方苍鹰算法优化多重双向深度学习回归预测
苍鹰来啦!快来看呀!NGO-BiTCN-BiGRU-Attention北方苍鹰算法优化多重双向深度学习回归预测 目录 苍鹰来啦!快来看呀!NGO-BiTCN-BiGRU-Attention北方苍鹰算法优化多重双向深度学习回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实…...

关于WebSocket必知必会的知识点
什么是WebSocket WebSocket是一种网络传输协议,可以在单个TCP连接上进行全双工通信,位于OSI模型的应用层。 WebSocket使得客户端和服务器之间的数据交换变得更加简单,服务器可以主动向客户端发送消息。在WebSocket API中,浏览器和…...

Go 1.19.4 Sort排序进阶-Day 12
1. 结构体(切片)排序 结构体返回的是切片。 之前学习了sort.Ints()和sort.Strings(),使用这两个sort库下面的方法,可以对int和strings进行排序。 那如果我要对自定义类型进行排序,怎么办,sort库没提供&…...

python-求距离(赛氪OJ)
[题目描述] 给你一个 1−>n 的排列,现在有一次机会可以交换两个数的位置,求交换后最小值和最大值之间的最大距离是多少?输入格式: 输入共两行。 第一行一个数 n 。 第二行 n 个数表示这个排列。输出格式: 输出一行一…...

《第二十一章 传感器与定位 - 传感器应用》
《第二十一章 传感器与定位 - 传感器应用》 在当今的移动应用开发中,充分利用设备的传感器能够为用户带来更加智能和便捷的体验。本章将重点探讨加速度传感器、方向传感器和光线传感器的应用。 一、传感器应用的重要性 随着智能手机和移动设备的普及,传感…...

Windows系统命令
Windows系统命令 Windows 系统中的命令行工具是指令式编程语言,可以用来执行各种任务、管理文件和目录、监控系统状态等。下面是一个 Windows 命令应用实例: 1. 文件操作 cd:用于改变当前目录。例如,cd Documents 将当前目录更…...

C语言函数递归
前言与概述 本文章将通过多个代码并赋予图示,详细讲解C语言函数递归的定义和函数递归的运算过程。 函数递归定义 程序调用自身的编程技巧称为递归。递归作为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法。它…...

【python数据分析11】——Pandas统计分析(分组聚合进行组内计算)
分组聚合进行组内计算 前言1、groupby方法拆分数据2、agg方法聚合数据3、apply方法聚合数据4、transform方法聚合数据5 小案例5.1 按照时间对菜品订单详情表进行拆分5.2 使用agg方法计算5.3 使用apply方法统计单日菜品销售数目 前言 依据某个或者几个字段对数据集进行分组&…...

高性能web服务器
目录 一、简介 (一)nginx-高性能的web服务端 (二)用户访问体验 二、I/O模型 (一)概念 (二)网络I/O模型 (三)阻塞型 I/O 模型 (四…...

微服务案例搭建
目录 一、案例搭建 1.数据库表 2.服务模块 二、具体代码实现如下: (1) 首先是大体框架为: (2)父模块中的pom文件配置 (3)shop_common模块,这个模块里面只需要配置pom.xml,与实体…...

SAP负库存
业务示例 在系统中,对于一些物料而言,不能立即将收到的交货输入为收货。如果要使发货无论如何都是可以过帐的,则需要允许这些物料的负库存。 负库存 发货数量大于预订数量时,过帐该发货就会出现负库存。如果由于组织原因&#…...

集团数字化转型方案(三)
集团数字化转型方案通过系统整合人工智能(AI)、大数据、云计算和物联网(IoT)技术,建立了一个全面智能化的业务管理平台,涵盖从业务流程自动化、数据驱动决策支持,到客户体验优化和供应链管理的各…...

ESP32智能设备:蓝牙音箱、AI语音助手、环境监测与调节以及智能控制,基于BLE与MQTT技术(代码详解)
本文将介绍如何实现一个功能丰富的ESP32项目,集成蓝牙音箱、AI语音助手、智能设备控制器、环境监测与调节等功能。通过本项目,您将学习到硬件设计、嵌入式编程、蓝牙技术、音频处理、人工智能与语音识别、物联网平台、数据分析及用户界面构建等技术。 一…...