当前位置: 首页 > news >正文

第二十一周:Mask R-CNN

Mask R-CNN

  • 摘要
  • Abstract
  • 文章信息
  • 研究动机
  • Mask RCNN
    • RoIPool与RoIAlign
  • 双线性插值
  • Mask Branch(FCN)
  • 其他细节
    • Mask RCNN损失
    • Mask分支预测
  • 网络搭建
  • 创新点与不足
  • 总结

摘要

本篇博客介绍了Mask R-CNN,这是一种用于实例分割的模型,能够在目标检测的基础上实现像素级分割。其核心思想是在Faster R-CNN框架中引入一个并行的Mask分支,同时完成目标检测(分类和边界框回归)和实例分割(像素级掩码生成)。针对Faster R-CNN中RoIPool导致的特征图与原始图像空间不对齐问题,Mask R-CNN提出了RoIAlign技术,通过双线性插值消除量化误差,显著提升了分割精度。此外,Mask分支采用全卷积网络(FCN)结构,能够高效地生成目标的二值掩码。但Mask R-CNN也存在一些不足,如计算复杂度高、对小目标分割效果有限、数据需求高等。未来的改进方向包括优化模型效率(如轻量化设计)、提升小目标分割能力(如引入多尺度特征融合)以及探索无监督或弱监督学习方法以降低数据标注成本。

Abstract

This blog introduces Mask R-CNN, a model designed for instance segmentation that achieves pixel-level segmentation on top of object detection. Its core idea is to introduce a parallel Mask branch into the Faster R-CNN framework, enabling simultaneous object detection (classification and bounding box regression) and instance segmentation (pixel-level mask generation). To address the misalignment issue between feature maps and the original image caused by RoIPool in Faster R-CNN, Mask R-CNN proposes RoIAlign, which eliminates quantization errors through bilinear interpolation, significantly improving segmentation accuracy. Additionally, the Mask branch adopts a Fully Convolutional Network (FCN) structure, efficiently generating binary masks for targets. However, Mask R-CNN also has some limitations, such as high computational complexity, limited effectiveness in segmenting small objects, and high data requirements. Future improvements may include optimizing model efficiency (e.g., lightweight design), enhancing small object segmentation (e.g., multi-scale feature fusion), and exploring unsupervised or weakly supervised learning methods to reduce data annotation costs.


文章信息

Title:Mask R-CNN
Author:Kaiming He, Georgia Gkioxari, Piotr Dollar, Ross Girshick
Source:https://arxiv.org/abs/1703.06870


研究动机

在 Mask R-CNN提出之前,计算机视觉领域中的目标检测和语义分割任务的效果都取得了明显提升。语义分割是在不区分实例的情况下对每个像素进行分类。而实例分割既是语义分割,又是一种检测的形式,其目标是将每个像素分类为一类固定的类别,而不区分对象。本文为了实现简洁、快速的实例分割,将目标检测方法与语义分割方法相结合,使用目标检测来得到边界框并对边界框中的目标进行分类,再对每个边界框中的物体进行像素级分类(生成二值掩码)。

Mask RCNN

The method, called Mask R-CNN, extends Faster R-CNN by adding a branch for predicting an object mask in parallel with the existing branch for bounding box recognition.

Mask RCNN是在Faster RCNN的基础上添加一个掩码分支(FCN),用于预测每个感兴趣区域(ROI)上的分割掩码,与现有的分类和边界框回归分支并行。掩模分支是应用于每个RoI的小FCN,预测像素级的分割掩码。
在这里插入图片描述
上图是Mask RCNN网络的框架图,其中“class box”所在分支是是Faster RCNN,下面的分支扩展的掩码分支。与Faster RCNN的的区别除了添加了掩码分支外,原本的RoIPool被替换成了RoIAlign,这可以减少定位误差,二者具体对比见下文。
另外,文中给出了两种结构的Mask分支,一种是打击FPN的,一种是不带的。结构如下:
在这里插入图片描述
不带FPN结构的mask分支与 class、box 分支共用 RoIAlign 部分。
而不带FPN结构的mask分支与class、box分支不共用RoIAlign部分。在训练过程中,对于class, box分支RoIAlign将RPN(Region Proposal Network)得到的Proposals池化到7x7大小,而对于Mask分支RoIAlign将Proposals池化到14x14大小。

RoIPool与RoIAlign

Faster R-CNN was not designed for pixel-to-pixel alignment between network inputs and outputs. This is most evident in how RoIPool, the de facto core operation for attending to instances, performs coarse spatial quantization for feature extraction.

