SiameseRPN原理详解(个人学习笔记)

参考资源:

  1. 视觉目标跟踪SiamRPN
  2. SiameseRPN详解
  3. CVPR2018视觉目标跟踪之 SiameseRPN

目录)

  • 1. 模型架构
    • 1.1 Siamese Network
    • 1.2 RPN
  • 2. 模型训练
    • 2.1 损失函数
    • 2.2 端到端训练
    • 2.3 正负样本选择
  • 3. 跟踪阶段
  • 总结

SiamRPN是在SiamFC的基础上进行改进而得到的一种新架构。与基础的SiamFC相比,其添加了RPN(Region Proposal Network,区域建议网络)模块,从而避免了多尺度测试(multi-scale test),并提高了执行速度,同时,RPN中对anchor box的运用使得其输出的跟踪框准确度更高。

除此之外,SiamRPN的另一个特点在于其可以基于稀疏数据来进行训练,这代表可以用更多的数据来对网络进行训练(稀疏标记的数据集所包含的数据量会比精确标记的数据集大得多),而在目标跟踪领域,更多的训练数据往往意味着更好更鲁棒的模型性能。

RPN首次被提出是在Faster R-CNN: T owards Real-Time Object Detection with Region Proposal Networks这篇文章中,也就是大名鼎鼎的Faster RCNN,可以通过阅读这篇RCNN Fast R-CNN Faster R-CNN总结(学习笔记)来详细了解其原理。

1. 模型架构

image-20240329132454923

SiamRPN的主要网络架构如上图所示,可以分为两个部分:

  • 与SiamFC一样,包括一个Siamese网络用于特征提取,分别提取模板帧和检测帧(搜索区域)的图像特征。这个步骤是用同一个CNN实现的,即backbone。也就是说,尽管在图中看起来好像分别用了两个CNN来提取特征,但是实际上模板特征提取分支和检测区域特征提取分支共用同一个CNN。

  • 提取完的特征被送入Region Proposal Network,该子网络应用anchor机制对bounding box(边界框)进行预测。anchor,也称anchor box,是预先定义好的候选边界框。我们定义一组anchor boxes,并默认这组框能够覆盖到所有状态时刻的跟踪目标。

    基于Siamese网络提取到的抽象特征,RPN网络通过分类分支来得到每一个anchor box包含跟踪目标的置信度(也就是将其分类为目标/背景),同时通过回归分支将可能包含目标的候选框(置信度高的anchor box)的位置和长宽进行微调,以使得微调后的anchor box能够完美包裹住跟踪目标(anchor是预设的,其长宽比、位置都是固定的,数量有限,因此不微调的话很难总是包裹住跟踪目标)

    有关anchor,具体可以参考这篇目标检测中的anchor机制。如果看不懂可以看这篇RCNN Fast R-CNN Faster R-CNN总结(学习笔记)中有关anchor的部分。

1.1 Siamese Network

