基于LoFTR_TRT项目实现LoFTR模型的trt推理与onnx推理,3060显卡下320图像30ms一组图

本博文主要记录了使用LoFTR_TRT项目将LoFTR模型导出为onnx模型,然后将onnx模型转化为trt模型。并分析了LoFTR_TRT与LoFTR的基本代码差异,但从最后图片效果来看是与官网demo基本一致的,具体可以查看上一篇博客记录。最后记录了onnx模型的使用【特征点提取、图像重叠区提取】,同时记录了在3060显卡,cuda12.1+ort17.1,输入尺寸为320x320的环境下,30ms一组图。

项目地址:https://github.com/Kolkir/LoFTR_TRT
模型地址:https://drive.google.com/drive/folders/1DOcOPZb3-5cWxLqn256AhwUVjBPifhuf

1、基本环境准备

这里要求已经安装好torch-gpu、onnxruntime-gpu环境。

1.1 下载安装tensorRT推理库

1、根据cuda版本下载最新的tensorrt,解压后,设置好环境变量即可

tensorrt下载地址:https://developer.nvidia.com/nvidia-tensorrt-8x-download

配置环境变量细节如下所示:
在这里插入图片描述

2、然后查看自己的python版本
在这里插入图片描述
3、安装与版本对应的tensorRT库

在这里插入图片描述

1.2 下载LoFTR_TRT项目与模型

下载https://github.com/Kolkir/LoFTR_TRT项目
在这里插入图片描述
下载预训练模型,https://drive.google.com/drive/folders/1DOcOPZb3-5cWxLqn256AhwUVjBPifhuf
在这里插入图片描述
将下载好的模型解压,放到项目根目录下,具体组织形式如下所示。
在这里插入图片描述

2、代码改动分析

正常LoFTR模型是无法导出为onnx模型的,为此对LoFTR_TRT-main项目代码进行分析。通过其官网说明einsum and einops were removed,可以发现其移除了einsum 与einops 操作

2.1 主流程

通过LoFTR_TRT-main中loftr\loftr.py,可以看到与原始的loftr模型forward不一样。原始loftr模型有下面的三个步骤

        self.fine_preprocess = FinePreprocess(config)self.loftr_fine = LocalFeatureTransformer(config["fine"])self.fine_matching = FineMatching()

而改动后的loftr,滤除了这三个步骤。同时对于 rearrange操作,使用了torch进行改写。此外,对于图像特征结果feat_c0, feat_f0, feat_c1, feat_f1,只使用了feat_c0与feat_c1。同时模型输出的只是原始LoFTR的中间数据 conf_matrix,需要特定后处理。

import torch
import torch.nn as nnfrom .backbone import build_backbone
from .utils.position_encoding import PositionEncodingSine
from .loftr_module import LocalFeatureTransformer
from .utils.coarse_matching import CoarseMatchingclass LoFTR(nn.Module):def __init__(self, config):super().__init__()# Miscself.config = config# Modulesself.backbone = build_backbone(config)self.pos_encoding = PositionEncodingSine(config['coarse']['d_model'],temp_bug_fix=config['coarse']['temp_bug_fix'])self.loftr_coarse = LocalFeatureTransformer(config['coarse'])self.coarse_matching = CoarseMatching(config['match_coarse'])self.data = dict()def backbone_forward(self, img0, img1):"""'img0': (torch.Tensor): (N, 1, H, W)'img1': (torch.Tensor): (N, 1, H, W)"""# we assume that data['hw0_i'] == data['hw1_i'] - faster & better BN convergencefeats_c, feats_i, feats_f = self.backbone(torch.cat([img0, img1], dim=0))feats_c, feats_f = self.backbone.complete_result(feats_c, feats_i, feats_f)bs = 1(feat_c0, feat_c1), (feat_f0, feat_f1) = feats_c.split(bs), feats_f.split(bs)return feat_c0, feat_f0, feat_c1, feat_f1def forward(self, img0, img1):""" 'img0': (torch.Tensor): (N, 1, H, W)'img1': (torch.Tensor): (N, 1, H, W)"""# 1. Local Feature CNNfeat_c0, feat_f0, feat_c1, feat_f1 = self.backbone_forward(img0, img1)# 2. coarse-level loftr module# add featmap with positional encoding, then flatten it to sequence [N, HW, C]# feat_c0 = rearrange(self.pos_encoding(feat_c0), 'n c h w -> n (h w) c')# feat_c1 = rearrange(self.pos_encoding(feat_c1), 'n c h w -> n (h w) c')feat_c0 = torch.flatten(self.pos_encoding(feat_c0), 2, 3).permute(0, 2, 1)feat_c1 = torch.flatten(self.pos_encoding(feat_c1), 2, 3).permute(0, 2, 1)feat_c0, feat_c1 = self.loftr_coarse(feat_c0, feat_c1)# 3. match coarse-levelconf_matrix = self.coarse_matching(feat_c0, feat_c1)return conf_matrixdef load_state_dict(self, state_dict, *args, **kwargs):for k in list(state_dict.keys()):if k.startswith('matcher.'):state_dict[k.replace('matcher.', '', 1)] = state_dict.pop(k)return super().load_state_dict(state_dict, *args, **kwargs)