在 Faster RCNN 中,用到的是RoIPool操作,其将RPN得到的Proposal池化到固定大小。这个过程在计算中涉及取整操作,导致定位有偏差(Mask RCNN论文中称为misalignment问题)。
下面以一个例子说明RoIPool的计算流程。
在这里插入图片描述
假设通过RPN得到了一个Proposal,它在原图上的左上角坐标是(10,10),右下角的坐标是 ( 124 , 124 ) ,对应要映射的特征层相对原图的步距为32,要求通过RoIPool得到的输出大小为 2 × 2 2\times 2 2×2,具体步骤如下:

  1. 将proposal映射到特征层上,左上角计算为 ( 10 32 , 10 32 ) (\frac {10}{32},\frac {10}{32}) (3210,3210),四舍五入取整的左上角坐标为 ( 0 , 0 ) (0,0) (0,0),右下角计算为 ( 124 32 , 124 32 ) (\frac {124}{32},\frac {124}{32}) (32124,32124),四舍五入取整的右下角坐标为 ( 4 , 4 ) (4,4) (4,4)。映射到特征图上为上面的黑色框部分(第0到第4行,第0到第4列)
  2. 因为RoIPool的期望输出大小为 2 × 2 2\times 2 2×2,但第一步映射到特征图上的大小为 5 × 5 5\times 5 5×5,不能均分,所以划分后的区域又大又小。如上图所示的划分方法,每个区域的大小都不一样。
  3. 对第二步划分后的每个区域中实施maxpool操作,得到固定大小的输出,如上图蓝色区域。

其中,第一步在计算proposal映射到特征图和第二步按输出对特征图上的proposal划分区域时都涉及取整操作,可能导致定位结果有偏差,进而影响后续的检测效果。
为了解决这个问题,Mask RCNN的作者提出了用RoIAlign来代替原本的RoIPool,以获得更精确的定位信息。
RoIAlign 的计算过程其实与RoIPool相似,但其计算位置和划分区域时并不进行取整,在最后计算输出时用双线性插值法。
为方便说明二者的差别,还是以上面的假设为例,说明RoIAlign的计算过程:

在这里插入图片描述
采样率是指每个子区域采样点的个数,为方便说明这里设置为1.

  1. 将proposal映射到特征层上,左上角坐标为 ( 10 32 , 10 32 ) (\frac {10}{32},\frac {10}{32}) (3210,3210),写成小数为 ( 0.3125 , 0.3125 ) (0.3125,0.3125) (0.3125,0.3125),不进行四舍五入,同理,右下角坐标映射为 ( 3.875 , 3.875 ) (3.875,3.875) (3.875,3.875)。得到的映射图为图中大的蓝色框区域。
  2. 因为RoIPool的期望输出大小为 2 × 2 2\times 2 2×2,所以将映射的Proposal划分为2x2四个子区域,是对映射区域的均分,不使用四舍五入取整,得到的结果入图中蓝色区域中的划分。
  3. 为每个字区域分配采样点,采样点需均匀分布在子区域内。这里设置每个子区域采样一个点,即子区域的中心点。计算每个子区域中每个采样点的值(具体是用双线性插值方法计算),每个子区域内所有样本点的均值作为此子区域的输出。

RoIAlign整个计算过程中不涉及取整操作,所以其得到的特征图与原始图像得以高度对齐。
在这里插入图片描述

作者也在文中提到,将RoIPool替换成RoIAlign后,分割的Mask准确率相对提升了10%到50%(见下图d),并且将预测Mask和class进行了解耦,解耦后也带来了很大的提升(见下图b)。

双线性插值

双线性插值(bilinear interpolation),又称为双线性内插。在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。在数字图像和音频处理领域都有应用。

在图像处理中,双线性插值法考虑围绕未知像素的计算位置的 2 × 2 2\times 2 2×2 最近邻域的已知像素。然后对这4个像素进行加权平均,以得出其最终的内插值。
现对双线性插值的公式进行推导:
如下图,已知P的位置,求其像素值, 已知相邻 2 × 2 2\times 2 2×2 的像素区域对应位置和像素值,其中坐下角像素区域标号为11,左上角像素区域标号为12,右下角像素区域标号为21,右上角像素区域标号为22。
双线性插值
Q是对应像素的中心点
双线性插值计算
双线性插值其实就是目标像素值相邻四个像素的像素值加权和值。
在这里插入图片描述
当目标元素与某个相邻元素的距离越近,目标元素元素与该相邻像素的对角像素组成的矩形框面积大小就越大,该相邻像素对应的权重值就越大。

Mask Branch(FCN)

