深度学习-6.用于计算机视觉的深度学习
Deep Learning - Lecture 6 Deep Learning for Computer Vision
- 简介
- 深度学习在计算机视觉领域的发展时间线
- 语义分割
- 语义分割系统的类型
- 上采样层
- 语义分割的 SegNet 架构
- 软件中的SegNet 架构
- 数据标注
- 目标检测与识别
- 目标检测与识别问题
- 两阶段和一阶段目标检测与识别
- 两阶段检测器:Faster R - CNN
- 一阶段检测:YOLO
- YOLO损失函数
- 非极大值抑制(Non - maximum suppression,NMS)
- YOLO 系列模型的发展历程及主要改进点
- 实例分割
- 总结
- 引用
本节目标:
- 解释深度学习在计算机视觉中的主要用途
- 为计算机视觉设计并实现深度学习系统
本节中只是粗略介绍用于计算机视觉(computer vision, CV)的一些网络,更加详细的内容我之后会在机械视觉的课程中展示。
简介
深度学习对计算机视觉产生了重大影响。
上图展示了计算机视觉中的四个不同任务,分别以牛的图像为例:
- (a) 图像分类(Image Classification):对整个图像进行分类,判断图像中是否存在牛这一类别,这里确定图像中有牛。
- (b) 目标检测(Object Detection):不仅要检测出图像中是否存在牛,还要用边界框(如红、绿、蓝框)标出每头牛在图像中的具体位置。
- © 语义分割(Semantic Segmentation):将图像中的每个像素分配到特定的类别(这里是牛),把图像中属于牛的区域用绿色进行分割标记,不区分具体是哪头牛。
- (d) 实例分割(Instance Segmentation):在语义分割的基础上,进一步区分出不同的个体实例,每头牛用不同颜色(如红、绿、黄)进行分割和标记,并编号1、2、3 。
深度学习在计算机视觉领域的发展时间线
- 图像识别(Image Recognition):2012年出现Alexnet,2013年有ZFNet,2014年是VGGNet,2015年为GoogleNet、ResNet,2016年有MobileNet,2019年是EfficientNet,2020年为NasNet。
- 目标检测(Object Detection):2014年出现R - CNN,2015年有Fast R - CNN,2016年是Faster R - CNN、Yolo,2017年为SSD、Retinanet、Yolo - v2 。
- 语义分割(Semantic Segmentation):2015年有FCN,2016年是U - Net、SegNet,2018年为DeepLabv3+ 。
- 实例分割(Instance Segmentation):2017年出现Mask R - CNN,2018年有PANet,2019年是Yolact,2020年为Solo 。 这些模型推动了计算机视觉领域深度学习技术的发展和应用。
语义分割
语义分割是将图像的每个像素与一个类别标签相关联的过程。
语义分割系统的类型
有多种知名的语义分割系统,多数采用编码器 - 解码器架构
- 全卷积网络,如FCN(Long等人,2015年);
- 编码器 - 解码器结构,如SegNet(Badrinarayanan等人,2017年);
- 带跳跃连接的编码器 - 解码器,如U - Net(Ronneberger等人,2015年);
- 多尺度编码器 - 解码器,如DeepLabV3 +(Chen等人,2018年)。
图片下方有一个卷积编码器 - 解码器的示意图,展示了从输入RGB图像到输出分割结果的过程。
上图为一个卷积编码器 - 解码器的示意图,输入图像经过一系列我们之前学过的网络层,诸如:卷积(Conv)、批量归一化(Batch Normalisation)、ReLU 激活函数操作,还有池化(Pooling),最后和上采样(Upsampling)(这个马上学)步骤,最终通过 Softmax 得到分割结果。
上采样层
解码器系统中的上采样方法分为两类:
- 固定方法:快速、简单。
- 学习方法:训练较慢,但可能更准确。
- 最近邻法(Nearest neighbour):左侧示例图中,输入为2×2的矩阵,数值分别为1、2、3、4。通过最近邻上采样,输出为4×4的矩阵,每个小格中的数值由最近邻的输入值填充。此方法是刚刚提到的固定采样方法。
- 最大反池化法(Max Unpooling):中间示例图中,输入同样为2×2的矩阵,输出为4×4的矩阵。其中非零位置由编码器层中相应最大池化步骤的索引定义。此方法也是固定采样方法。
- 转置卷积法(Transposed Convolution):右侧示例图展示了输入2×2的矩阵(周围有零填充)通过转置卷积操作,输出为4×4的矩阵。此方法是学习方法。
语义分割的 SegNet 架构
SegNet 系统采用编码器 - 解码器架构,在解码器阶段使用最大反池化(max unpooling)
软件中的SegNet 架构
Matlab 有一个特定函数 “segnetLayers” 用于实现 SegNet 语义分割系统。
- Matlab 使用一种称为层图(layer graph,‘lgraph’)的特定结构来构建 SegNet。
- 层图对于实现具有来自多个层的输入和输出到多个层的深度网络来说是更灵活的结构。
% Create SegNet layers.
imageSize = [32 32];
numClasses = 2;
numLayers = 3;
lgraph = segnetLayers(imageSize,numClasses,numLayers)
% training data
ds = combine(imds,pxds);
% Set up training options.
options = trainingOptions('sgdm','InitialLearnRate',1e-3, ...
'MaxEpochs',20,'VerboseFrequency',10);
% Train the network
net = trainNetwork(ds,lgraph,options)
Python部分则还是之前的keras,需要手搓。
from keras.models import Model
from keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D
from keras.layers import Activation# Encoder
conv1 = Conv2D(64, 3, activation='relu', padding='same')(inputs)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
conv2 = Conv2D(128, 3, activation='relu', padding='same')(pool1)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)# Decoder
up2 = UpSampling2D(size=(2, 2))(pool2)
deconv2 = Conv2D(128, 3, activation='relu', padding='same')(up2)
up1 = UpSampling2D(size=(2, 2))(deconv2)
deconv1 = Conv2D(64, 3, activation='relu', padding='same')(up1)# Output
outputs = Conv2D(num_classes, 1, padding='same')(deconv1)
outputs = Activation('softmax')(outputs)# Create the model
model = Model(inputs, outputs)
数据标注
实施自己的计算机视觉项目时,通常需要自行标注数据。
-
在Matlab 提供了一个有用的工具 “imageLabeler”,可在命令行中输入该名称启动。
-
当然也有许多非 Matlab 的图像标注工具,包括:
- VGG 图像标注器 (VGG Image Annotator, VIA),网址为:https://www.robots.ox.ac.uk/~vgg/software/via/
- Labelme 网址为 :http://labelme.csail.mit.edu/Release3.0/ ;
- CVAT,网址为 https://www.cvat.ai/ 。
目标检测与识别
目标检测与识别是指在图像中找到一个目标,并用边界框框出,同时识别框内的物体是什么.
目标检测与识别问题
目标检测与识别是将回归和分类融合成了一个单一的问题。
- 左边是输入图像,作为检测与识别的对象来源。
- 中间是目标检测与识别系统,对输入图像进行处理分析。
- 右边是输出结果,包含了边界框(bounding box)和类别(class)。在右侧的示例图像中,用黄色框标注出了汽车,并且还标注了类别标签(class label)、中心 x x x 坐标( x − c e n t r e x - centre x−centre)、中心 y y y 坐标( y − c e n t r e y - centre y−centre)、高度(height)和宽度(width),这些信息用于精准定位和识别目标物体。
过程中的损失函数 J ( θ ) J(\theta) J(θ)为:
J ( θ ) = ∑ j = 1 m e j T e j + γ ∑ j = 1 m ∑ k = 1 K y j , k log y ^ j , k J(\theta)=\sum_{j = 1}^{m} e_{j}^{T} e_{j}+\gamma\sum_{j = 1}^{m}\sum_{k = 1}^{K} y_{j,k} \log \hat{y}_{j,k} J(θ)=j=1∑mejTej+γj=1∑mk=1∑Kyj,klogy^j,k
损失函数由两部分构成:
- 左边部分:
∑ j = 1 m e j T e j \sum_{j = 1}^{m} e_{j}^{T} e_{j} j=1∑mejTej
是边界框的平方误差损失(Bounding box squared error loss),它的作用是衡量边界框预测值和真实值之间的误差情况,其中 e j e_{j} ej 是与边界框相关的误差向量。 - 右边部分:
γ ∑ j = 1 m ∑ k = 1 K y j , k log y ^ j , k \gamma\sum_{j = 1}^{m}\sum_{k = 1}^{K} y_{j,k} \log \hat{y}_{j,k} γj=1∑mk=1∑Kyj,klogy^j,k
是分类的交叉熵损失(Classification categorical cross - entropy loss),用于衡量分类的预测结果和真实标签之间的差异。这里的 y j , k y_{j,k} yj,k 是真实标签, y ^ j , k \hat{y}_{j,k} y^j,k 是预测标签, K K K 是类别数量, γ \gamma γ 是一个用于平衡这两项损失的参数。
两阶段和一阶段目标检测与识别
目标检测与识别系统中的两种主要类型:两阶段和一阶段检测器:
- 两阶段检测器
- 特点:速度较慢,但更准确。
- 示例:Faster R - CNN。
- 流程:第一阶段生成区域建议(region proposal),第二阶段对目标进行检测和分类。
- 一阶段检测器
- 特点:速度较快,但准确性较低。
- 示例:YOLO。
- 流程:检测和目标识别在单个阶段完成。
上图展示了从2013 - 2021年一些代表性检测器的发展时间线。2013 - 2016年主要是两阶段检测器的发展,如R - CNN、Fast R - CNN、Faster R - CNN;2016 - 2021年主要是一阶段检测器的发展,如Yolo、SSD、Yolo - v2、Yolo - v3 。
两阶段检测器:Faster R - CNN
Faster R - CNN是一种流行的两阶段检测/识别系统,它使用一个单独的区域建议网络。
- 第一阶段:区域建议(Region Proposal)
- 深度学习区域建议网络(Deep Learning Region Proposa)对目标/无目标进行二分类,并生成边界框。
- 二分类的含义:在目标检测场景下,区域建议网络会在输入图像中划分出大量不同的候选区域。对于每个候选区域,它只判断两件事:这个区域里有没有目标物体。因此,输出结果只有两种状态,即 “有目标物体”(正类)和 “没有目标物体”(负类),这就是二分类。
- 输入图像首先经过深度卷积网络特征提取器(Deep Conv Net Feature Extractor),然后通过感兴趣区域最大池化(Region of Interest Max Pooling, ROI Pooling),将特征图转换为固定大小的特征向量,为后续的区域建议提供特征。
- 深度学习区域建议网络(Deep Learning Region Proposa)对目标/无目标进行二分类,并生成边界框。
- 第二阶段:目标检测/识别(Object Detection/Recognition)
- 分类层(Classification Layers)进行目标类别的预测。
- 回归层(Regression Layers)进行边界框的调整,最终输出目标的类别和精确的边界框。
相关发展
- R - CNN:仅用于类别预测的卷积深度网络。
- Fast R - CNN:深度网络用于类别和边界框预测,但不用于区域建议。
- Faster R - CNN:全深度卷积网络(但性能较慢)。
一阶段检测:YOLO
YOLO(You Only Look Once)模型基于标准卷积网络,并对输出层进行了巧妙选择。
网络结构
- 主干网络(Backbone Network):由卷积层(Conv)和最大池化层(Maxpool)组成。
- 全连接层(Fully connected x2):位于主干网络之后。
- 头部网络(Head Network):最终输出维度为 7 × 7 × 30 7\times7\times30 7×7×30 。
输出解释
-
网络将图像视作被划分为 7 × 7 7\times7 7×7的网格单元,因此输出是 7 × 7 × 30 7\times7\times30 7×7×30 。分法就像下面这样。
-
30个输出包含:
- 2个边界框,每个边界框有4个坐标值 ( x , y , w , h ) (x, y, w, h) (x,y,w,h) ,共 4 × 2 4\times2 4×2个值。
- 每个边界框对应一个置信度分数,共 1 × 2 1\times2 1×2个值。
- 所有类别(共20个类别)的预测分数。
-
对于网格单元 i , j i, j i,j ,其预测值 y ^ i , j \hat{y}_{i,j} y^i,j包含上述共30个元素,即 ( x , y , w , h , c , x , y , w , h , c , z 1 , … , z k ) (x, y, w, h, c, x, y, w, h, c, z_1, \ldots, z_k) (x,y,w,h,c,x,y,w,h,c,z1,…,zk) ,其中 x , y , w , h x, y, w, h x,y,w,h是边界框坐标和尺寸, c c c是置信度, z 1 , … , z k z_1, \ldots, z_k z1,…,zk是类别分数。
-
为什么所有类别是20个?
在早期版本的YOLO(比如YOLO v1)中,其训练和应用场景常基于PASCAL VOC数据集。PASCAL VOC数据集包含20个常见的目标类别,例如人、汽车、自行车、猫、狗等。所以模型输出会针对这20个类别进行预测,以判断每个网格单元中是否存在这些类别的目标。 -
为什么只输出两个边界框?
- 平衡计算量与检测效果:YOLO模型为了在检测速度和一定的检测精度间取得平衡。输出两个边界框可以让模型对每个网格单元内可能存在的目标提供两种不同的定位预测。这样既不会因为边界框数量过多导致计算量大幅增加、检测速度变慢,又能在一定程度上提高对目标的定位准确性。
- 目标重叠处理:在实际图像中,可能存在多个目标部分重叠的情况。两个边界框可以分别去拟合不同的目标,或者对同一个目标从不同角度进行更准确的定位。例如,当两个较小目标挨得很近时,两个边界框有可能分别对应这两个目标,从而提高检测的召回率。
-
为什么图像分为7×7?
- 计算资源与效率考量:将图像划分为7×7的网格单元,是一种对计算资源和检测效率的权衡。划分的网格数量如果过多,虽然能更精细地定位目标,但会显著增加计算量和模型的复杂度;而划分得过少,又可能无法准确捕捉目标的位置和特征。7×7的网格划分在当时被认为是一个相对合理的选择,既能在一定程度上覆盖图像中的目标,又不会使计算量过大,能够在保证一定检测效果的同时,实现较快的检测速度。
- 目标尺度适应性:对于常见的目标尺度,7×7的网格划分可以较好地适应。每个网格单元负责预测其内部或中心位于该单元内的目标,这种划分方式对于一般大小的目标能够提供较为有效的检测和定位。
那么,假如一张图片,里面我要检测3个物体,输出的边界框预测一共是多少个?对于某一个物体,应该是多少个?
- 在YOLO v1中,无论图片里有几个物体,其边界框预测数量的计算方式都是固定的:
- 输出的边界框预测总数:由于YOLO v1将图像划分为7×7的网格,每个网格单元输出2个边界框,所以不管图片中要检测的物体是3个还是更多,输出的边界框预测总数都是7×7×2=98个。
- 对于某一个物体的边界框预测:每个物体可能会由一个或多个网格单元负责检测,每个相关网格单元都会输出2个边界框来尝试对该物体进行定位。比如一个物体可能横跨了4个网格单元,那么就会有4×2=8个边界框预测与这个物体相关,但最终会通过置信度和非极大值抑制等方法筛选出最能准确代表这个物体的边界框。
- YOLO v2和YOLO v3:引入了锚框概念,每个网格单元通常会预测多个边界框,比如YOLO v3每个网格单元一般预测3个边界框。如果同样是检测3个物体,以常见的特征图尺寸为例,如果特征图尺寸为13×13,那么边界框预测总数可能达到13×13×3个甚至更多(因为可能在多个不同尺度的特征图上进行预测)。对于某一个物体,相关的边界框预测数量也会因物体在图像中的位置和大小等因素,由多个网格单元及其对应的多个锚框来进行预测,数量会比YOLO v1更多。
- YOLO v5及后续版本:在不同尺度的特征图上进行多尺度检测,每个尺度的特征图上的网格单元都会根据设定的锚框数量进行边界框预测。对于检测3个物体,输出的边界框预测数量会根据具体的模型配置和输入图像大小等因素而变化,通常会比前面的版本更多。对于单个物体,会有多个来自不同尺度、不同位置的网格单元及其对应的边界框来进行预测,以提高对不同大小、不同位置物体的检测精度。
YOLO损失函数
YOLO损失函数由多个部分组成,包括边界框损失、类别损失和目标置信度分数损失。
损失函数公式 (损失函数略有改动并进行了简化)
J ( θ ) = ∑ j = 1 m e j T e j + λ 1 ∑ j = 1 m ∑ k = 1 K y j , k log y ^ j , k + λ 2 ∑ j = 1 m ( c ^ − c ) 2 J(\theta)=\sum_{j = 1}^{m} e_{j}^{T} e_{j}+\lambda_{1}\sum_{j = 1}^{m}\sum_{k = 1}^{K} y_{j,k} \log \hat{y}_{j,k}+\lambda_{2}\sum_{j = 1}^{m}(\hat{c} - c)^{2} J(θ)=j=1∑mejTej+λ1j=1∑mk=1∑Kyj,klogy^j,k+λ2j=1∑m(c^−c)2其中:
- 边界框平方误差损失(Bounding box squared error loss): ∑ j = 1 m e j T e j \sum_{j = 1}^{m} e_{j}^{T} e_{j} ∑j=1mejTej,用于衡量边界框预测值 ( x , y , w , h ) (x, y, w, h) (x,y,w,h)与真实值之间的误差。 e j e_j ej代表边界框相关的误差向量。
- 分类交叉熵损失(Classification categorical cross - entropy loss): λ 1 ∑ j = 1 m ∑ k = 1 K y j , k log y ^ j , k \lambda_{1}\sum_{j = 1}^{m}\sum_{k = 1}^{K} y_{j,k} \log \hat{y}_{j,k} λ1∑j=1m∑k=1Kyj,klogy^j,k,用于衡量类别预测的准确性。 y j , k y_{j,k} yj,k是真实标签, y ^ j , k \hat{y}_{j,k} y^j,k是预测标签, K K K是类别数量, λ 1 \lambda_{1} λ1是平衡参数。
- 目标检测置信度损失(Confidence in object detection): λ 2 ∑ j = 1 m ( c ^ − c ) 2 \lambda_{2}\sum_{j = 1}^{m}(\hat{c} - c)^{2} λ2∑j=1m(c^−c)2,用于衡量目标置信度分数的预测误差。 c ^ \hat{c} c^是预测的置信度分数, c c c是真实的置信度分数, λ 2 \lambda_{2} λ2是平衡参数。
交并比(IoU)指标
使用交并比(Intersection over union, IoU)作为置信度真实值的度量指标。公式为 c = I o U = A r e a o f O v e r l a p A r e a o f U n i o n c = IoU = \frac{Area of Overlap}{Area of Union} c=IoU=AreaofUnionAreaofOverlap即交并比等于重叠区域面积除以并集区域面积。当边界框预测完美时,IoU = 1。
如图,蓝色框为真实框,黄色框为预测框,红色阴影部分为重叠区域,红色轮廓内为并集区域。
非极大值抑制(Non - maximum suppression,NMS)
非极大值抑制用于YOLO网络之后,以抑制对同一物体的重复检测。
方法
选择置信度 c ^ \hat{c} c^最大的预测,然后抑制所有与该预测的交并比(IoU)大于阈值的其他预测。
流程
从左到右依次为:
- 输入图像。
- 经过YOLO卷积网络(YOLO Conv net)处理。
- 再经过非极大值抑制(Non - maximum suppression)处理。
- 得到最终预测结果(Final predictions)。
效果对比
- 非极大值抑制前(Before non - maximum suppression):图像中的汽车被多个边界框重复检测标注。
- 非极大值抑制后(After non - maximum suppression):只保留了置信度最高且能较好框定汽车的边界框,去除了重复的检测框,使检测结果更加简洁准确。
YOLO 系列模型的发展历程及主要改进点
- YOLO V1(2016 年):确立了一阶段检测器的关键思想。
- YOLO V2(2017 年):引入锚框(anchor boxes);采用全卷积网络。
- YOLO V3(2018 年):具备多尺度检测能力;主干网络基于 ResNet;使用二分类器进行多标签分类。
- YOLO V4(2019 年):采用跨阶段分层网络(CSPNet)、路径聚合网络(PANet)以及空间注意力模块(SAM)。
- YOLO V5(2020 年):基于 PyTorch 开发。
- YOLO V6 & V7(2021 - 2022 年):图片未详细列出具体改进,仅提及版本名称。
- YOLO V8(2023 年):采用无锚框检测(anchor free detection);引入自注意力机制(self attention);改进了训练过程。
代码示例
Matlab最多到V4.
% download, unzip, install, load pre-trained detector
pretrainedURL = "https://ssd.mathworks.com/supportfiles/vision/data/yolov4CSPDarknet53VehicleExample_22a.zip";
websave("yolov4CSPDarknet53VehicleExample_22a.zip", pretrainedURL);
unzip("yolov4CSPDarknet53VehicleExample_22a.zip");
pretrained = load("yolov4CSPDarknet53VehicleExample_22a.mat");
detector = pretrained.detector;
% test
I = imread("highway.png");
[bboxes,scores,labels] = detect(detector,I);
I = insertObjectAnnotation(I,"rectangle",bboxes,scores); figure; imshow(I)
% retrain
detector = trainYOLOv4ObjectDetector(trainingData,detector,trainingOptions);
Python都支持,下面示例是V8
import keras
import keras_cv
model = keras_cv.models.YOLOV8Detector(
num_classes=20,
bounding_box_format="xywh",
backbone=keras_cv.models.YOLOV8Backbone.from_preset(
"yolo_v8_m_backbone_coco"),
fpn_depth=2
)
# Evaluate model without box decoding and NMS
model(images)
# Prediction with box decoding and NMS
model.predict(images)
# Train model
model.compile(
classification_loss='binary_crossentropy',
box_loss='ciou',
optimizer=tf.optimizers.SGD(global_clipnorm=10.0),
jit_compile=False,
)
model.fit(images, labels)
实例分割
实例分割结合了语义分割和目标检测/识别。
示例
Mask R - CNN是一种流行的实例分割方法,它通过添加一个二分类掩码预测输出层对Faster R - CNN进行了扩展。
流程
流程与之前相似,只不过在第二部分多了一个:掩码二分类器(Mask Binary Classifier)在边界框内以像素级别输出目标/无目标的掩码。
总结
深度学习对计算机视觉产生了重大影响,关键领域包括:
- 图像识别(Image recognition):涉及的模型有VGG、GoogleNet、ResNet、Mobilenet 。这些模型用于对图像中的内容进行分类和识别。
- 语义分割(Semantic segmentation):相关模型包括U - Net、Segnet、DeepLabv3+ 。语义分割旨在将图像中的每个像素分配到预定义的类别中,例如区分图像中的道路、天空、建筑物等不同区域。
- 目标检测(Object detection):
- 两阶段检测器(Two - stage):如R - CNN、Fast R - CNN、Faster R - CNN 。这类检测器先生成可能包含目标的区域建议,再进行目标检测和分类。
- 一阶段检测器(One - stage):例如Yolo及其v2、v3、v4、v5、v6、v7、v8等版本。它们在单个阶段内完成目标检测和识别,通常检测速度较快。
- 实例分割(Instance segmentation):结合了语义分割与目标检测和识别,能够在像素级别上区分不同的目标实例,例如区分图像中的多个行人,并为每个行人生成对应的掩码。
引用
- (语义分割的 SegNet 架构)V. Badrinarayanan, A. Kendall and R. Cipolla (2017). SegNet: A Deep Convolutional EncoderDecoder Architecture for Image Segmentation. IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 39, no. 12, pp. 2481-2495.
- (Faster R - CNN)Ren, Shaoqing, Kaiming He, Ross Girshick, and Jian Sun. “Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks.” Neurips . Vol. 28, 2015.
- (Mask R-CNN)He, K., Gkioxari, G., Dollár, P., & Girshick, R. (2017). Mask R-CNN. In Proceedings of
the IEEE International Conference on Computer Vision (pp. 2961-2969).
相关文章:
深度学习-6.用于计算机视觉的深度学习
Deep Learning - Lecture 6 Deep Learning for Computer Vision 简介深度学习在计算机视觉领域的发展时间线 语义分割语义分割系统的类型上采样层语义分割的 SegNet 架构软件中的SegNet 架构数据标注 目标检测与识别目标检测与识别问题两阶段和一阶段目标检测与识别两阶段检测器…...
低概率发生调用`pthread_cond_wait`的线程没有被唤醒
低概率发生调用pthread_cond_wait的线程没有被唤醒 背景: 你是否也踩过坑,在A线程调用pthread_cond_wait等待,在B线程调用pthread_cond_signal唤醒A线程进行工作处理,然后在某一次用户产品反馈中发现了低概率问题。A线程像是卡住…...
MATLAB学习之旅:数据插值与曲线拟合
在MATLAB的奇妙世界里,我们已经走过了一段又一段的学习旅程。从基础的语法和数据处理,到如今,我们即将踏入数据插值与曲线拟合这片充满魅力的领域。这个领域就像是魔法中的艺术创作,能够让我们根据现有的数据点,构建出更加丰富的曲线和曲面,从而更好地理解和描述数据背后…...
Python复习
第一章 Python概述 python特点 优点: 简单易学;开发效率高;典型的工具语言;强大丰富的模块库;优秀的跨平台; 缺点: 执行效率不高;代码不能加密;用缩进区分语句关系&…...
通信系统中物理层与网络层联系与区别
在通信系统中,物理层和网络层是OSI(开放系统互连)模型中的两个重要层次,分别位于协议栈的最底层和第三层。它们在功能、职责和实现方式上有显著的区别,但同时也在某些方面存在联系。以下是物理层与网络层的联系与区别的…...
go 错误处理 error
普通错误处理 // 包路径 package mainimport ("errors""fmt" )func sqrt(f1, f2 float64) (float64, error) {if f2 < 0 {return 0, errors.New("error: f2 < 0")}return f1 / f2, nil }func sqrt1(f1, f2 float64) {if re, err : sqrt(f…...
Redis 缓存穿透、击穿、雪崩:问题与解决方案
在使用 Redis 作为缓存中间件时,系统可能会面临一些常见的问题,如 缓存穿透、缓存击穿 和 缓存雪崩。这些问题如果不加以解决,可能会导致数据库压力过大、系统响应变慢甚至崩溃。本文将详细分析这三种问题的起因,并提供有效的解决…...
Spring容器初始化扩展点:ApplicationContextInitializer
目录 一、什么是ApplicationContextInitializer? 1、核心作用2、适用场景 二、ApplicationContextInitializer的使用方式 1、实现ApplicationContextInitializer接口2、注册初始化器 三、ApplicationContextInitializer的执行时机四、实际应用案例 1、动态设置环境…...
冯·诺依曼体系结构、理解操作系统管理
在谈操作系统概念之前,先简单讲解一下冯诺伊曼体系结构,理解了在硬件层面上数据流的走向,这对后续的理解有很大的帮助。 文章目录 一.冯诺依曼结构冯诺依曼体系结构内存存在的意义 二.理解操作系统管理操作系统的作用管理的本质系统调用 一.…...
Linux初体验:从零开始掌握操作系统的发展与多样性
Linux初体验:从零开始掌握操作系统的发展与多样性 前言一、什么是Linux?1. Linux的定义2. Linux的组成 二、Linux的发展历史1. Unix的诞生2. Linux的诞生3. Linux的普及 三、Linux的发行版1. **Ubuntu**2. **CentOS**3. **Debian**4. **Fedora**5. **Arc…...
文心一言大模型的“三级跳”:从收费到免费再到开源,一场AI生态的重构实验
2025年2月,百度文心大模型接连抛出两枚“重磅炸弹”:4月1日起全面免费,6月30日正式开源文心大模型4.5系列。这一系列动作不仅颠覆了李彦宏此前坚持的“闭源优势论”13,更标志着中国AI大模型竞争进入了一个全新的阶段——从技术壁垒…...
技术教程 | 如何实现1v1音视频通话(含源码)
今天,给大家讲一下怎么实现1v1音视频通话,以下是教程内容: 开发环境 开发环境要求如下: 环境要求说明JDK 版本1.8.0 及以上版本Android API 版本API 21、Android Studio 5.0 及以上版本CPU架构ARM 64、ARMV7IDEAndroid Studio其…...
mysql实时同步到es
测试了多个方案同步,最终选择oceanu产品,底层基于Flink cdc 1、实时性能够保证,binlog量很大时也不产生延迟 2、配置SQL即可完成,操作上简单 下面示例mysql的100张分表实时同步到es,优化备注等文本字段的like查询 创…...
Linux-ubuntu系统移植之Uboot启动流程
Linux-ubuntu系统移植之Uboot启动流程 一,Uboot启动流程1.Uboot的两阶段1.1.第一阶段1.11.硬件初始化1.12.复制 U-Boot 到 RAM1.13.跳转到第二阶段 1.2.第二阶段1.21.C 语言环境初始化1.22. 硬件设备初始化1.23. 加载环境变量1.24. 显示启动信息1.25. 等待用户输入&…...
《Operating System Concepts》阅读笔记:p62-p75
《Operating System Concepts》学习第 10 天,p62-p75 总结,总计 14 页。 一、技术总结 1. system call (1) 定义 The primary interface between processes and the operating system, providing a means to invoke services made available by th…...
【Java场景题】MySQL死锁排查
大家好,今天XiXi给大家分享一个MySQL死锁排查的实验,文章主要有: 通过show engine innodb status,查看最近一次死锁信息开启innodb_print_all_deadlocks,在错误日志中能够记录所有死锁信息通过解析binlog日志定位死锁…...
JSON格式,C语言自己实现,以及直接调用库函数(一)
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。以下为你提供不同场景下常见的 JSON 格式示例。 1. 简单对象 JSON 对象是由键值对组成,用花括号 {} 包裹&…...
leetcode刷题第十三天——二叉树Ⅲ
本次刷题顺序是按照卡尔的代码随想录中给出的顺序 翻转二叉树 226. 翻转二叉树 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*//*总体思路就是,对于每一个结点&…...
spring boot知识点5
1.如何你有俩套配置环境,运行时如何选择 如果有俩套配置环境,则需要三个yml application.yml 用于配置你用那个配置环境 application-dev.yml 用于开发配置环境 application-prod.yml 用于发布配置环境 spring:profiles:active: prod # 指定当前激…...
bboss v7.3.5来袭!新增异地灾备机制和Kerberos认证机制,助力企业数据安全
ETL & 流批一体化框架 bboss v7.3.5 发布,多源输出插件增加为特定输出插件设置记录过滤功能;Elasticsearch 客户端新增异地双中心灾备机制,提升框架高可用性;Elasticsearch client 和 http 微服务框架增加对 Kerberos 认证支持…...
Android自带的省电模式主要做什么呢?
Android自带的省电模式主要做什么呢? 省电模式支持的策略 LOCATION 灭屏后开启GPS待机省电模式 VIBRATION 关闭触摸震动和来电震动 ANIMATION 关闭动画 FULL_BACKUP 全备份 KEYVALUE_BACKUP 键值备份 NETWORK_FIREWALL 网络防火墙,限制 Doze …...
tp6上传文件大小超过了最大值+验证文件上传大小和格式函数
问题: 最近用tp6的文件上传方法上传文件时报文件过大错误。如下所示: $file $this->request->file(file);{"code": 1,"msg": "上传文件大小超过了最大值!","data": {"code": 1,&q…...
将RocketMQ集成到了Spring Boot项目中,实现站内信功能
1. 添加依赖 首先,在pom.xml中添加RocketMQ的依赖: <dependencies><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifac…...
Spring Boot文件上传
5.3.1文件上传 开发Web应用时,文件上传是很常见的一个需求浏览器通过表单形式将文件以流的形式传递给服务器,服务器再对上传的数据解析处理。下面我们通过一个案例讲解如何使用SpringBoot实现文件上传,具体步骤如下。 1.编写文件上传的表单…...
动态规划算法
动态规划算法模板 public class DynamicProgramming {public int solve(int n, int[] nums) {// Step 1: 初始化 dp 数组,dp[i] 表示从0到i的最优解int[] dp new int[n 1]; // Step 2: 设置初始条件,通常是dp数组的第一个元素dp[0] 0; // 假设从第0个…...
Python中常见库 PyTorch和Pydantic 讲解
PyTorch 简介 PyTorch 是一个开源的深度学习框架,由 Facebook 的 AI 研究团队开发。它提供了丰富的工具和库,用于构建和训练各种深度学习模型,如卷积神经网络(CNN)、循环神经网络(RNN)及其变体&…...
74. 搜索二维矩阵(LeetCode 热题 100)
题目来源; 74. 搜索二维矩阵 - 力扣(LeetCode) 题目内容: 给你一个满足下述两条属性的 m x n 整数矩阵: 每行中的整数从左到右按非严格递增顺序排列。 每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &am…...
高防服务器的适用场景有哪些?
高防服务器作为具有着较高防御能力的网络设备,可以抵御DDOS和CC等常见的网络攻击类型,保障企业服务的连续性和稳定性,那高防服务器的适用场景有哪些呢? 对于大型的网站和电商平台来说,高流量的用户访问和数据信息让它们…...
HTTP与网络安全
一、HTTPS和HTTP有怎样的区别呢?HTTPS HTTP SSL/TLS(SSL或者TLS) HTTP:应用层 SSL/TLS:协议中间层 TCP:传输层 IP:网络层 HTTPS 是安全的HTTP,他的安全是由SSL或者TLS来决定的&a…...
UE地编材质世界对齐纹理旋转
帖子地址 https://forums.unrealengine.com/t/how-to-rotate-a-world-aligned-texture/32532/4世界对齐纹理本身不能改 自己创建了个函数 把世界对齐纹理的内容赋值粘贴 在纹理偏移里给值 不要局限0-1 给值给大一点...
SpringBoot使用Nacos进行application.yml配置管理
Nacos是阿里巴巴开源的一个微服务配置管理和服务发现的解决方案。它提供了动态服务发现、配置管理和 服务管理平台。Nacos的核心功能包括服务发现、配置管理和动态服务管理,使得微服务架构下的服务治理 变得简单高效。 Nacos的设计基于服务注册与发现、配置管理、动…...
JavaScript中的symbol类型的意义和使用
JavaScript 中的Symbol类型是 ES6(ECMAScript 2015)引入的一种原始数据类型,它表示独一无二的值。下面详细介绍 Symbol 的意义和使用方法。 意义 1. 避免属性名冲突 在 JavaScript 中,对象的属性名通常是字符串。当多个模块或者…...
C++ 设计模式-状态模式
火箭状态模式,涵盖发射、多级分离、入轨、返航、紧急状态等流程,以及状态间的转换逻辑: 状态设计 状态列表: IdleState(待机)PreparingState(准备)LaunchingState(发射中)FirstStageSeparatingState(一级分离)SecondStageSeparatingState(二级分离)ThirdStageSep…...
verilog基础知识
一,Verilog和VHDL区别 全世界高层次数字系统设计领域中,应用Verilog和VHDL的比率是80%和20%;这两种语言都是用于数字电路系统设计的硬件描述语言, 而且都已经是 IEEE 的标准。 VHDL 是美国军方组织开发的,VHDL1987年成为标准;Verilog 是由一个公司的私有财产转化而来,…...
14.8 Auto-GPT 自主智能体设计解密:构建具备长期记忆的智能决策系统
Auto-GPT 自主智能体设计解密:构建具备长期记忆的智能决策系统 关键词:Auto-GPT 架构设计、自主智能体开发、LangChain Agents、长期记忆系统、工具链编排 1. 自主智能体的核心架构设计 Auto-GPT 系统架构图解: #mermaid-svg-NuDU1eo6sXqhA6Ve {font-family:"trebuch…...
ubuntu安装docker docker/DockerHub 国内镜像源/加速列表【持续更新】
ubuntu安装docker & docker镜像代理【持续更新】 在Ubuntu上安装Docker,你可以选择两种主要方法:从Ubuntu的仓库安装,或者使用Docker的官方仓库安装。下面我会详细解释这两种方法。 方法一:从Ubuntu的仓库安装Docker 这种方…...
模拟实现分布式文件存储
Q1:如何解决海量数据存的下的问题 传统做法是在单机存储。但是随着数据变多,会遇到存储瓶颈。 单机纵向扩展:内存不够加内存,磁盘不够加磁盘。有上限限制,不能无限制加下去。 多机横向扩展:采用多台机器存储&#x…...
HW面试经验分享 | 北京蓝中研判岗
目录: 所面试的公司介绍 面试官的问题: 1、面试官先就是很常态化的让我做了一个自我介绍 2、自我介绍不错,听你讲熟悉TOP10漏洞,可以讲下自己熟悉哪些方面吗? 3、sql注入原理可以讲下吗? 4、sql注入绕WAF有…...
HarmonyOS学习第3天: 环境搭建开启鸿蒙开发新世界
一、引言 在数字化时代,操作系统作为连接用户与硬件设备的桥梁,其重要性不言而喻。HarmonyOS 作为华为公司推出的面向全场景的分布式操作系统,以其创新的理念和卓越的性能,正逐渐在全球范围内崭露头角。它打破了设备之间的界限&a…...
基于STM32与BD623x的电机控制实战——从零搭建无人机/机器人驱动系统
系列文章目录 1.元件基础 2.电路设计 3.PCB设计 4.元件焊接 5.板子调试 6.程序设计 7.算法学习 8.编写exe 9.检测标准 10.项目举例 11.职业规划 文章目录 一、为什么选择这两个芯片?1.1 STM32微控制器1.2 ROHM BD623x电机驱动 二、核心控制原理详解2.1 H桥驱动奥…...
【react18】如何使用useReducer和useContext来实现一个todoList功能
重点知识点就是使用useReducer来攻坚小型的公共状态管理,useImmerReducer来实现数据的不可变 实现效果 实现代码 项目工程结构 App.js文件 import logo from "./logo.svg"; import "./App.css"; import TodoLists from "./comps/TodoLi…...
Java多线程三:补充知识
精心整理了最新的面试资料,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 Lambda表达式 简介: 希腊字母表中排序第十一位的字母,英语名称为Lambda避免匿名内部类定义过多其实质属于函数式编程的概念 为什么要使用lam…...
go WEB框架
推荐选型 https://chat.deepseek.com/a/chat/s/e6061607-8f33-4768-a5f0-8970cb1ffefd echo github:https://github.com/labstack/echo wiki:https://echo.labstack.com/docs/quick-start block:https://blog.csdn.net/qq_38105536/artic…...
【Python爬虫(27)】探索数据可视化的魔法世界
【Python爬虫】专栏简介:本专栏是 Python 爬虫领域的集大成之作,共 100 章节。从 Python 基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取ÿ…...
渲染 101 支持 3ds Max 的渲染器及其优势
在 3ds Max 创作流程里,渲染环节对最终成果的呈现效果起着决定性作用,渲染 101 云渲染平台则为 3ds Max 用户提供了全面且高效的渲染解决方案。 支持的渲染器 V-Ray 渲染器 在 3ds Max 中应用广泛,具备全局光照、光线追踪技术,…...
在 Java 中使用 `if` 语句实现双重判定
关于在 Java 中使用 if 语句实现双重判定,并使用 Eclipse 和 JUnit4 进行单元测试的详细介绍: --- ### 一、双重判定的实现 **双重判定**指在 if 语句中通过逻辑运算符组合两个条件。常用方式: - **逻辑与 &&**:两个条件…...
Ollama 安装
Ollama 支持多种操作系统,包括 macOS、Windows、Linux 以及通过 Docker 容器运行。 Ollama 对硬件要求不高,旨在让用户能够轻松地在本地运行、管理和与大型语言模型进行交互。 CPU:多核处理器(推荐 4 核或以上)。GPU…...
Docker Swarm 内置的集群编排
在现代容器化应用中,容器编排(Container Orchestration)是至关重要的,它负责自动化容器的部署、扩展、负载均衡和管理。Docker Swarm 是 Docker 提供的原生集群管理和容器编排工具,允许用户通过 Docker CLI 在多个 Doc…...
AF3 _build_query_to_hit_index_mapping函数解读
AlphaFold3 中templates模块的_build_query_to_hit_index_mapping函数是将原始查询序列(original_query_sequence)中的索引与hit 序列(hit_sequence)中的索引进行映射。 在蛋白质序列比对(如 HHsearch)中,hit 是与查询序列部分匹配的区域。由于存在缺口(-)和部分比对…...
Windows 中的启动项如何打开?管理电脑启动程序的三种方法
在日常使用电脑时,我们经常会发现一些应用程序在开机时自动启动,这不仅会拖慢系统的启动速度,还可能占用不必要的系统资源。幸运的是,通过几个简单的步骤,你可以轻松管理这些开机自启的应用程序。接下来,我…...