2.2 后处理

通过对LoFTR_TRT项目中webcam.py分析,发现其输出结果依赖get_coarse_match函数,才可抽取出mkpts0, mkpts1, mconf 信息。
使用代码如下:

mkpts0, mkpts1, mconf = get_coarse_match(conf_matrix, img_size[1], img_size[0], loftr_coarse_resolution)

get_coarse_match函数的定义实现如下,有一个重要参数resolution,其值默认为16。如果需要实现c++部署,则需要将以下代码修改为c++,可以参考numcpp进行改写实现

def get_coarse_match(conf_matrix, input_height, input_width, resolution):"""Predicts coarse matches from conf_matrixArgs:resolution: imageinput_width:input_height:conf_matrix: [N, L, S]Returns:mkpts0_c: [M, 2]mkpts1_c: [M, 2]mconf: [M]"""hw0_i = (input_height, input_width)hw0_c = (input_height // resolution, input_width // resolution)hw1_c = hw0_c  # input images have the same resolutionfeature_num = hw0_c[0] * hw0_c[1]# 3. find all valid coarse matches# this only works when at most one `True` in each rowmask = conf_matrixall_j_ids = mask.argmax(axis=2)j_ids = all_j_ids.squeeze(0)b_ids = np.zeros_like(j_ids, dtype=np.long)i_ids = np.arange(feature_num, dtype=np.long)mconf = conf_matrix[b_ids, i_ids, j_ids]# 4. Update with matches in original image resolutionscale = hw0_i[0] / hw0_c[0]mkpts0_c = np.stack([i_ids % hw0_c[1], np.trunc(i_ids / hw0_c[1])],axis=1) * scalemkpts1_c = np.stack([j_ids % hw1_c[1], np.trunc(j_ids / hw1_c[1])],axis=1) * scalereturn mkpts0_c, mkpts1_c, mconf

3、模型导出

安装依赖项目:
pip install yacs
pip install pycuda #trt运行必须,ort运行可以忽略

3.1 导出配置说明

loftr\utils\cvpr_ds_config.py对应着导出模型的参数设置,主要是针对图像的宽高、BORDER_RM 、DSMAX_TEMPERATURE 等参数

from yacs.config import CfgNode as CNdef lower_config(yacs_cfg):if not isinstance(yacs_cfg, CN):return yacs_cfgreturn {k.lower(): lower_config(v) for k, v in yacs_cfg.items()}_CN = CN()
_CN.BACKBONE_TYPE = 'ResNetFPN'
_CN.RESOLUTION = (8, 2)  # options: [(8, 2)]
_CN.INPUT_WIDTH = 640
_CN.INPUT_HEIGHT = 480# 1. LoFTR-backbone (local feature CNN) config
_CN.RESNETFPN = CN()
_CN.RESNETFPN.INITIAL_DIM = 128
_CN.RESNETFPN.BLOCK_DIMS = [128, 196, 256]  # s1, s2, s3# 2. LoFTR-coarse module config
_CN.COARSE = CN()
_CN.COARSE.D_MODEL = 256
_CN.COARSE.D_FFN = 256
_CN.COARSE.NHEAD = 8
_CN.COARSE.LAYER_NAMES = ['self', 'cross'] * 4
_CN.COARSE.TEMP_BUG_FIX = False# 3. Coarse-Matching config
_CN.MATCH_COARSE = CN()_CN.MATCH_COARSE.BORDER_RM = 2
_CN.MATCH_COARSE.DSMAX_TEMPERATURE = 0.1default_cfg = lower_config(_CN)

3.2 导出onnx模型

运行export_onnx.py即可导出模型,修改weights参数可以选择要导出的预训练权重,配置prune参数的efault=True,可以导出剪枝后的模型

import argparse
from loftr import LoFTR, default_cfg
import torch
import torch.nn.utils.prune as prunedef main():parser = argparse.ArgumentParser(description='LoFTR demo.')parser.add_argument('--weights', type=str, default='weights/outdoor_ds.ckpt',help='Path to network weights.')parser.add_argument('--device', type=str, default='cuda',help='cpu or cuda')parser.add_argument('--prune', default=False, help='Do unstructured pruning')opt = parser.parse_args()print(opt)device = torch.device(opt.device)print('Loading pre-trained network...')model = LoFTR(config=default_cfg)checkpoint = torch.load(opt.weights)if checkpoint is not None:missed_keys, unexpected_keys = model.load_state_dict(checkpoint['state_dict'], strict=False)if len(missed_keys) > 0:print('Checkpoint is broken')return 1print('Successfully loaded pre-trained weights.')else:print('Failed to load checkpoint')return 1if opt.prune:print('Model pruning')for name, module in model.named_modules():# prune connections in all 2D-conv layersif isinstance(module, torch.nn.Conv2d):prune.l1_unstructured(module, name='weight', amount=0.5)prune.remove(module, 'weight')# prune connections in all linear layerselif isinstance(module, torch.nn.Linear):prune.l1_unstructured(module, name='weight', amount=0.5)prune.remove(module, 'weight')weight_total_sum = 0weight_total_num = 0for name, module in model.named_modules():# prune connections in all 2D-conv layersif isinstance(module, torch.nn.Conv2d):weight_total_sum += torch.sum(module.weight == 0)# prune connections in all linear layerselif isinstance(module, torch.nn.Linear):weight_total_num += module.weight.nelement()print(f'Global sparsity: {100. * weight_total_sum / weight_total_num:.2f}')print(f'Moving model to device: {device}')model = model.eval().to(device=device)with torch.no_grad():dummy_image = torch.randn(1, 1, default_cfg['input_height'], default_cfg['input_width'], device=device)torch.onnx.export(model, (dummy_image, dummy_image), 'loftr.onnx', verbose=True, opset_version=11)if __name__ == "__main__":main()

代码运行成功后,会在根目录下,生成 loftr.onnx
在这里插入图片描述

3.3 onnx模型转trt模型

先将前面转换好的onnx模型上传到https://netron.app/进行分析,可以发现是一个静态模型。
在这里插入图片描述
转换命令:trtexec --onnx=loftr.onnx --workspace=4096 --saveEngine=loftr.trt --fp16
具体执行效果如下所示,生成了 loftr.trt
在这里插入图片描述

4、运行模型

4.1 前置修改

修改一: utils.py 中np.long修改为np.int64,具体操作为将代码中第30行与31行修改为以下

    b_ids = np.zeros_like(j_ids, dtype=np.int64)i_ids = np.arange(feature_num, dtype=np.int64)

如果电脑没有摄像头,则需要进行下列额外代码修改

修改一: webcam.py中默认参数camid,类型修改为str,默认值修改为自己准备好的视频文件

def main():parser = argparse.ArgumentParser(description='LoFTR demo.')parser.add_argument('--weights', type=str, default='weights/outdoor_ds.ckpt',help='Path to network weights.')# parser.add_argument('--camid', type=int, default=0,#                     help='OpenCV webcam video capture ID, usually 0 or 1.')parser.add_argument('--camid', type=str, default=r"C:\Users\Administrator\Videos\风景视频素材分享_202477135455.mp4",help='OpenCV webcam video capture ID, usually 0 or 1.')

修改二:camera.py中init函数修改为以下,用于支持读取视频文件

class Camera(object):def __init__(self, index):if isinstance(index,int):#加载摄像头视频流self.cap = cv2.VideoCapture(index, cv2.CAP_V4L2)else:#加载视频self.cap = cv2.VideoCapture(index)if not self.cap.isOpened():print('Failed to open camera {0}'.format(index))exit(-1)# self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)# self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)self.thread = Thread(target=self.update, args=())self.thread.daemon = Trueself.thread.start()self.status = Falseself.frame = None

将推理时的图像分辨率修改为320x240 ,即将webcam.py中的 img_size 设置(320, 240),loftr\utils\cvpr_ds_config.py中对应的设置

_CN.INPUT_WIDTH = 320
_CN.INPUT_HEIGHT = 240

然后运行webcam.py,可以发现fps为20左右,此时硬件环境为3060显卡。与https://hpg123.blog.csdn.net/article/details/140235431中的分析一致,40ms左右处理完一张图片。
在这里插入图片描述
在这里插入图片描述

4.2 torch模型运行

直接运行 webcam.py ,可以看到fps为5
在这里插入图片描述

4.3 trt模型运行

修改webcam.py 中的trt配置,为其添加默认值 loftr.trt,具体修改如以下代码的最后一行。

def main():parser = argparse.ArgumentParser(description='LoFTR demo.')parser.add_argument('--weights', type=str, default='weights/outdoor_ds.ckpt',help='Path to network weights.')# parser.add_argument('--camid', type=int, default=0,#                     help='OpenCV webcam video capture ID, usually 0 or 1.')parser.add_argument('--camid', type=str, default=r"C:\Users\Administrator\Videos\风景视频素材分享_202477135455.mp4",help='OpenCV webcam video capture ID, usually 0 or 1.')parser.add_argument('--device', type=str, default='cuda',help='cpu or cuda')parser.add_argument('--trt', type=str, default='loftr.trt', help='TensorRT model engine path')

运行效果如下,发现fps是2,比较低,不如torch运行
在这里插入图片描述

5、onnx模型推理

章节4中是原作者实现的推理代码,这里参考https://hpg123.blog.csdn.net/article/details/137381647中的代码进行推理实现。

5.1 依赖库与前置操作

操作一:
将 博客 https://hpg123.blog.csdn.net/article/details/124824892 中的代码保存为 imgutils.py
操作二:
将 cvpr_ds_config.py中的宽高配置,修改为320x320,然后重新运行export_onnx.py,导出onnx模型

_CN.INPUT_WIDTH = 320
_CN.INPUT_HEIGHT = 320

运行后生成的模型结构如下所示
在这里插入图片描述

5.2 运行代码

将下列代码保存为onnx_infer.py ,代码中有几行是计算运行时间的,可以删除。

from imgutils import *
import onnxruntime as ort
import numpy as np
import time
def get_coarse_match(conf_matrix, input_height, input_width, resolution):"""Predicts coarse matches from conf_matrixArgs:resolution: imageinput_width:input_height:conf_matrix: [N, L, S]Returns:mkpts0_c: [M, 2]mkpts1_c: [M, 2]mconf: [M]"""hw0_i = (input_height, input_width)hw0_c = (input_height // resolution, input_width // resolution)hw1_c = hw0_c  # input images have the same resolutionfeature_num = hw0_c[0] * hw0_c[1]# 3. find all valid coarse matches# this only works when at most one `True` in each rowmask = conf_matrixall_j_ids = mask.argmax(axis=2)j_ids = all_j_ids.squeeze(0)b_ids = np.zeros_like(j_ids, dtype=np.int64)i_ids = np.arange(feature_num, dtype=np.int64)mconf = conf_matrix[b_ids, i_ids, j_ids]# 4. Update with matches in original image resolutionscale = hw0_i[0] / hw0_c[0]mkpts0_c = np.stack([i_ids % hw0_c[1], np.trunc(i_ids / hw0_c[1])],axis=1) * scalemkpts1_c = np.stack([j_ids % hw1_c[1], np.trunc(j_ids / hw1_c[1])],axis=1) * scalereturn mkpts0_c, mkpts1_c, mconfmodel_name="loftr.onnx"
model = ort.InferenceSession(model_name,providers=['CUDAExecutionProvider'])img_size=(320,320)
loftr_coarse_resolution=8
tensor2a,img2a=read_img_as_tensor_gray(r"C:\Users\Administrator\Pictures\t1.jpg",img_size,device='cpu')
tensor2b,img2b=read_img_as_tensor_gray(r"C:\Users\Administrator\Pictures\t2.jpg",img_size,device='cpu')
data={'img0':tensor2a.numpy(),'img1':tensor2b.numpy()}
conf_matrix = model.run(None,data)[0]
mkpts0, mkpts1, confidence = get_coarse_match(conf_matrix, img_size[1], img_size[0], loftr_coarse_resolution)
#-----------计算运行时间---------------------
times=10
st=time.time()
for i in range(times):conf_matrix = model.run(None,data)[0]mkpts0, mkpts1, confidence = get_coarse_match(conf_matrix, img_size[1], img_size[0], loftr_coarse_resolution)
et=time.time()
runtime=(et-st)/times
print(f"{img_size} 图像推理时间为: {runtime:.4f}")#myimshows( [img2a,img2b],size=12)import cv2 as cv
pt_num = mkpts0.shape[0]
im_dst,im_res=img2a,img2b
img = np.zeros((max(im_dst.shape[0], im_res.shape[0]), im_dst.shape[1]+im_res.shape[1]+10,3))
img[:,:im_res.shape[0],]=im_dst
img[:,-im_res.shape[0]:]=im_res
img=img.astype(np.uint8)
match_threshold=0.6
for i in range(0, pt_num):if (confidence[i] > match_threshold):pt0 = mkpts0[i].astype(np.int32)pt1 = mkpts1[i].astype(np.int32)#cv.circle(img, (pt0[0], pt0[1]), 1, (0, 0, 255), 2)#cv.circle(img, (pt1[0], pt1[1]+650), (0, 0, 255), 2)cv.line(img, pt0, (pt1[0]+im_res.shape[0], pt1[1]), (0, 255, 0), 1)
myimshow( img,size=12)import cv2
def getGoodMatchPoint(mkpts0, mkpts1, confidence,  match_threshold:float=0.5):print(mkpts0.shape,mkpts1.shape)n = min(mkpts0.shape[0], mkpts1.shape[0])srcImage1_matchedKPs, srcImage2_matchedKPs=[],[]if (match_threshold > 1 or match_threshold < 0):print("match_threshold error!")for i in range(n):kp0 = mkpts0[i]kp1 = mkpts1[i]pt0=(kp0[0].item(),kp0[1].item());pt1=(kp1[0].item(),kp1[1].item());c = confidence[i].item();if (c > match_threshold):srcImage1_matchedKPs.append(pt0);srcImage2_matchedKPs.append(pt1);return np.array(srcImage1_matchedKPs),np.array(srcImage2_matchedKPs)
pts_src, pts_dst=getGoodMatchPoint(mkpts0, mkpts1, confidence)h1, status = cv2.findHomography(pts_src, pts_dst, cv.RANSAC, 8)
im_out1 = cv2.warpPerspective(im_dst, h1, (im_dst.shape[1],im_dst.shape[0]))
im_out2 = cv2.warpPerspective(im_res, h1, (im_dst.shape[1],im_dst.shape[0]),16)
#这里 im_res和im_out1是严格配准的状态
myimshowsCL([im_dst,im_out1,im_res,im_out2],rows=2,cols=2, size=6)

此时项目的目录结构如下所示,图中画红框的是项目依赖文件
在这里插入图片描述

5.3 运行效果

代码运行速度信息如下所示,30ms一张图(3060显卡,cuda12,ort17.1【自行编译】)
在这里插入图片描述

点匹配效果如下所示,可以发现针对于近景与远景有不同的匹配关系组,对于这样的数据,是无法进行良好的图像拼接或者重叠区提取的
在这里插入图片描述
重叠区提取效果如下所示
在这里插入图片描述

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

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

相关文章

WebAssembly场景及未来

引言 从前面的文章中&#xff0c;我们已经了解了 WebAssembly&#xff08;WASM&#xff09; 的基本知识&#xff0c;演进历程&#xff0c;以及简单的使用方法。通过全面了解了WebAssembly的设计初衷和优势&#xff0c;我们接下来要知道在什么样的场景中我们会使用 WASM 呢&…

在门店里造绿色氧吧!康养行业也这么卷了?

拼啥不如拼健康&#xff0c;现在的人算是活明白了&#xff0c;不但中老年人这样想&#xff0c;年轻人也这样干。你可能不知道&#xff0c;现在众多健康养生门店&#xff0c;逐渐成了年轻人“组团养生”的好去处&#xff0c;也是他们吃喝玩乐之外的新兴消费趋势。 而在看得见的…

原理图设计工作平台:capture和capture CIS的区别在于有没有CIS模块

1环境:design entry CIS 2.参数设置命令options——preference&#xff08;7个选项卡colors/print&#xff0c;grid display&#xff0c;miscellaneous&#xff0c;pan and zoom&#xff0c;select&#xff0c;text editor和board simulation&#xff09; 1)颜色设置colors/p…

应急响应--网站(web)入侵篡改指南

免责声明:本文... 目录 被入侵常见现象: 首要任务&#xff1a; 分析思路&#xff1a; 演示案例: IIS&.NET-注入-基于时间配合日志分析 Apache&PHP-漏洞-基于漏洞配合日志分析 Tomcat&JSP-弱口令-基于后门配合日志分析 (推荐) Webshell 查杀-常规后门&…

R语言实战—圆形树状图

话不多说&#xff0c;先看最终效果&#xff1a; 圆形树状图是树状图的一个变型&#xff0c;其实都是层次聚类。 接下来看代码步骤&#xff1a; 首先要先安装两个包&#xff1a; install.packages("ggtree") install.packages("readxl") 咱就别问问什么…

go zero入门

一、goctl安装 goctl 是 go-zero 的内置脚手架&#xff0c;可以一键生成代码、文档、部署 k8s yaml、dockerfile 等。 # Go 1.16 及以后版本 go install github.com/zeromicro/go-zero/tools/goctllatest检查是否安装成功 $ goctl -v goctl version 1.6.6 darwin/amd64vscod…

vue2响应式原理+模拟实现v-model

效果 简述原理 配置对象传入vue实例 模板解析&#xff0c;遍历出所有文本节点&#xff0c;利用正则替换插值表达式为真实数据 data数据代理给vue实例&#xff0c;以后通过this.xxx访问 给每个dom节点增加观察者实例&#xff0c;由观察者群组管理&#xff0c;内部每一个键值…

sqlite 数据库 介绍

文章目录 前言一、什么是 SQLite &#xff1f;二、语法三、SQLite 场景四、磁盘文件 前言 下载 目前已经出到了&#xff0c; Version 3.46.0 SQLite&#xff0c;是一款轻型的数据库&#xff0c;是遵守ACID的关系型数据库管理系统&#xff0c;它包含在一个相对小的C库中。它是…

VMware虚拟机配置桥接网络

转载&#xff1a;虚拟机桥接网络配置 一、VMware三种网络连接方式 VMware提供了三种网络连接方式&#xff0c;VMnet0, VMnet1, Vmnet8&#xff0c;分别代表桥接&#xff0c;Host-only及NAT模式。在VMware的编辑-虚拟网络编辑器可看到对应三种连接方式的设置&#xff08;如下图…

Square Root SAM论文原理

文章目录 Square Root SAM论文原理核心原理SLAM问题的3种表示贝叶斯网络因子图&#xff08;Factor graph&#xff09;马尔科夫随机场(Markov Random Field, MRF) SLAM最小二乘问题&线性化因式分解 factorization矩阵与图(Matrices ⇔ Graphs)因式分解&变量消元(Factori…

Kafka系列之Kafka知识超强总结

一、Kafka简介 Kafka是什么 Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff08;消息引擎系统&#xff09;&#xff0c;它可以处理消费者在网站中的所有动作流数据。 这种动作&#xff08;网页浏览&#xff0c; 搜索和其他用户的行动&#xff09;是在现代网络上的许多社…

14-22 剑和远方2 - 深度神经网络中的学习机制

概论 在第一部分中&#xff0c;我们深入探讨了人工智能的兴衰简史以及推动人工智能发展的努力。我们研究了一个简单的感知器&#xff0c;以了解其组件以及简单的 ANN 如何处理数据和权重层。在简单的 ANN 中&#xff0c;不会对数据执行特定操作。ANN 中的激活函数是一个线性函…

flask使用定时任务flask_apscheduler(APScheduler)

Flask-APScheduler描述: Flask-APScheduler 是一个 Flask 扩展&#xff0c;增加了对 APScheduler 的支持。 APScheduler 有三个内置的调度系统可供您使用&#xff1a; Cron 式调度&#xff08;可选开始/结束时间&#xff09; 基于间隔的执行&#xff08;以偶数间隔运行作业…

移动校园(7)ii:uniapp响应拦截器处理token,以及微信小程序报错当前页面正在处于跳转状态,请稍后再进行跳转....

依据昨天的写完&#xff0c;在token过期之后&#xff0c;再次调用接口&#xff0c;会触发后端拦截&#xff0c;扔进全局错误处理中间件 前端说明提示都没有&#xff0c;只有一个这个&#xff0c;现在优化一下&#xff0c;再写一个类似全局后置守卫&#xff0c;当状态码是401的时…

RAID 冗余磁盘阵列

RAID也是Linux操作系统中管理磁盘的一种方式。 只有Linux操作系统才支持LVM的磁盘管理方式。 而RAID是一种通用的管理磁盘的技术&#xff0c;使用于多种操作系统。 优势&#xff1a;提升数据的读写速度&#xff0c;提升数据的可靠性。具体实现哪什么功能&#xff0c;要看你所…

LVGL移植与VS模拟器使用

一、移植文件介绍 二、移植部分 第一步&#xff1a;创建LVGL文件夹 第二步&#xff1a; 构造LVGL文件夹&#xff1a;LVGL - GUI - lvgl - 第三步&#xff1a;添加文件 3.1 从examples中添加2个.c文件 3.2 从src中添加文件 draw文件 extra文件 第四步&#xff1a; 三、Ke…

Linux系统安装软件包的方法rpm和yum详解

起因&#xff1a; 本篇文章是记录学习Centos7的历程 关于rpm 常见命令 1&#xff09;查看已经安装的软件包 rpm -q 软件包名 2&#xff09;查看文件的相关信息 rpm -qi 软件包名 3&#xff09;查看软件包的依赖关系 就是说要想安装这个软件包&#xff0c;就必须把一些前…

三级_网络技术_04_中小型网络系统总体规划与设计

1.下列关于路由器技术特征的描述中&#xff0c;正确的是()。 吞吐量是指路由器的路由表容量 背板能力决定了路由器的吞吐量 语音、视频业务对延时抖动要求较低 突发处理能力是以最小帧间隔值来衡量的 2.下列关于路由器技术特征的描述中&#xff0c;正确的是()。 路由器的…

springboot公寓租赁系统-计算机毕业设计源码03822

摘要 1 绪论 1.1 研究背景与意义 1.2选题背景 1.3论文结构与章节安排 2 公寓租赁系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分析 2.3 系统用例分析 2.4 系…

韦东山嵌入式linux系列-第一个实验

1 前言 笔者使用的是韦东山STM32MP157 Pro的板子&#xff0c;环境搭建部分按照说明文档配置完成。配置桥接网卡实现板子、windows、ubuntu的通信&#xff0c;也在开发板挂载 Ubuntu 的NFS目录 &#xff0c;这里就不再赘述了。 板子: 192.168.5.9 windows: 192.168.5.10 ubunt…