Mask分支分为带FPN和不带FPN两种,下图中左边是不带RPN的,右边是带RPN的,图中灰色部分为原Faster R-CNN预测box, class信息的分支,白色部分为Mask分支。
Mask分支
实际应用中,带FPN的Mask分支较常见,下图为其详细结构:
在这里插入图片描述
FCN是对每个像素针对每个类别都会预测一个分数,然后通过softmax得到每个类别的概率(不同类别之间存在竞争关系),哪个概率高就将该像素分配给哪个类别。但在Mask R-CNN中,作者将预测Mask和class进行了解耦,即对输入的RoI针对每个类别都单独预测一个Mask,最终根据box, cls分支预测的classes信息来选择对应类别的Mask(不同类别之间不存在竞争关系)。作者说解耦后带来了很大的提升。
另外还需要注意一个细节:训练网络的时候输入Mask分支的目标是由RPN提供的,即Proposals,但在预测的时候输入Mask分支的目标是由Fast R-CNN提供的(即预测的最终目标)。并且训练时采用的Proposals全部是Fast R-CNN阶段匹配到的正样本。

其他细节

Mask RCNN损失

Mask R-CNN的损失就是在Faster R-CNN的基础上加上了Mask分支上的损失,即:
在这里插入图片描述
Mask分支上的损失就是二值交叉熵损失(Binary Cross Entropy)。
如下图所示,假设通过RPN得到了一个Proposal(图中黑色的矩形框),通过RoIAlign后得到对应的特征信息(shape为14x14xC),接着通过Mask Branch预测每个类别的Mask信息得到图中的logits(logits通过sigmoid激活函数后,所有值都被映射到0至1之间,是网络预测的输出)。通过Fast R-CNN分支正负样本匹配过程我们能够知道该Proposal的GT类别为猫(cat),所以将logits中对应类别猫的预测mask(shape为28x28)提取出来。然后根据Proposal在原图对应的GT上裁剪并缩放到28x28大小,得到图中的GT mask(对应目标区域为1,背景区域为0)。最后计算logits中预测类别为猫的mask与GT mask的BCELoss(BinaryCrossEntropyLoss)即可。
在这里插入图片描述

Mask分支预测

在真正预测推理的时候,输入Mask分支的目标是由Fast R-CNN分支提供的。
在这里插入图片描述
如上图所示,首先,通过Fast R-CNN分支生成目标的边界框信息和类别预测结果。随后,将这些边界框信息输入到Mask分支中,生成目标的logits(未归一化的概率值)。根据Fast R-CNN分支提供的类别信息,从logits中提取出对应类别的Mask(形状为28x28,经过sigmoid激活函数处理后,其值范围在0到1之间)。接下来,使用双线性插值将Mask缩放到与预测边界框相同的尺寸,并将其映射到原始图像中的对应区域。为了将Mask转换为二值图,设定一个阈值(通常为0.5),将大于阈值的区域标记为前景,其余区域标记为背景。最终,对于每个检测到的目标,可以在原始图像中绘制出其边界框、类别标签以及对应的Mask信息。

网络搭建

  1. 骨干网络搭建,使用 ResNet50 作为骨干网络,并结合 FPN(Feature Pyramid Network)提取多尺度特征。
class Backbone(nn.Module):def __init__(self):super(Backbone, self).__init__()# 加载预训练的 ResNet50resnet = resnet50(pretrained=True)# 提取 ResNet 的前四个阶段(去掉最后的全连接层和平均池化层)self.layer0 = nn.Sequential(resnet.conv1, resnet.bn1, resnet.relu, resnet.maxpool)self.layer1 = resnet.layer1self.layer2 = resnet.layer2self.layer3 = resnet.layer3self.layer4 = resnet.layer4def forward(self, x):# 提取多尺度特征c1 = self.layer0(x)  # [batch_size, 256, H/4, W/4]c2 = self.layer1(c1)  # [batch_size, 512, H/8, W/8]c3 = self.layer2(c2)  # [batch_size, 1024, H/16, W/16]c4 = self.layer3(c3)  # [batch_size, 2048, H/32, W/32]return c1, c2, c3, c4
  1. 搭建FPN(Feature Pyramid Network),用于生成多尺度的特征金字塔。
class FPN(nn.Module):def __init__(self, in_channels_list, out_channels):super(FPN, self).__init__()# 定义 lateral 和 output 卷积层self.lateral_convs = nn.ModuleList()self.output_convs = nn.ModuleList()for in_channels in in_channels_list:self.lateral_convs.append(nn.Conv2d(in_channels, out_channels, kernel_size=1))self.output_convs.append(nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1))def forward(self, c1, c2, c3, c4):# 自顶向下生成特征金字塔p4 = self.lateral_convs[3](c4)  # [batch_size, 256, H/32, W/32]p3 = self.lateral_convs[2](c3) + F.interpolate(p4, scale_factor=2, mode="nearest")  # [batch_size, 256, H/16, W/16]p2 = self.lateral_convs[1](c2) + F.interpolate(p3, scale_factor=2, mode="nearest")  # [batch_size, 256, H/8, W/8]p1 = self.lateral_convs[0](c1) + F.interpolate(p2, scale_factor=2, mode="nearest")  # [batch_size, 256, H/4, W/4]# 对每个金字塔层进行输出卷积p4 = self.output_convs[3](p4)p3 = self.output_convs[2](p3)p2 = self.output_convs[1](p2)p1 = self.output_convs[0](p1)return p1, p2, p3, p4
  1. 搭建RPN(Region Proposal Network),用于生成候选区域。