Siamese Network,译为孪生网络,代表该子网络由两个分支组成,可以参考网络架构图。孪生网络接受两个输入,一个是template frame(模板帧),一个是detection fame(检测帧),其中,模板帧从视频的第一帧中由人工勾选出来,检测帧则是从视频流中除了第一帧以外的其它帧中crop出来的(这里是指实际推理阶段,训练阶段的模板帧和检测帧的选择方式是不同的

实际上,这两个分支的卷积神经网络共享权重(因为都是为了提取抽象特征,只不过一个是提取模板,一个是提取检测区域,所以可以共享),即,在代码实现中,只包含一个网络。

需要注意的是,Siamese子网络采用全卷积网络,即不包含padding,以满足平移不变性。关于什么是平移不变性,可以参考这篇【深入思考】卷积网络(CNN)的平移不变性和这篇卷积神经网络中的平移不变性,看了之后受益良多。

除此之外,原论文中还提到:

We use a modified AlexNet pretrained from ImageNet with the parameters of the first three convolution layers fixed and only fine-tune the last two convolution layers in Siamese-RPN. These parameters are obtained by optimizing the loss function in Eq. 5 with SGD

这里表示SiamRPN用了古老的AlexNet来进行特征提取。至于为什么不用新一点的ResNet来进行特征提取,这个原因将在SiamRPN++中提及。这里不作过多解释。

Siamese网络分别提取模板帧 z z z和检测帧 x x x的特征,并分别生成6×6×256的特征图 φ ( z ) \varphi(z) φ(z)22×22×256的特征图 φ ( x ) \varphi(x) φ(x)

1.2 RPN

从SiameseRPN结构图可以看到,RPN子网络有两个分支,一个分支叫做分类分支,另一个分支叫做回归分支。每个分支都接收 φ ( z ) \varphi(z) φ(z) φ ( x ) \varphi(x) φ(x)通过卷积层改变维度后的两个特征图作为输入。

对于分类分支,其接收 [ φ ( z ) ] c l s [\varphi(z)]_{cls} [φ(z)]cls [ φ ( x ) ] c l s [\varphi(x)]_{cls} [φ(x)]cls作为输入,对于回归分支,其接收 [ φ ( z ) ] r e g [\varphi(z)]_{reg} [φ(z)]reg [ φ ( x ) ] r e g [\varphi(x)]_{reg} [φ(x)]reg作为输入。其中,通过图中被黄色标注的3×3卷积核后, φ ( z ) \varphi(z) φ(z)分别产生了4×4×(2k×256) [ φ ( z ) ] c l s [\varphi(z)]_{cls} [φ(z)]cls4×4×(4k×256) [ φ ( z ) ] r e g [\varphi(z)]_{reg} [φ(z)]reg

这里从6×6的尺寸经过3×3的卷积核得到4×4的特征尺寸比较简单,值得注意的是特征通道从256上升到了2k×256以及4k×256。对于分类分支,之所以特征通道上升了2k倍,是因为在特征图的每个点都预设了k个anchor,分类分支预测每个anchor是背景还是目标,总共有2类,所以是从256变成了256×2k。同理,每个anchor可以用 ( x , y , w , h ) (x,y,w,h) (x,y,w,h)来描述,共有4个参数,因此,对于需要微调这4个参数的回归分支,其特征图通道从256上升成了256×4k。检测帧的特征 φ ( x ) \varphi(x) φ(x)在经过卷积层后,也被分成两个分支特征 [ φ ( x ) ] c l s [\varphi(x)]_{cls} [φ(x)]cls [ φ ( x ) ] r e g [\varphi(x)]_{reg} [φ(x)]reg,但保持通道数不变。

之后,将模板图像上全部2k个anchor的4×4×256特征与检测图像的20×20×256特征进行相关操作,从而产生分类分支响应图,对于回归分支,也是类似的操作,最终,分别生成17×17×2k的分类响应图 A w × h × 2 k c l s A^{cls}_{w\times h\times 2k} Aw×h×2kcls和17×17×4k的回归响应图 A w × h × 4 k r e g A^{reg}_{w\times h\times 4k} Aw×h×4kreg
A w × h × 2 k c l s = [ φ ( x ) ] c l s ⋆ [ φ ( z ) ] c l s A w × h × 4 k r e g = [ φ ( x ) ] r e g ⋆ [ φ ( z ) ] r e g (1) A^{cls}_{w\times h\times 2k}=[\varphi(x)]_{cls}\star[\varphi(z)]_{cls}\\ A^{reg}_{w\times h\times 4k}=[\varphi(x)]_{reg}\star[\varphi(z)]_{reg}\tag{1} Aw×h×2kcls=[φ(x)]cls[φ(z)]clsAw×h×4kreg=[φ(x)]reg[φ(z)]reg(1)
其中, ⋆ \star 代表的是卷积操作,相当于用卷积核 [ φ ( z ) ] c l s [\varphi(z)]_{cls} [φ(z)]cls [ φ ( z ) ] r e g [\varphi(z)]_{reg} [φ(z)]reg来对 [ φ ( x ) ] c l s [\varphi(x)]_{cls} [φ(x)]cls [ φ ( x ) ] r e g [\varphi(x)]_{reg} [φ(x)]reg进行卷积操作。

2. 模型训练

2.1 损失函数

在训练过程中,使用cross-entropy loss(交叉熵损失)作为分类分支的损失函数,使用smooth L1 loss作为回归分支的损失函数。交叉熵损失函数比较常见了。这里主要介绍一下smooth L1 loss:

之前说过,一个anchor可以用 ( x , y , w , h ) (x,y,w,h) (x,y,w,h)来描述,其中, x x x y y y描述了anchor的中心点坐标, w w w h h h则描述了anchor的宽和高。假设,跟踪目标的真实边界框(bounding box)为 ( T x , T y , T w , T h ) (T_x,T_y,T_w,T_h) (Tx,Ty,Tw,Th),而此时有个anchor十分接近这个边界框,其anchor box为 ( A x , A y , A w , A h ) (A_x,A_y,A_w,A_h) (Ax,Ay,Aw,Ah),那我们的回归目标则为:
δ [ 0 ] = T x − A x A w , δ [ 1 ] = T y − A y A h δ [ 2 ] = ln ⁡ T w A w , δ [ 3 ] = ln ⁡ T h A h (2) \delta [0]=\frac{T_x-A_x}{A_w},\space\space\delta [1]=\frac{T_y-A_y}{A_h}\\ \delta [2]=\ln\frac{T_w}{A_w}, \space\space\space\space\space \delta [3]=\ln\frac{T_h}{A_h}\tag{2} δ[0]=AwTxAx,  δ[1]=AhTyAyδ[2]=lnAwTw,     δ[3]=lnAhTh(2)
在这个回归目标的基础上,应用smooth L1损失,smooth L1损失为:
s m o o t h L 1 ( x , σ ) = { 0.5 σ 2 x 2 , ∣ x ∣ < 1 σ 2 ∣ x ∣ − 1 2 σ 2 , ∣ x ∣ ≥ 1 σ 2 (3) smooth_{L_1}(x,\sigma)=\begin{cases}0.5\sigma^2x^2, \space\space|x|<\frac{1}{\sigma^2} \\ |x|-\frac{1}{2\sigma^2},|x|\ge\frac{1}{\sigma^2}\tag{3} \end{cases} smoothL1(x,σ)={0.5σ2x2,  x<σ21x2σ21,xσ21(3)
其中, σ \sigma σ是控制平滑区域范围的超参数。不同的 σ \sigma σ值决定了在何处从平方损失过渡到绝对值损失。则,回归分支的损失函数为:
L r e g = ∑ i = 0 3 = s m o o t h L 1 ( δ [ i ] , σ ) (4) L_{reg}=\sum^3_{i=0}=smooth_{L_1}(\delta[i],\sigma)\tag{4} Lreg=i=03=smoothL1(δ[i],σ)(4)
最后,总的损失函数为:
l o s s = L c l s + λ L r e g (5) loss=L_{cls}+\lambda L_{reg}\tag{5} loss=Lcls+λLreg(5)
其中, λ \lambda λ是用于平衡两个分支损失的超参数。

2.2 端到端训练

训练阶段,首先应用Imagenet对Siamese子网络进行了预训练。之后,再应用Youtube-BB数据集和ILSVRC数据集对整个SiameseRPN进行了端到端的训练(基于SGD)。由于训练回归分支需要更多的数据量,因此文中提到采用了数据增强方法,如仿射变换。

除此之外,作者提到了:

We choose less anchors in tracking task than detection task by noticing that the same object in two adjacent frames won’t change much. So only one scale with different ratios of anchor is adopted and the anchor ratios we adopted are [0.33, 0.5, 1, 2, 3].

也就是说,考虑到相邻帧之间目标不会发生太大的变化,因此和传统的RPN会在特征图的每个点生成三种尺度和三种宽高比即3×3=9种anchor相比,SiameseRPN只会考虑一种尺度和5种宽高比即1×5=5种anchor,所采用的宽高比为 [ 1 3 , 1 2 , 1 , 2 , 3 ] [\frac{1}{3},\frac{1}{2},1,2,3] [31,21,1,2,3]

  1. 对于模板帧和检测帧的选取,在训练阶段,模板帧和检测帧来自于同一个视频流中的同一个目标的两帧。为了更好地学习目标的变换,模板帧和检测帧分别取自不同的帧,且这两帧之间有一定的随机间隔(间隔小于100,因为过远的间隔会导致目标的变换过大)。

  2. 假设目标的边界框(bounding box)大小为 ( w , h ) (w,h) (w,h),则我们将从全局图像中裁剪一个大小为 A × A A\times A A×A的patch作为模板帧, A A A的定义如下:
    ( w + p ) × ( h + p ) = A 2 (6) (w+p)\times(h+p)=A^2\tag{6} (w+p)×(h+p)=A2(6)
    其中, p = ( w + h ) 2 p=\frac{(w+h)}{2} p=2(w+h)。之后,裁剪得到的patch被resize到 127 × 127 127\times127 127×127大小。检测帧基于同样的方式被crop出来,但是其大小是模板帧的两倍,同时resize到 255 × 255 255\times255 255×255大小。

2.3 正负样本选择

使用IOU作为判断正负样本的标准,设置高(0.6)和低(0.3)两个阈值,正样本为IOU>0.6的anchor和其对应的ground truth,负样本则为IOU<0.3的anchor。同时,还限制了一个training pair中包含64个样本,其中正样本最多16个。

3. 跟踪阶段

在原文的第4节Tracking as one-shot detection中,作者将跟踪任务描述为了one-shot detection检测任务。首先,其在4.1节对什么是one-shot detection进行了公式化的建模,得到了下述公式:
min ⁡ W 1 n ∑ i = 1 n L ( ζ ( φ ( x i ; W ) ; φ ( z i ; W ) ) , ℓ i ) (7) \min\limits_W \frac{1}{n} \sum_{i=1}^n \mathcal{L}(\zeta (\varphi(x_i;W);\varphi(z_i;W)),\ell_i)\tag{7} Wminn1i=1nL(ζ(φ(xi;W);φ(zi;W)),i)(7)
4.1节比较好理解,这里不对公式(7)作过多解释。建议仔细阅读原文。

比较难理解的是4.1节的最后一段。我翻来覆去看了很多遍,才有一点自以为是的感悟,现分享如下:

We can now reinterpret the template branch in Siamese subnetwork as training parameters to predict the kernel of the local detection task, which is typically the learning to learn process. In this interpretation, the template branch is used to embed the category information into the kernel and the detection branch performs detection using the embedded information. During the training phase, the meta-learner doesn’t need any other supervision except the pairwise bounding box supervision. In the inference phase, Siamese framework is pruned only leaving the detection branch except the initial frame thus leading to high speed. The target patch from the first frame is sent into the template branch and the detection kernel is pre-computed so that we can perform one-shot detection in other frames. Because the local detection task is based on the category information only given by the template on initial frame, it can be viewed as one-shot detection.

首先用三种颜色标注这段话中比较重要的三个部分。对于每个部分,分别解释如下:

  1. 红色部分,直译过来是:将连体子网络中的模板分支重新解释为预测local detection task内核的训练参数

    看回到公式(1),还记得上面提到的:最终用于分类预测和回归预测的响应图是用卷积核 [ φ ( z ) ] c l s [\varphi(z)]_{cls} [φ(z)]cls [ φ ( z ) ] r e g [\varphi(z)]_{reg} [φ(z)]reg来对 [ φ ( x ) ] c l s [\varphi(x)]_{cls} [φ(x)]cls [ φ ( x ) ] r e g [\varphi(x)]_{reg} [φ(x)]reg进行卷积操作得到的吗?也就是说,这里是把模板帧的特征图当成卷积核,在检测帧的特征图上进行卷积。这里十分关键,模板帧的特征图是“卷积核”,则特征图的值就可以被理解为CNN中卷积核训练好的参数值,而特征图又是由模板分支得到的,因此,模板分支的参数相当于什么?是不是就可以相当于训练过程中咱们人工设置好的超参数?

    对吧,类比卷积神经网络的卷积核参数(训练后得到)和训练网络用的超参数(训练前人工设置得到)的关系,就可以理解这句话。并且,在训练阶段,模板分支的参数是不是会被训练?一旦训练结束,到测试阶段,模板分支的参数就固定了,基于固定的模板分支参数和不同的输入检测帧,我们可以得到不同的特征图,也就相当于,基于同样的超参数和不同的数据集,我们能够训练出不同的卷积核。看到这里应该能大概理解红色部分语句的意思了,句中的local detection task的内核其实就是指的是基于模板分支提取得到的模板帧特征图。

  2. 蓝色部分,直译过来是:在这种解释下,模板分支用于将类别信息嵌入内核,而检测分支则利用嵌入的信息执行检测

    理解了红色部分,蓝色部分就更好理解了。将类别信息融入内核指的就是模板分支提取模板帧的深度特征,然后生成特征图,即“内核”,然后,检测分支利用特征图中蕴含的深度特征,进行互相关操作,以生成响应图,来生成对anchor类别和边界框回归的预测。

  3. 橙色部分,直译过来是:在推理阶段,除初始帧外,Siamese框架只在检测分支中剪枝,因此速度很快。第一帧的目标patch被送入模板分支,并预先计算检测内核,这样我们就可以在其他帧中执行单次检测。由于local-detection task仅基于初始帧模板提供的类别信息,因此可以将其视为一次检测

    这里也很好理解,可以参考下图,在推理阶段(实际跟踪阶段),SiameseRPN只在第一帧中生成模板帧,并通过模板分支计算得到特征图,也就是local-detection的“内核”。在之后的跟踪过程中,为了保证模板的准确性,当然,也是相信深度卷积神经网络能够提取得到足够有用和准确的特征,SiamRPN不再对模板进行更新,因此只需通过模板分支计算一次模板帧的特征图。这也是为什么作者将跟踪任务视为local-detection task的原因,因为算法只使用了初始帧模板提供的类别信息

image-20240329210643452

4.2节主要是对推理过程进行了数学建模(自己看一下!很好懂!),最终,基于前 K K K个分类置信度最高的anchor boxes,和回归分支对这 K K K个anchor boxes的回归预测,得到 K K K个更精确(相较于anchor)的proposals

由于这 K K K个proposals不一定完全准确,因此作者提出了两种策略来选择保留哪些proposals:

  1. 策略一:抛弃远离中心的anchor生成的proposals,例如,只保留中心 g × g g\times g g×g区域的anchor圣成的proposals,这个策略是考虑到相邻帧间目标不会有太大的运动。实际代码中, g g g被设置为7。
  2. 策略二:使用余弦窗口和比例变化惩罚来对这 K K K个proposals进行re-rank(重新排名)。

最后,进行NMS(非极大值抑制),然后选择排名第一的proposal作为最终的输出。在确定最终边界框后,通过线性插值更新目标尺寸,以保持形状的平滑变化

总结

了解RPN和SiamFC的话,可以很容易地理解SiameseRPN的架构和核心思想。还没跑过代码,希望有时间试试。

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

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

相关文章

开源,微信小程序-超级计算器T3000 简介

笔者于四年前自学微信小程序开发&#xff0c;这个超级计算器T3000就是当时的练习作品。超级计算器T3000的功能有很多&#xff0c;其中的核心技术是矩阵计算&#xff0c;使用的工具库是math.js&#xff0c;其次是复杂运算和分式运算。关于math.js的使用&#xff0c;可以参考另一…

基于springboot的船舶维保管理系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

Kibana操作Elasticsearch教程

文章目录 简介ES文档操作创建索引查看索引创建映射字段查看映射关系字段属性详解typeindexstore 字段映射设置流程 新增数据新增会随机生成id新增自定义id智能判断 修改数据删除数据查询基本查询查询所有&#xff08;match_all&#xff09;匹配查询多字段查询词条匹配多词条精确…

可望而不可即的“人文关怀”

死亡既然是最后的归宿&#xff0c;生命的必然&#xff0c;自然也就没有必要过多地害怕了。一切顺其自然&#xff0c;交给“命运”就是了。 我参观过英国的临终关怀医院&#xff0c;这是世界上最早的一所临终关怀医院&#xff0c;已有100多年历史。 那里的大多数病人都只剩一个…

沃通国密SSL根证书入根赢达信国密浏览器

近日&#xff0c;沃通CA国密SSL根证书正式入根赢达信国密安全浏览器&#xff0c;携手推动国产密码技术应用、完善国密应用生态体系&#xff0c;也标志着沃通国密SSL证书兼容性再次得到提升&#xff0c;进一步夯实国密应用根基。 密码算法的安全性是信息安全保障的核心&#xff…

ethers.js:sign(签名)

Signers 在ethers中Signer是以太坊账户的抽象&#xff0c;可以用来签名消息和交易&#xff0c;如将签名的交易发送到以太坊网络以执行状态更改的操作。 npm install ethers5.4.0// 引入 import { ethers } from ethers签名 this.provider new ethers.providers.Web3Provider(…

数据库系统概论(超详解!!!) 第四节 关系数据库标准语言SQL(Ⅱ)

1.数据查询 SELECT [ ALL | DISTINCT] <目标列表达式>[&#xff0c;<目标列表达式>] … FROM <表名或视图名>[&#xff0c; <表名或视图名> ] … [ WHERE <条件表达式> ] [ GROUP BY <列名1> [ HAVING <条件表达式> ] ] [ ORDER BY…

设计模式——结构型——外观模式Facade

处理器类 public class Cpu {public void start() {System.out.println("处理器启动了...");} } 内存类 public class Memory {public void start() {System.out.println("内存启动了...");} } 硬盘类 public class Disk {public void start() {Syste…

主流公链 - Monero

Monero: 加密货币的隐私标杆 1. 简介 Monero&#xff08;XMR&#xff09;&#xff0c;世界语中货币的意思&#xff0c;是一种去中心化的加密货币&#xff0c;旨在提供隐私和匿名性。与比特币等公开区块链不同&#xff0c;Monero专注于隐私保护&#xff0c;使用户的交易记录和余…

系统分析师-软件开发模型总结

前言 软件工程模型也称软件开发模型。它是指软件开发全部过程、活动和任务的结构框架&#xff0c;通过该模型能清晰、直观地表达软件开发全过程&#xff0c;明确地规定要完成的主要活动和任务&#xff0c;它奠定了软件项目工作的基础 一、瀑布模型&#xff08;Waterfall Model…

罐头鱼AI传单系统说明完整版(一)|网页版视频矩阵获客系统

罐头鱼AI传单系统说明完整版&#xff08;一&#xff09; 一&#xff1a;概述 系统用于通过系统发布视频到抖音&#xff0c;通过AI加抖音关键词提供高播放量&#xff0c;可绑定多抖音号&#xff0c;管理素材&#xff0c;素材直接发布到抖音&#xff0c;Q:290615413定时发布&am…

stable diffusion如何下载预处理器?

如何下载预处理器&#xff1f; 具体位置:SD文件>extensions>sd-webui-controlnet>annotator” 把整个文件夹复制到SD的文件夹里面 里面有一个“downloads”文件夹 把这些模型复制到“downloads”文件夹里

【数据结构】顺序表习题之移除元素和合并两个有效数组

&#x1f451;个人主页&#xff1a;啊Q闻 &#x1f387;收录专栏&#xff1a;《数据结构》 &#x1f389;道阻且长&#xff0c;行则将至 前言 嗨呀&#xff0c;今天的博客是关于顺序表的两道题目&#xff0c;是力扣的移除元素和合并有序数组的题目。 一.移除…

缺省和重载.引用——初识c++

. 个人主页&#xff1a;晓风飞 专栏&#xff1a;数据结构|Linux|C语言 路漫漫其修远兮&#xff0c;吾将上下而求索 文章目录 C输入&输出cout 和cin<<>> 缺省参数全缺省半缺省应用场景声明和定义分离的情况 函数重载1.参数的类型不同2.参数的个数不同3.参数的顺…

【AI】『Suno』哎呦不错呦,AI界的周董,快来创作你的歌曲吧!

前言 &#x1f34a;缘由 Suno AI的旋风终于还是吹到了音乐圈 &#x1f3c0;事情起因&#xff1a; 朋友说他练习时长两天半&#xff0c;用Suno发布了首张AI音乐专辑。震惊之余&#xff0c;第一反应是音乐圈门槛也这么低了&#xff0c;什么妖魔鬼怪都可以进军了嘛&#xff01;…

【详细讲解MNN介绍,安装和编译】

&#x1f308;个人主页:程序员不想敲代码啊&#x1f308; &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家&#x1f3c6; &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提…

【ERP原理与应用】作业·思考题三、四

思考题三 P77第四章3&#xff0c; 6&#xff0c;8 3.生产规划的基本内容是什么&#xff1f; 生产规划是根据企业未来一段时间内预计资源可用量和市场需求量之间的平衡所制定的概括性设想是根据企业所拥有的生产能力和需求预测&#xff0c;对企业未来较长一段时间内的产品、产…

如何将录音制作成二维码?在线生成扫码听音频的二维码

录制的音频文件能做成二维码吗&#xff1f;录制的音频文件用传统的方式来传递&#xff0c;比如微信、QQ、网盘等方式会比较繁琐&#xff0c;而且用户需要接受下载之后才可以播放&#xff0c;不仅占用内存空间&#xff0c;而且不利于音频的快速传播。而生成二维码的方式可以很好…

C语言结合体和枚举的魅力展现

前言 ✨✨欢迎&#x1f44d;&#x1f44d;点赞☕️☕️收藏✍✍评论 个人主页&#xff1a;秋邱’博客 所属栏目&#xff1a;人工智能 &#xff08;感谢您的光临&#xff0c;您的光临蓬荜生辉&#xff09; 引言: 前面我们已经讲了结构体的声明&#xff0c;自引用&#xff0c;内存…

离线Linux/openEuler服务器指定本地yum仓库

1、前提准备一个预装坏境比较完整的linux镜像文件&#xff0c;本文服务器使用的是openEuler 官网&#xff1a;openEuler下载 | 欧拉系统ISO镜像 | openEuler社区官网 2、上传镜像文件至服务器 如果是集群服务器&#xff0c;上传其中一台服务器之后&#xff0c;使用scp指令将镜…