以图像识别为例,关于卷积神经网络(CNN)的直观解释
大家读完觉得有意义记得关注和点赞!!!
作者以图像识别为例,用图文而非数学公式的方式解释了卷积神经网络的工作原理, 适合初学者和外行扫盲。
目录
1 卷积神经网络(CNN)
1.1 应用场景
1.2 起源:LeNet, 1990s
1.3 现代架构
2 CNN:直观解释
2.1 输入:图像(像素值组成的矩阵)
2.2 第一步:卷积运算
2.2.2 动图直观解释
2.2.2 特征图/卷积特征参数
2.3 第二步:非线性(Non Linearity / ReLU)运算
2.4 第三步:降采样
2.4.1 原理:直观解释
2.4.2 小结:卷积层 + ReLU + 降采样层
2.5 第四步:全连接层:基于特征分类
2.6 第五步:反向传播:形成闭环
3 CNN 完整架构和工作流
4 案例:CNN 学习识别字符 8
4.1 多层特征
4.2 学习字符 8
5 其他 CNN 架构
6 总结
参考资料
1 卷积神经网络(CNN)
1.1 应用场景
卷积神经网络(ConvNets 或 CNN)是一类神经网络(a category of Neural Networks), 在图像识别和分类等领域已经证明非常有效。CNN 已经成功用于 人脸识别、物体和交通标志识别,机器人视觉,自动驾驶等等。下面看两个具体例子。
图 1 是给一个图片,自动识别其中的内容并生成一句描述,
图 1:图像识别和自动生成描述。cs.stanford.edu
图 2 则是 CNN 用于识别日常人和物,
图 2:图像识别。来自 paper pdf
此外,CNN 在一些自然语言处理任务(如句子分类)中也展现出很不错的效果。 因此,CNN 在机器学习领域将是一个非常重要的工具。不过,新手学习起来经常比较受挫。 本文试图拿 CNN for image processing 为例,向大家直观解释一下 CNN 是如何工作的。
- 想了解 neural networks 可戳 this short tutorial on Multi Layer Perceptrons,不了解也没关系。
- Multi Layer Perceptrons(多层感知器/多层感知机)在本文中将称为 “Fully Connected Layers”。
1.2 起源:LeNet, 1990s
LeNet 由 Yann LeCun 在 1988 提出,是最早推动深度学习领域发展的卷积神经网络之一。 后来经过多次改进,直到 LeNet5 [3]。 当时 LeNet 架构主要用于字符识别, 例如读取邮政编码、数字等。
1.3 现代架构
近年来提出了几种新的架构,都是对 LeNet 的改进,它们都继承了 LeNet 的主要概念。 因此如果对 LeNet 比较了解,理解现代架构将容易很多。 下图展示了这类架构是如何学习识别图像的:
图 3:基于卷积神经网络识别图像。image credit
- 图中的卷积神经网络在架构上与早期 LeNet 差不多,它对输入图像进行分类(LeNet 主要用于字符识别);
- 这个例子中会分成四类:dog, cat, boat, bird,所有概率的总和是 100%(后文会解释);
- 从图中可以明显看出,在 boat 图像作为输入时,该网络最终的分类结果中,boat 的概率最高(0.94)。
根据上图,我们可以看到现代 CNN 主要有四种操作:
- 卷积(Convolution)
- 非线性(Non Linearity,ReLU))
- 池化或降采样(Pooling or Sub Sampling)
- 分类/全连接层(Classification, Fully Connected Layer)
这几个功能是所有卷积神经网络的基本模块。下面我们尝试从直观上来理解每个操作的含义。
2 CNN:直观解释
2.1 输入:图像(像素值组成的矩阵)
每个图像(image)本质上就是一个由像素值(pixel values)组成的矩阵:
图 4:每个图像都是一个像素值组成的矩阵。[6]
Channel(通道)是一个传统术语,指图像的某一部分数据。 例如,
- 数码相机拍出的图像通常有三个通道 —— red/green/blue —— 可以想象成从下往上依次堆叠的 3 个二维矩阵(每种颜色一个),每个像素值都在 0 到 255 范围内。
- grayscale(灰度)图像只有一个通道。
简单起见,本文将只考虑灰度图像。 这意味着我们将有一个表示图像的二维矩阵,其中中每个像素的值范围从 0 到 255 —— 0 表示黑色,255 表示白色。
2.2 第一步:卷积运算
CNN(卷积神经网络)的名字来源于“卷积”运算,
- 卷积的主要目的是从输入图像中提取特征;
- 通过一个小矩阵(称为 filter)对输入矩阵进行运算,来学习图像特征(image features);
- filter 保留了像素之间的空间关系(spatial relationship between pixels)。
这里不深入探讨卷积的数学细节,只尝试了解它如何处理图像。
2.2.2 动图直观解释
每个图像都是像素值组成的矩阵。考虑一个 5x5 的图像,其像素值只有 0 和 1(灰度图像的像素值范围为 0 到 255,这里我们进一步简化,像素值只有 0 和 1):
然后引入一个 3x3 矩阵作为 filter,
那么,用 5x5 和 3x3 矩阵来计算卷积的过程就如下面的动图所示,
图 5:卷积的计算。计算得到的结果矩阵称为 Convolved Feature or Feature Map(卷积特征,或特征图)。[7]
计算过程:
- 在 5x5 的输入矩阵上,覆盖一个 3x3 矩阵,
- 对当前 3x3 覆盖的部分,分别与 3x3 矩阵按像素相乘,然后把 9 个值加起来得到一个整数,
- 按这种方式,以一个像素为单位依次滑动和计算,最后就得到一个输出矩阵(右边)。
用 CNN 术语来说,
- 3x3 矩阵叫做 filter(滤波器),或 kernel、feature detector 等;
- 滑动的粒度(这里是一个像素)叫做 stride(步长);
- 最后得到的矩阵叫 Convolved Feature(卷积特征)或 feature map(特征图);
显然,对于同一个图像,用的卷积矩阵(filter matrix)不同,得到的特征图(feature maps)也就不同。 或者说不同的 filter 可以检测不同的特征。例如对于下面这张图片,
我们可以根据目的(边缘检测、锐化、模糊化等)的不同,选用不同的 filter,得到的效果如下 [8],
下面是另一个例子,用动图展示两个不同的 filter 计算卷积得到的 feature map,
图 6:卷积运算。Source [9]
这里需要再提醒一下,image 和 filter 都只是一个数值矩阵(numeric matrix)。
2.2.2 特征图/卷积特征参数
实际上,CNN 在训练过程中自行学习(learn)这些 filter 的值 (尽管我们仍然需要在训练时指定某些参数,例如过 filter 数量、filter size、网络架构等)。 filter 数量越多,提取的图像特征就越多,训练出来的网络在识别未见过的图像时效果就越好。
Feature Map(Convolved Feature)的大小由三个参数 [4] 控制,在训练之前确定:
-
深度(depth):将要用来做卷积运算的 filter 数量。
在下图所示的网络中,我们使用三个不同的 filter 对原始图像执行卷积,从而生成三个不同的特征图。 可以将这三个特征图视为三个自下向上堆叠(stacking)在一起的二维矩阵, 这也是为什么成它为特征图的“深度”。
图 7:特征图的深度
-
步长(stride):在输入矩阵上滑动滤波器(filter)矩阵的像素数。
- 步长为 1 就是一次将 filter 移动一个像素,步长为 2 就是一次滑动 2 个像素。
- 步长越大,得到的特征图越小。
-
零值填充(Zero-padding):有时需要在图像边界用零填充,这样就可以对输入图像的边界像素应用 filter。
- zero-padding 会使生成的特征图稍大一些;
- 使用了 zero-padding 称为 wide convolution,不使用的称为 narrow convolution [14]。
2.3 第二步:非线性(Non Linearity / ReLU)运算
每次卷积运算之后,还会跟着一个称为 ReLU(Rectified Linear Unit,修正线性单元)的运算。 这是一个非线性运算,输入输出公式为,
图 8:ReLU 公式与效果(负值置为零)
ReLU 是一个像素级别的操作,将特征图中所有负值置为零。 ReLU 的目的是在 CNN 中引入非线性,因为真实世界中的大部分数据都是非线性的, 我们希望 CNN 能与现实更加匹配。
卷积是一种线性运算 —— 逐像素做矩阵乘法和加法,因此我们通过引入像 ReLU 这样的非线性函数来解释(account for)非线性。
下图可以清楚地看到 ReLU 操作之后的效果,
图 9:真实特征图执行 ReLU 操作之后的效果。Source [10]
- 左边的特征图是卷积运算之后得到的;
- 右边是接着做了 ReLU 运算(负数全部置零)之后的效果。也称为“修正之后的”特征图。
除了 ReLU,还可以使用 tanh
或 sigmoid
等非线性函数,不过在大部分场景下,ReLU 的性能都更好。
2.4 第三步:降采样
Spatial Pooling,又称为降采样、下采样(subsampling、downsampling),
- 目的是在降低 feature map 维度的同时,保留尽量多的重要信息。
- 有不同的类型:
Max/Average/Sum
等。
2.4.1 原理:直观解释
图 10 是对一个卷积 + ReLU 之后得到的特征图执行 2x2 降采样,
图 10: Max Pooling. Source [4]
- 首先定义一个 spatial neighborhood (2x2 窗口),
- 然后执行降采样函数,这里用的是
Max
函数,也就是取其中最大的那个值作为结果, - 注意这里滑动窗口的步长是 2,也就是降采样矩阵的尺寸;
最终把 4x4 特征图降维到了 2x2。
下图是对三个卷积结果(rectified feature map)依次执行降采样,
图 11:对三个维度的特征图执行降采样。
Average Pooling 和 sum 类似,只不过取的是平均值和累加和。 实际中,Max Pooling 效果更好一些。下面是一个效果对比:
图 12:Max/Sum 降采样函数效果对比。Source [10]
Pooling 的作用是主动降低输入表示(input representation)的空间大小(spatial size) [4],
- 使输入表示(特征维度)更小且更易于管理;
- 减少网络参数和计算量,避免过度拟合(overfitting)[4];
- 使网络能容忍输入图像中较小的变换、扭曲和平移:小扭曲不会改变降采样的输出 —— 因为我们采用相邻区域内的最大值/平均值;
- 使我们能获得一个几乎跟输入分辨率无关的特征表示(确切的术语是 “equivariant representation”): 这一点非常重要,因有了这种能力,那无论一个目标是在图像中什么位置,我们都能把它检测出来 [18,19]。
2.4.2 小结:卷积层 + ReLU + 降采样层
至此,我们已经了解了卷积、ReLU 和降采样的工作原理,它们是构成任何 CNN 的基本构建块。 如图 13 所示,
图 13:两个基本处理单元构成的 CNN
- 卷积层 + ReLU + 降采样层构成一个基本处理单元;
- 图中级联了两个这样的处理单元。
这些层联合在一起,从图像中提取有用特征、引入非线性、减少特征维度,同时在使特征在某种程度上做到缩放和平移不变 [18]。 降采样之后的输出就可以对图像分类了,具体的分类过程由称为全连接层的模块来完成。
2.5 第四步:全连接层:基于特征分类
全连接层(Fully Connected Layer)是一种传统的多层感知器(Multi Layer Perceptron), 在输出层使用 softmax()
函数(也可以使用 SVM 等其他分类器,但本文中使用 softmax)。 术语“全连接”表示上一层中的每个神经元都连接到下一层中的每个神经元。
想了解多层感知器,可参考这篇文章。
卷积层和降采样层的输出表示了输入图像的 high-level 特征。 全连接层的目的是基于这些特征,对输入图像进行分类。
例如,假设我们的图像分类有四种可能,如下图所示(图中省略了全连接层中节点之间的连接),
图 14:全连接层
除了分类的作用,加一个全连接层(通常)还是一种低成本的学习这些特性的非线性组合的方式 (learning non-linear combinations of these features)。 卷积层和降采样层的输出对于分类来说可能已经很好了,但组合二者能达到更好的性能 [11]。
全连接层 output 的所有可能性加起来是 100%,这是由 softmax activation function 保证的: softmax 接收任何实值向量输入,将其中的元素归一化到 [0,1] 之间,并且总和等于 1。
2.6 第五步:反向传播:形成闭环
分类结果(各种可能性的概率)出来之后,再 使用反向传播(backpropagation)算法计算所有概率的误差梯度, 并使用梯度下降算法更新所有滤波器值/权重和参数值,以最小化输出误差。
然后就又可以从头开始了,有了这种反馈,下一次的迭代会更加准确。
3 CNN 完整架构和工作流
卷积层 + 降采样层充当输入图像的特征提取器(Feature Extractors), 而全连接层充当分类器(classifier)。
下图中,由于输入图像是 boat,因此 Boat 类的目标概率为 1,其他三个类的目标概率为 0,即
- Input Image = Boat
- Target Vector = [0, 0, 1, 0]
图 15: Training the CNN
卷积网络的训练过程大致如下:
- 用随机值初始化所有 filter 和参数/权重。
-
将训练图像作为输入,经过 forward propagation 步骤(卷积、 ReLU 和降采样以及全连接层中的前向传播),计算出每个类别的输出概率。
- 假设上面的 boat 图像的输出概率是 [0.2, 0.4, 0.1, 0.3]
- 由于第一个训练示例的权重是随机分配的,因此输出概率也是随机的。
-
计算输出层的总误差(所有 4 个类的总和)
- Total Error = ∑ ½ (target probability – output probability) ²
-
使用反向传播计算网络中所有权重的误差梯度,并使用梯度下降算法 更新所有滤波器值/权重和参数值,以最小化输出误差。
- 权重根据它们对总误差的贡献按比例调整。
- 当再次输入相同的图像时,输出概率可能就是 [0.1, 0.1, 0.7, 0.1],更接近目标向量 [0, 0, 1, 0], 这意味着网络已经学会通过调整其权重/过滤器来正确分类该特定图像,从而减少输出误差。
- 过滤器数量、过滤器大小、网络架构等参数在步骤 1 之前都已固定,并且在训练过程中不会更改——只有过滤器矩阵和连接权重的值会更新。
- 对训练集中的所有图像重复步骤 2-4。
以上就是训练 CNN 的步骤,结束之后 CNN 的所有权重和参数都已经过优化,能够正确地对训练集中的图像进行分类。
当一个新的(没见过的)图像被输入到 CNN 中时,网络将通过 forward propagation 计算输出每个类别的概率。 如果训练集足够大,网络将大概率将新图像分类到正确的类别中。
以上步骤已经过简化,以避免过多数学细节,让读者对训练过程有个直觉上的理解。 想了解进一步有关细节,可参考 [4,12]。
上面的例子中使用了两组卷积层和降采样层。实际上可以在单个 CNN 中重复任意层。 另外,每个卷积层之后不是必须要跟着一个降采样层。如图 16 所示,
图 16:多层 CNN 及每层的效果。Source [4]
4 案例:CNN 学习识别字符 8
4.1 多层特征
一般来说,卷积步骤越多,网络能学到的特征就可以越复杂。 例如,在图像分类中,CNN 可能会
- 在第一层学习从原始像素检测物体边缘,然后
- 基于边缘检测判断第二层中的简单形状,然后
- 使用这些形状来检测更高级别的特征,例如面部形状 [14]。
下图是用 Convolutional Deep Belief Network 学习到的特征,
图 17:Convolutional Deep Belief Network 学习特征: 第一层检测边缘;第二次检测形状;第三张检测人脸。 Source [21]
这里只是一个简单的例子,现实中的卷积滤波器可能会检测到对人类无意义的物体。
4.2 学习字符 8
Adam Harley 在 MNIST 手写数字数据库 [13] 上训练卷积神经网络,创造了惊人的可视化效果。
下面看一个 CNN 网络如何处理输入字符 “8”。输入图像包含 1024 像素(32x32),
图 18: Visualizing a CNN trained on handwritten digits. 注意 ReLU 没画出来。 Source [13]
- 第一层卷积:由 6 个独立的 5×5(步长 1)滤波器与输入图像卷积,产生深度为 6 的特征图。
-
第一层降采样:分别对 1 中的六个特征图进行 2×2 Max 降采样(步长为 2)。 注意由于用的是 Max,因此 2x2 网格中的最大值(最亮的像素)的像素进入了降采样结果层。
图 19:卷积 + 降采样。Source [13]
- 第二层卷积:对 2 的结果进行 5x5 卷积(步长 1);
- 第二层降采样:对 3 的结果进行降采样;
- 第一层全连接:120 neurons;
- 第二层全连接:100 neurons;
-
第三层全连接:10 neurons,分别代表 0-9 这 10 个字符作为输出 —— 也称为 Output layer
注意到 output 层中 node
8
最亮,这表示分类结果中8
的概率最大。图 20: Visualizing the Filly Connected Layers. Source [13]
5 其他 CNN 架构
上世纪 90 年代初期就出现卷积神经网络了,本文介绍的 LeNet 只是其中一种,
- LeNet (1990s): 本文介绍的就是这个;
- 1990s to 2012: In the years from late 1990s to early 2010s convolutional neural network were in incubation. As more and more data and computing power became available, tasks that convolutional neural networks could tackle became more and more interesting.
- AlexNet (2012) – In 2012, Alex Krizhevsky (and others) released AlexNet which was a deeper and much wider version of the LeNet and won by a large margin the difficult ImageNet Large Scale Visual Recognition Challenge (ILSVRC) in 2012. It was a significant breakthrough with respect to the previous approaches and the current widespread application of CNNs can be attributed to this work.
- ZF Net (2013) – The ILSVRC 2013 winner was a Convolutional Network from Matthew Zeiler and Rob Fergus. It became known as the ZFNet (short for Zeiler & Fergus Net). It was an improvement on AlexNet by tweaking the architecture hyperparameters.
- GoogLeNet (2014) – The ILSVRC 2014 winner was a Convolutional Network from Szegedy et al. from Google. Its main contribution was the development of an Inception Module that dramatically reduced the number of parameters in the network (4M, compared to AlexNet with 60M).
- VGGNet (2014) – The runner-up in ILSVRC 2014 was the network that became known as the VGGNet. Its main contribution was in showing that the depth of the network (number of layers) is a critical component for good performance.
- ResNets (2015) Residual Network developed by Kaiming He (and others), winner of ILSVRC 2015. 目前最好的 CNN 模型(as of May 2016)。
- DenseNet (August 2016) – Recently published by Gao Huang (and others), the Densely Connected Convolutional Network has each layer directly connected to every other layer in a feed-forward fashion. The DenseNet has been shown to obtain significant improvements over previous state-of-the-art architectures on five highly competitive object recognition benchmark tasks. Check out the Torch implementation here.
6 总结
本文试图用尽量简单的术语来解释卷积神经网络(CNN)背后的主要概念, 希望能让读者对其工作原理有一些直观理解。
参考资料
- karpathy/neuraltalk2: Efficient Image Captioning code in Torch, Examples
- Shaoqing Ren, et al, “Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks”, 2015, arXiv:1506.01497
- Neural Network Architectures, Eugenio Culurciello’s blog
- CS231n Convolutional Neural Networks for Visual Recognition, Stanford
- Clarifai / Technology
- Machine Learning is Fun! Part 3: Deep Learning and Convolutional Neural Networks
- Feature extraction using convolution, Stanford
- Wikipedia article on Kernel (image processing)
- Deep Learning Methods for Vision, CVPR 2012 Tutorial
- Neural Networks by Rob Fergus, Machine Learning Summer School 2015
- What do the fully connected layers do in CNNs?
- Convolutional Neural Networks, Andrew Gibiansky
- A. W. Harley, “An Interactive Node-Link Visualization of Convolutional Neural Networks,” in ISVC, pages 867-877, 2015 (link). Demo
- Understanding Convolutional Neural Networks for NLP
- Backpropagation in Convolutional Neural Networks
- A Beginner’s Guide To Understanding Convolutional Neural Networks
- Vincent Dumoulin, et al, “A guide to convolution arithmetic for deep learning”, 2015, arXiv:1603.07285
- What is the difference between deep learning and usual machine learning?
- How is a convolutional neural network able to learn invariant features?
- A Taxonomy of Deep Convolutional Neural Nets for Computer Vision
- Honglak Lee, et al, “Convolutional Deep Belief Networks for Scalable Unsupervised Learning of Hierarchical Representations” (link)
相关文章:
以图像识别为例,关于卷积神经网络(CNN)的直观解释
大家读完觉得有意义记得关注和点赞!!! 作者以图像识别为例,用图文而非数学公式的方式解释了卷积神经网络的工作原理, 适合初学者和外行扫盲。 目录 1 卷积神经网络(CNN) 1.1 应用场景 1.2 起…...
使用PyTorch实现基于稀疏编码的生成对抗网络(GAN)在CIFAR-10数据集上的应用
使用PyTorch实现基于稀疏编码的生成对抗网络(GAN)在CIFAR-10数据集上的应用 目录 使用PyTorch实现基于稀疏编码的生成对抗网络(GAN)在CIFAR-10数据集上的应用1. 引言2. 数据集介绍3. 模型网络结构3.1 网络结构3.2 编码器3.3 生成器3.4 判别器4. 模型优化器与损失函数4.1 优…...
Java重要面试名词整理(十八):Sentinel
文章目录 服务雪崩及其解决方案技术选型: Sentinel or Hystrix 流量治理组件Sentinel**基于SentinelResource注解埋点实现资源保护** Sentinel控制台**限流阈值类型****流控模式****直接****关联** **流控效果**系统规则——系统自适应保护 限流算法**计数器法****滑动时间窗口…...
【微信小程序获取用户手机号
微信小程序获取用户手机号有2种,一种是前端自己解密,一种是获取后发给后端,后端去解密 重点:要在微信公众平台设置里面绑定微信开放平台账号,不然反解不出来用户手机号上代码: <button style"font-size: 16px;" open-type"getPhoneNumber" getphonenumb…...
Profinet转EtherNet/IP网关连接AB PLC的应用案例
某大型制造企业的生产车间同时采用了西门子 S7 - 1500 PLC 作为核心控制系统的一部分,负责主要生产流程的控制与数据处理;而在特定生产环节,由于历史设备遗留或工艺配套需求,存在使用 AB PLC 的情况。这就导致了在整个自动化生产系…...
Maven的依赖管理
1. 依赖管理 依赖管理,可以将有关依赖项的所有信息放在共同的POM中,并对子POM中的工件进行更简单的引用。举个例子: 父POM <project>......<dependencyManagement><dependencies><dependency><groupId>gro…...
验证码识别插件 - captcha-killer
验证码识别插件 - captcha-killer 简介 captcha-killer 是一款用于 Burpsuite 的验证码识别插件。它的主要功能是调用各种验证码识别接口,以便在进行渗透测试时能够自动识别和绕过验证码。这个插件本身并不直接进行验证码的识别,而是通过调用外部的 OC…...
面试题解,Java中的“对象”剖析
一、说一说JVM中对象的内存布局?new一个对象到底占多大内存? 话不多说,看下图,对象的内存布局图 一个对象的内存布局主要由三部分组成:对象头(Object Header)、实例数据(Instance D…...
对计网大题的一些指正(中间介绍一下CDM的原理和应用)
目录 前言: (1)五层原理体系结构每层功能: 下面是文档的答案: 我在之前的博客里面有介绍过五层原理体系结构, 按理来说,第五层应该是应用层才对,而会话层的功能应该被放到应用层…...
122. 买卖股票的最佳时机 II
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/?envTypestudy-plan-v2&envIdtop-interview-150问题分析: 和买卖股票的最佳时机I这题相比,区别就是可以买多只股票虽然同时只能持有一支,但是我们还是可以…...
qt中如何判断字符串是否为数字,整数,浮点数?
在 Qt 中,可以使用多种方法来判断字符串是否为数字、整数或浮点数。Qt 提供了一些方便的字符串和数值处理函数,可以帮助你实现这些判断。以下是几种常见的方法: 1. 使用 QRegularExpression Qt 提供了 QRegularExpression 类,可…...
《GICv3_Software_Overview_Official_Release_B》学习笔记
1.不同版本的 GIC 架构及其主要功能如下图所示: 2.GICv2m(Generic Interrupt Controller Virtualization Model)是针对ARM架构的GIC(通用中断控制器)的一种扩展, GICv2m扩展为虚拟化环境中的中断管理提供了…...
告别Kibana:Elasticsearch 桌面客户端的新变革
告别Kibana:Elasticsearch 桌面客户端的新变革 在大数据处理与分析领域,Elasticsearch 及其相关技术的应用日益广泛。长期以来,Kibana 在数据可视化与查询管理方面占据重要地位,但随着技术的不断发展,用户对于更高效、…...
【蓝桥杯研究生组】第14届Java试题答案整理
试题链接:链接 A题 满足条件的答案有:35813116 public class TianShu {public static void main(String[] args) {int ans 0;// 2000.1.1 - 2000000.1.1// 年份是月份的倍数,也是日的倍数for (int year2000; year<2000000; year) {for …...
链式调用方式重写父类set方法导致fastjson解析的对象属性未赋值
反序列化后发现属性为null 昨天使用fastjson的JSON.parseArray(json, class)反序列化的时候,发现返回的list列表中的对象某个属性为null,但是json字符串里面这个属性是有值的,经过排查发现是因为子类重写了父类的set方法,且返回值…...
[AUTOSAR 基础入门] - AUTOSAR配置工具
返回总目录 前文我们提到了要借助 EasySAR 平台来助力大家更好地融合 AUTOSAR 的理论与实践,让大家能够切实将所学知识转化为实际操作能力。建议大家感兴趣的去注册一下看看。跳转链接:EasySAR EasySAR是昂辉科技基于 AUTOSAR 方法论设计的一款面向汽车…...
鸿蒙开发:实现键值数据库存储
前言 鸿蒙当中数据持久化存储,为我们提供了多种的实现方式,比如用户首选项方式,关系型数据库方式,键值型数据库方式,文件存储方式等等,对于数据量比较的小的,我们直接选择轻量级的用户首选项方式…...
ip属地的信息准确吗?ip归属地不准确怎么办
在数字化时代,IP属地信息成为了我们日常生活中不可或缺的一部分。在各大社交媒体平台上,IP属地信息都扮演着重要的角色。然而,随着技术的不断进步和网络的复杂性增加,IP属地信息的准确性问题也日益凸显。那么,IP属地信…...
CSS——1.优缺点
<!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title><link rel"stylesheet" type"text/css" href"1-02.css"/></head><body><!--css:层叠样式表…...
Android设备使用AOA协议进行主机与配件模式通信
1.使用TYPC-C数据线连接两台华为手机: TYPE-C线,先连接下图右边的ACCESSORY 再连接左边的HOST 此时左边的HOST(白色) 会给右边的ACCESSORY(黑色) 充电 接着打开左连接的HostChart会自动调起授权,然后会启动右边的AccessoryChart USB HOS…...
MySQL中深度分页问题的优化
MySQL中深度分页问题的优化 在MySQL中,使用LIMIT子句进行分页查询时,可能会遇到一个常见的性能问题:当LIMIT子句中的偏移量X很大时,查询速度会显著下降。例如,LIMIT 0,10可能只需要20毫秒,而LIMIT 1000000,…...
5. C语言 常量与宏定义
本章目录: 前言一、什么是常量?1. 整型常量2. 浮点型常量3. 字符常量4. 字符串常量 二、如何定义常量?1. 使用 #define 宏定义2. 使用 const 关键字 三、#define 和 const 的区别四、使用建议1. 使用场景区分2. 避免宏定义的潜在问题 五、特殊用法与小技…...
【mybatis-plus问题集锦系列】mybatis使用xml配置文件实现数据的基础增删改查
简单的数据查询,我们可以在mapper接口里面去实现,但是如果是复杂的查询,我们就可以使用xml配置文件去做, 官网链接xml配置文件 实现效果 实现代码 根据mapper接口的包结构,在resources包里面新建同名同结构的xml文件…...
spring防止重复点击,两种注解实现(AOP)
第一种:EasyLock 简介 为了简化可复用注解,自己实现的注解,代码简单随拿随用 使用方式 1.创建一个注解 Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) Documented public interface EasyLock {long waitTime() default …...
Spring Boot 3 实现 MySQL 主从数据库之间的数据同步
✅ Spring Boot 3 实现 MySQL 主从数据库之间的数据同步 在实际项目中,为了提高 系统的读性能 和 数据的可用性,通常会使用 主从数据库架构。Spring Boot 提供了对 多数据源 的良好支持,可以轻松配置 主从数据库 的数据同步,实现 读写分离。 🎯 方案介绍 我们将通过 Sp…...
WPS-JS宏快速上手
WPS JS宏注意事项 代码后面可以不写分号“ ; ”; 缩进对程序的运行影响不大,但为了易读(防止自己以后看不懂),还是乖乖写好; 代码是逐行运行的,意味着下面一行代码错了,前面的代码…...
力扣hot100——堆
215. 数组中的第K个最大元素 快速排序 class Solution { public:int findKthLargest(vector<int>& a, int k) {auto qsort [&](this auto&& qsort, int l, int r) -> void {if (l r) return;int i l - 1, j r 1;int x a[(l r) / 2];/*如果把…...
【小制作】米家模拟手指点击
代码功能解释 这段代码是一个基于Arduino平台的控制程序,主要功能包括: 初始化:设置引脚模式、初始化编码器、舵机和EEPROM。按键检测:处理按钮的单击、双击和长按事件,并根据事件执行相应操作。编码器更新ÿ…...
ubuntu1604 apt镜像源切换
1、如何查看当前源 cat /etc/apt/sources.list less /etc/apt/sources.list 2、apt源修改为阿里镜像,这里ubuntu是1604: deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/…...
leetcode刷题笔记
题目思路1.两数之和哈希表2.两数相加链表操作3. 无重复字符的最长子串滑动窗口,特别注意数组越界情况!4. 寻找两个正序数组的中位数5.最长回文子串从中间向两边扩展,注意整个字符串都是回文串的边界情况10.正则表达式匹配动态规划,…...
修复 ITunes 在 Windows 或 Mac 上不断崩溃的问题 [100% 有效]
对于 iDevice 用户来说,只能通过 iTunes 在 iDevice 和计算机之间传输文件的困境一直是一个紧迫的问题。所有 iPhone 用户可能都知道,iTunes 并不是一款高效的应用程序,有时性能会很差,例如在 iDevices 和计算机之间传输文件时不断…...
Mac M2基于MySQL 8.4.3搭建(伪)主从集群
前置准备工作 安装MySQL 8.4.3 参考博主之前的文档,在本地Mac安装好MySQL:Mac M2 Pro安装MySQL 8.4.3安装目录:/usr/local/mysql,安装好的MySQL都处于运行状态,需要先停止MySQL服务最快的方式:系统设置 …...
Visual Point Cloud Forecasting enables Scalable Autonomous Driving——点云论文阅读(12)
此内容是论文总结,重点看思路!! 文章概述 这篇文章介绍了一个名为 ViDAR 的视觉点云预测框架,它通过预测历史视觉输入生成未来点云,作为自动驾驶的预训练任务。ViDAR 集成了语义、三维几何和时间动态信息,有效提升了感知、预测和规划等自动驾驶核心任务的性能。实验表明…...
handpose x plus 数据解析 >> DataBall
DataBall 助力快速掌握数据集的信息和使用方式,会员享有 百种数据集,持续增加中。 需要更多数据资源和技术解决方案,知识星球: “DataBall - X 数据球(free)” ---------------------------- 样品数据: 通过加入知识…...
LINUX线程操作
文章目录 线程的定义LINUX中的线程模型一对一模型多对一模型多对多模型 线程实现原理线程的状态新建状态(New)就绪状态(Runnable)运行状态(Running)阻塞状态(Blocked)死亡状态&#…...
每日一学——日志管理工具(ELK Stack)
5.1 ELK Stack 5.1.1 Elasticsearch索引机制 嘿,小伙伴们!今天我们要聊聊ELK Stack——一套由Elasticsearch、Logstash和Kibana组成的强大日志管理工具集。通过这套工具,我们可以轻松地收集、存储、搜索和可视化日志数据。首先,…...
设计模式 结构型 适配器模式(Adapter Pattern)与 常见技术框架应用 解析
适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将一个类的接口转换成客户端所期望的另一个接口,从而使原本因接口不兼容而无法一起工作的类能够协同工作。这种设计模式在软件开发中非常有用,尤其是在需要集成…...
【Leetcode】732. 我的日程安排表 III
文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接🔗 当 k k k 个日程存在一些非空交集时(即, k k k 个日程包含了一些相同时间),就会产生 k k k 次预订。 给你一些日程安排 [startTime, endTime…...
Flutter Android修改应用名称、应用图片、应用启动画面
修改应用名称 打开Android Studio,打开对应项目的android文件。 选择app下面的manifests->AndroidManifest.xml文件,将android:label"bluetoothdemo2"中的bluetoothdemo2改成自己想要的名称。重新启动或者重新打包,应用的名称…...
RocketMQ消费者如何消费消息以及ack
1.前言 此文章是在儒猿课程中的学习笔记,感兴趣的想看原来的课程可以去咨询儒猿课堂 这篇文章紧挨着上一篇博客来进行编写,有些不清楚的可以看下上一篇博客: https://blog.csdn.net/u013127325/article/details/144934073 2.broker是如何…...
华为消费级QLC SSD来了
近日,有关消息显示,华为的消费级SSD产品线,eKitStor Xtreme 200E系列,在韩国一家在线零售商处首次公开销售,引起了业界的广泛关注。 尽管华为已经涉足服务器级别的SSD制造多年,但直到今年6月才正式推出面向…...
Conda 安装 Jupyter Notebook
文章目录 1. 安装 Conda下载与安装步骤: 2. 创建虚拟环境3. 安装 Jupyter Notebook4. 启动 Jupyter Notebook5. 安装扩展功能(可选)6. 更新与维护7. 总结 Jupyter Notebook 是一款非常流行的交互式开发工具,尤其适合数据科学、机器…...
高等数学学习笔记 ☞ 极限的运算法则与存在准则
1. 极限的运算法则 (1)有限个无穷小的和是无穷小。 (2)有限个无穷小的乘积是无穷小。 备注: ①:无限个无穷小的和不一定是无穷小,反例如下…...
【开源】创建自动签到系统—QD框架
1. 介绍 QD是一个 基于 HAR 编辑器和 Tornado 服务端的 HTTP 定时任务自动执行 Web 框架。 主要通过抓包获取到HAR来制作任务模板,从而实现异步响应和发起HTTP请求 2. 需要环境 2.1 硬件需求 CPU:至少1核 内存:推荐 ≥ 1G 硬盘:推…...
k8s集群,CRI-Docker部署条件及方法
CRI-Docker部署条件及方法 文章目录 CRI-Docker部署条件及方法CRI-Docker使用条件安装 cri-docker 的步骤: CRI-Docker使用条件 在 Kubernetes 1.20 及以上版本,kubeadm 默认使用 containerd 作为容器运行时(Container Runtime Interface, C…...
STLG_01_09_程序设计C语言 - 指针
C语言中的指针是一个非常重要的概念,它允许程序直接访问和操作内存地址。理解指针对于掌握C语言编程至关重要。 1. 指针的基本概念 指针:指针是一个变量,它存储的是另一个变量的内存地址。指针变量:指针变量专门用来存储内存地址…...
Seaborn的分类柱状图sns.barplot()
Seaborn的分类柱状图sns.barplot 一、sns.barplot()参数详解二、代码实现一、sns.barplot()参数详解 sns.barplot 是 Seaborn 库中用于绘制分类柱状图(bar chart)的函数。Seaborn 是一个基于 Matplotlib 的数据可视化库,它提供了更高级别的接口来绘制统计图形,并且有更…...
SpringBoot入门之创建一个Hello World项目
文章目录 一、创建一个SpringBoot项目二、配置pom.xml文件三、下载Maven依赖四、创建一个Controller类:com.devops.controller.HelloController五、创建一个引导类:com.devops.HelloApplication六、启动项目七、访问8080八、完整项目结构九、参考视频 一…...
MAC系统QT Creator的快捷键
安装好QT Creator后使用了一段时间,真是越用越难受,只想说🗑️。。。 找一圈qt creator的快捷键 0. 快捷键界面 这里的搜索真的是…无语,不考虑是人查找吗?? 1. 代码前后浏览 2. 移动代码 3. 半自动导入…...
qml Rectangle详解
1、概述 Rectangle是Qt Quick中的一个基础图形元素,用于在QML界面上绘制一个可带边框和可填充的矩形区域。它继承自Item类,因此具有Item的所有属性和功能,如位置、尺寸、变换等。通过Rectangle,可以创建各种矩形形状,…...