class RPN(nn.Module):def __init__(self, in_channels, num_anchors):super(RPN, self).__init__()# 定义 RPN 的卷积层self.conv = nn.Conv2d(in_channels, in_channels, kernel_size=3, padding=1)# 定义分类头和回归头self.cls_logits = nn.Conv2d(in_channels, num_anchors, kernel_size=1)self.bbox_pred = nn.Conv2d(in_channels, num_anchors * 4, kernel_size=1)def forward(self, x):# 前向传播x = self.conv(x)logits = self.cls_logits(x)  # 分类分数bbox_deltas = self.bbox_pred(x)  # 边界框偏移量return logits, bbox_deltas
  1. 搭建RoIAlign(Region of Interest Align),用于将候选区域映射到固定大小的特征图。
class RoIAlign(nn.Module):def __init__(self, output_size):super(RoIAlign, self).__init__()self.output_size = output_sizedef forward(self, features, rois):# 使用 RoIAlign 操作return ops.roi_align(features, rois, self.output_size)
  1. 搭建Head Network(头部网络),包括分类头、边界框回归头和掩码头。
class RoIAlign(nn.Module):def __init__(self, output_size):super(RoIAlign, self).__init__()self.output_size = output_sizedef forward(self, features, rois):# 使用 RoIAlign 操作return ops.roi_align(features, rois, self.output_size)
class MaskRCNNHead(nn.Module):def __init__(self, in_channels, num_classes):super(MaskRCNNHead, self).__init__()# 定义卷积层self.conv1 = nn.Conv2d(in_channels, 256, kernel_size=3, padding=1)self.conv2 = nn.Conv2d(256, 256, kernel_size=3, padding=1)self.conv3 = nn.Conv2d(256, 256, kernel_size=3, padding=1)# 定义输出卷积层self.mask_pred = nn.Conv2d(256, num_classes, kernel_size=1)def forward(self, x):# 前向传播x = torch.relu(self.conv1(x))x = torch.relu(self.conv2(x))x = torch.relu(self.conv3(x))masks = self.mask_pred(x)  # 掩码预测return masks
  1. 完整的Mask RCNN模型:
class MaskRCNN(nn.Module):def __init__(self, num_classes):super(MaskRCNN, self).__init__()# Backbone + FPNself.backbone = Backbone()self.fpn = FPN(in_channels_list=[256, 512, 1024, 2048], out_channels=256)# RPNself.rpn = RPN(in_channels=256, num_anchors=9)# RoIAlignself.roi_align = RoIAlign(output_size=7)# Head Networkself.fast_rcnn_head = FastRCNNHead(in_channels=256, num_classes=num_classes)self.mask_rcnn_head = MaskRCNNHead(in_channels=256, num_classes=num_classes)def forward(self, x):# 提取特征c1, c2, c3, c4 = self.backbone(x)p1, p2, p3, p4 = self.fpn(c1, c2, c3, c4)# RPN 生成候选区域rpn_logits, rpn_bbox_deltas = self.rpn(p4)# RoIAlignrois = self.generate_rois(rpn_bbox_deltas)  # 生成候选区域roi_features = self.roi_align(p4, rois)# Head Networkcls_logits, bbox_deltas = self.fast_rcnn_head(roi_features)masks = self.mask_rcnn_head(roi_features)return cls_logits, bbox_deltas, masksdef generate_rois(self, bbox_deltas):# 生成候选区域(这里简化实现)return torch.rand(10, 4)  # 假设生成 10 个候选区域

创新点与不足

Mask RCNN在Faster R-CNN的基础上增加了一个并行的Mask分支,用于生成每个目标的像素级分割掩码,实现了目标检测与实例分割的统一框架。用RoIAlign替代RoIPool,解决了特征图与原始图像之间的空间不对齐问题,显著提升了分割精度。另外,Mask分支的计算开销小,且模型设计灵活,可扩展至其他任务(如人体姿态估计、关键点检测)。
但由于增加了Mask分支和RoIAlign操作,推理速度较慢,难以满足实时性要求高的场景。而且对于小目标或密集目标,Mask分支的分割精度可能下降,尤其是当目标边界不清晰时。

总结

Mask R-CNN通过结合目标检测和像素级分割,实现了高效的实例分割,其核心创新在于引入Mask分支和RoIAlign层。Mask R-CNN的实现流程分为以下几个步骤:首先,通过主干网络(如ResNet-FPN)提取多尺度特征图;接着,利用区域建议网络(RPN)生成候选区域;然后,通过RoIAlign技术将候选区域映射到特征图上,并提取固定大小的特征;最后,分别通过分类分支、回归分支和Mask分支生成目标的类别、边界框和像素级掩码。尽管存在计算复杂度高、对小目标处理能力有限等不足,但其高精度和灵活性使其在计算机视觉领域得到了广泛应用。后续研究(如PointRend、CondInst等)针对其不足进行了进一步优化,推动了实例分割技术的发展。

相关文章:

第二十一周:Mask R-CNN

Mask R-CNN 摘要Abstract文章信息研究动机Mask RCNNRoIPool与RoIAlign 双线性插值Mask Branch(FCN)其他细节Mask RCNN损失Mask分支预测 网络搭建创新点与不足总结 摘要 本篇博客介绍了Mask R-CNN,这是一种用于实例分割的模型,能够在目标检测的基础上实现…...

特朗普政府将开展新网络攻击

近日,特朗普政府已表态:减少物理战争,网络战将代替,以实现美国的全球优势。 特朗普也指示美国网络司令部可以在没有总统批准的情况下开展更广泛行动,尤其是应对一些突发事件,这其实成为了后续美国通过网络…...

Android Studio:视图绑定的岁月变迁(2/100)

一、博文导读 本文是基于Android Studio真实项目,通过解析源码了解真实应用场景,写文的视角和读者是同步的,想到看到写到,没有上帝视角。 前期回顾,本文是第二期。 private Unbinder mUnbinder; 只是声明了一个 接口…...

【已解决】黑马点评项目Redis版本替换过程的数据迁移

黑马点评项目Redis版本替换过程的数据迁移 【哭哭哭】附近商户中需要用到的GEO功能只在Redis 6.2以上版本生效 如果用的是老版本,美食/KTV的主页能正常返回,但无法显示内容 上次好不容易升到了5.0以上版本,现在又用不了了 Redis 6.2的windo…...

Maven运行任何命令都报错“Internal error: java.lang.ArrayIndexOutOfBoundsException”

今天遇到一个奇怪的问题,在maven工程下运行任何mvn命令都报“Internal error: java.lang.ArrayIndexOutOfBoundsException”错误,具体错误如下: $ mvn install [INFO] Scanning for projects... [ERROR] Internal error: java.lang.ArrayInd…...

电商平台爬虫开发技术分享:多年的实战经验总结

在当今数字化时代,电商平台的数据蕴含着巨大的商业价值。作为一名从事电商平台爬虫开发的工程师,我深知数据抓取的重要性及其技术挑战。经过多年的实践,我积累了一些宝贵的经验,愿意在这里与大家分享,希望能为同行们提…...

大模型训练策略与架构优化实践指南

标题:大模型训练策略与架构优化实践指南 文章信息摘要: 该分析全面探讨了大语言模型训练、架构选择、部署维护等关键环节的优化策略。在训练方面,强调了pre-training、mid-training和post-training的不同定位与目标;在架构选择上…...

DeepSeek-R1 蒸馏模型及如何用 Ollama 在本地运行DeepSeek-R1

在人工智能飞速发展的领域中,大型语言模型(LLMs)的出现可谓是一项重大变革。在这些模型里,DeepSeek - R1 及其蒸馏模型备受瞩目,它们融合了独特的能力与高可用性。今天我们一起聊一下 DeepSeek - R1 蒸馏模型究竟是什么…...

机器学习 ---逻辑回归

逻辑回归是属于机器学习里面的监督学习,它是以回归的思想来解决分类问题的一种非常经典的二分类分类器。由于其训练后的参数有较强的可解释性,在诸多领域中,逻辑回归通常用作 baseline 模型,以方便后期更好的挖掘业务相关信息或提…...

虚幻浏览器插件 UE与JS通信

温馨提示:本节内容需要结合插件Content下的2_Communication和Resources下的sample.html 一起阅读。 1. UE调用JS 1.1 JS脚本实现 该部分共两步: 导入jstote.js脚本实现响应函数并保存到 ue.interface 中 jsfunc 通过json对象传递参数,仅支持函数名小…...

KVM/ARM——基于ARM虚拟化扩展的VMM

1. 前言 ARM架构为了支持虚拟化做了些扩展,称为虚拟化扩展(Virtualization Extensions)。原先为VT-x创建的KVM(Linux-based Kernel Virtual Machine)适配了ARM体系结构,引入了KVM/ARM (the Linux ARM hypervisor)。KVM/ARM没有在hypervisor中引入复杂的…...

池化层Pooling Layer

1. 定义 池化是对特征图进行的一种压缩操作,通过在一个小的局部区域内进行汇总统计,用一个值来代表这个区域的特征信息,常用于卷积神经网络(CNN)中。 2. 作用 提取代表性信息的同时降低特征维度,具有平移…...

为AI聊天工具添加一个知识系统 之63 详细设计 之4:AI操作系统 之2 智能合约

本文要点 要点 AI操作系统处理的是 疑问(信念问题)、缺省(逻辑问题)和异常(不可控因素 ) 而 内核 的三大功能 (资源分配/进程管理/任务调度)以及外围的三类接口( CLI、GUI和表面模型的 运行时…...

代码随想录——二叉树(二)

文章目录 前言二叉树最大深度二叉树的最小深度翻转二叉树对称二叉树完全二叉树的节点个数平衡二叉树二叉树的所有路径左叶子之和找左下角的值路径总和从中序与后序序列构造二叉树最大二叉树合并二叉树二叉搜索树中的搜索验证二叉搜索树二叉搜索树的最小绝对差二叉树中的众数二叉…...

一个基于Python+Appium的手机自动化项目~~

本项目通过PythonAppium实现了抖音手机店铺的自动化询价,可以直接输出excel,并带有详细的LOG输出。 1.excel输出效果: 2. LOG效果: 具体文件内容见GitCode: 项目首页 - douyingoods:一个基于Pythonappium的手机自动化项目,实现了…...

深入剖析SpringBoot启动机制:run()方法详尽解读

摘要 本文深入解析SpringBoot的启动机制,以run()方法为核心,逐步追踪并详细解释其关键步骤。首先探讨run()方法的工作原理,然后深入代码层面分析各个关键环节。文章提供刷新后钩子和启动后任务的代码示例,帮助读者理解SpringBoot源…...

deepseek v1手机端部署

在iPhone上部署DeepSeekR1 1. 安装快捷指令: 打开iPhone上的Safari浏览器,访问[这个链接](https://www.icloud.com/shortcuts/e0bc5445c39d45a78b90e1dc896cd010)下载快捷指令。 下载后,按照提示完成安装。 2. 获取并配置API Key&a…...

idea对jar包内容进行反编译

1.先安装一下这个插件java Bytecode Decompiler 2.找到这个插件的路径,在idea的plugins下面的lib文件夹内:java-decompiler.jar。下面是我自己本地的插件路径,以作参考: D:\dev\utils\idea\IntelliJ IDEA 2020.1.3\plugins\java-d…...

KMP算法原理 JAVA实现

KMP算法原理 JAVA实现 一、什么是KMP算法二、为什么需要KMP算法1. 算法背景1.1 暴力匹配过程1.2 暴力匹配的优劣 2. KMP算法的诞生3. next数组3.1 kmp算法的关键 三、求解KMP 一、什么是KMP算法 实际上KMP只是发明这个算法的三个人的英文名首字母短称,KMP本身无意义…...

利用Redis实现数据缓存

目录 1 为啥要缓存捏? 2 基本流程(以查询商铺信息为例) 3 实现数据库与缓存双写一致 3.1 内存淘汰 3.2 超时剔除(半自动) 3.3 主动更新(手动) 3.3.1 双写方案 3.3.2 读写穿透方案 3.3.…...

基于 RAMS 的数据驱动建模与应用实践:从理论到具体操作

基于 RAMS 的数据驱动建模与应用实践:从理论到具体操作 RAMS(区域大气建模系统)因其模块化设计、高分辨率模拟能力和广泛的应用领域,成为区域大气建模的强大工具。而数据驱动建模技术的崛起,使得 RAMS 的能力得到进一…...

计算机图形学实验练习(实验1.2-4.1AND补充实验12)

实验1.2 OpenGL与着色器编程 1.理论知识 1.1 OpenGL的含义 OpenGL是一种应用程序编程接口(Application Programming Interface,API),它是一种可以对图形硬件设备特性进行访问的软件库。OpenGL最新的4.3版本包含了超过500个不同的命令,可以用于设置所需的对象、图像和操…...

javascript-es6 (一)

作用域(scope) 规定了变量能够被访问的“范围”,离开了这个“范围”变量便不能被访问 局部作用域 函数作用域: 在函数内部声明的变量只能在函数内部被访问,外部无法直接访问 function getSum(){ //函数内部是函数作用…...

uni-app 程序打包 Android apk、安卓夜神模拟器调试运行

1、打包思路 云端打包方案(每天免费次数限制5,最简单,可以先打包尝试一下你的程序打包后是否能用): HBuilderX 发行App-Android云打包 选择Android、使用云端证书、快速安心打包本地打包: HBuilderX …...

yolov11 解读简记

1 文章详细介绍了YOLOv11的架构设计,包括以下几个关键组件: C3k2块:这是YOLOv11引入的一种新型卷积块,替代了之前版本中的C2f块。C3k2块通过使用两个较小的卷积核代替一个大的卷积核,提高了计算效率,同时保…...

CommonAPI学习笔记-1

CommonAPI学习笔记-1 一. 整体结构 CommonAPI分为两层:核心层和绑定层,使用了Franca来描述服务接口的定义和部署,而Franca是一个用于定义和转换接口的框架(https://franca.github.io/franca/)。 ​ 核心层和通信中间…...

从入门到精通:RabbitMQ的深度探索与实战应用

目录 一、RabbitMQ 初相识 二、基础概念速览 (一)消息队列是什么 (二)RabbitMQ 核心组件 三、RabbitMQ 基本使用 (一)安装与环境搭建 (二)简单示例 (三)…...

深入理解若依RuoYi-Vue数据字典设计与实现

深入理解若依数据字典设计与实现 一、Vue2版本主要文件目录 组件目录src/components:数据字典组件、字典标签组件 工具目录src/utils:字典工具类 store目录src/store:字典数据 main.js:字典数据初始化 页面使用字典例子&#xf…...

Cursor 帮你写一个小程序

Cursor注册地址 首先下载客户端 点击链接下载 1 打开微信开发者工具创建一个小程序项目 选择TS-基础模版 官方 2 然后使用Cursor打开小程序创建的项目 3 在CHAT聊天框输入自己的需求 比如 小程序功能描述:吃什么助手 项目名称: 吃什么小程序 功能目标…...

进程控制的学习

目录 1.进程创建 1.1 fork函数 1.2 fork函数返回值 1.3 写时拷贝 1.4 fork 常规用法 1.5 fork 调用失败的原因 2. 进程终止 2.1 进程退出场景 2.2 进程常见退出方法 2.2.1 从main 返回 2.2.2 echo $? 查看进程退出码 2.2.2.1 我们如何得到退出码代表的含…...

一文讲解Java中的接口和抽象类

抽象类和接口有什么区别? 一个类只能继承一个抽象类;但一个类可以实现多个接口。所以我们在新建线程类的时候,一般推荐使用Runnable接口的方式,这样线程类还可以继承其他类,而不单单是Thread类;抽象类符合…...

Vue 3 30天精进之旅:Day 05 - 事件处理

引言 在前几天的学习中,我们探讨了Vue实例、计算属性和侦听器。这些概念为我们搭建了Vue应用的基础。今天,我们将专注于事件处理,这是交互式Web应用的核心部分。通过学习如何在Vue中处理事件,你将能够更好地与用户进行交互&#…...

STM32完全学习——RT-thread在STM32F407上移植

一、写在前面 关于源码的下载,以及在KEIL工程里面添加操作系统的源代码,这里就不再赘述了。需要注意的是RT-thread默认里面是会使用串口的,因此需要额外的进行串口的初始化,有些人可能会问,为什么不直接使用CubMAX直接…...

Shodan Dorks安装指南,通过Shodan搜索漏洞

Shodan Dorks是一种基于Shodan的工具,不知道Shodan是什么的不必阅读下面的内容。简单的说就是,利用预定义的查询(dorks),通过Shodan轻松搜索漏洞和机密信息。 推荐渗透测试人员自行测试。 安装方法: 1.确…...

poi在word中打开本地文件

poi版本 5.2.0 方法1:使用XWPFFieldRun(推荐) 比如打开当前相对路径的aaaaa.docx XWPFFieldRun run paragraph.createFieldRun();CTRPr ctrPr run.getCTR().addNewRPr();CTFonts font ctrPr.addNewRFonts();// 设置字体font.setAscii(&quo…...

Linux查看服务器的内外网地址

目录: 1、内网地址2、外网地址3、ping时显示地址与真实不一致 1、内网地址 ifconfig2、外网地址 curl ifconfig.me3、ping时显示地址与真实不一致 原因是dns缓存导致的,ping这种方法也是不准确的,有弊端不建议使用,只适用于测试…...

OAuth1和OAuth2授权协议

OAuth 1 授权协议 1. 概述 OAuth1 是 OAuth 标准的第一个正式版本,它通过 签名和令牌 的方式,实现用户授权第三方访问其资源的功能。在 OAuth1 中,安全性依赖于签名机制,无需传递用户密码。 2. 核心特性 使用 签名&#xff08…...

DeepSeek学术题目选择效果怎么样?

论文选题 一篇出色的论文背后,必定有一个“智慧的选题”在撑腰。选题足够好文章就能顺利登上高水平期刊;选题不行再精彩的写作也只能“当花瓶”。然而许多宝子们常常忽视这个环节,把大量时间花在写作上,选题时却像抓阄一样随便挑一…...

数据结构(一)顺序表和链表

目录 1. 时间复杂度和空间复杂度 2. 顺序表 3. 链表 1. 时间复杂度和空间复杂度 如何估算一个算法的效率高低一般就是使用到时间复杂度和空间复杂度; 时间复杂度是评价一个算法运行快慢的, 而空间复杂度是算法额外需要空间大小. 1.1 时间复杂度的计算: 准确来说时间复杂度是…...

单相可控整流电路——单相桥式全控整流电路

以下是关于单相桥式整流电路的介绍: 电路构成(带阻性负载的工作情况) - 二极管:是电路0的核心元件,通常采用四个同型号或根据需求选择不同型号的二极管,如1N4001、1N4007等,如图Vt1和Vt4是一对…...

DeepSeek-R1:性能对标 OpenAI,开源助力 AI 生态发展

DeepSeek-R1:性能对标 OpenAI,开源助力 AI 生态发展 在人工智能领域,大模型的竞争一直备受关注。最近,DeepSeek 团队发布了 DeepSeek-R1 模型,并开源了模型权重,这一举动无疑为 AI 领域带来了新的活力。今…...

【Maui】提示消息的扩展

文章目录 前言一、问题描述二、解决方案三、软件开发(源码)3.1 消息扩展库3.2 消息提示框使用3.3 错误消息提示使用3.4 问题选择框使用 四、项目展示 前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架,用于使用 C# 和 XAML 创建本机移…...

001 mybatis入门

文章目录 mybatis是什么ORM是什么ORM框架和MyBatis的区别#{}和${}的区别编码流程UserDaoImpl.javaUserDao.javaUser.javadb.propertiesSqlMapConfig.xmlUserMapper.xmlMybatisTest.javapom.xmluser.sql 表现层 SpringMVC 业务层 Spring 持久层 Mybatis https://mybatis.org/myb…...

tomcat的accept-count、max-connections、max-threads三个参数的含义

tomcat的accept-count、max-connections、max-threads三个参数的含义 tomcat的accept-count、max-connections、max-threads三个参数的含义 max-connections:最大连接数 最大连接数是指,同一时刻,能够连接的最大请求数 需要注意的是&#x…...

8.2 从看图识字到智能解读:GPT-4 with Vision 开启多模态 AI 新纪元

从看图识字到智能解读:GPT-4 with Vision 开启多模态 AI 新纪元 引言:AI 的多模态跃迁 随着人工智能技术的快速发展,我们正迈入一个新的智能交互时代。传统的 AI 模型主要聚焦于文本处理,而多模态 AI 模型如 GPT-4 with Vision(GPT-4V) 则能够同时处理图像和文本。GPT-4…...

.strip()用法

.strip("") 是 Python 字符串方法 strip() 的一个用法,它会去除字符串两端指定字符集中的字符。 基本语法: string.strip([chars])string: 这是你要操作的字符串。chars: 可选参数,表示你想要去除的字符集(默认为空格…...

蓝桥杯例题三

无论前方困难如何重重,我们都要坚定信念,勇往直前。面对挑战和困境,不要退缩,不要放弃,要坚持走下去。当我们感到疲惫时,要告诉自己:“我可以,我一定行!”相信自己的实力…...

关于pygame窗口输入法状态异常切换现象的分析报告

一、问题描述 1.1 需求说明 我们准备使用Pygame开发一个键盘输入测试程序,需要确保输入时窗口始终处于英文输入模式,也就是禁止中文输入; 1.2 现象描述 控制台种显示,程序在初始化时,会有两次IMM状态切换操作&…...

【JavaEE进阶】应用分层

目录 🎋序言 🍃什么是应用分层 🎍为什么需要应用分层 🍀如何分层(三层架构) 🎄MVC和三层架构的区别和联系 🌳什么是高内聚低耦合 🎋序言 通过上⾯的练习,我们学习了SpringMVC简单功能的开…...

两数相加:链表操作的基础与扩展

两数相加:链表操作的基础与扩展 引言 链表(Linked List)是一种灵活且高效的数据结构,特别适用于动态增删操作。无论是初学者还是资深程序员,链表的基本操作都是算法学习中的重要一环。而 “两数相加” 问题则是链表操…...