遗传算法与深度学习实战(25)——使用Keras构建卷积神经网络
遗传算法与深度学习实战(25)——使用Keras构建卷积神经网络
- 0. 前言
- 1. 卷积神经网络基本概念
- 1.1 卷积
- 1.2 步幅
- 1.3 填充
- 1.4 激活函数
- 1.5 池化
- 2. 使用 Keras 构建卷积神经网络
- 3. CNN 层的问题
- 4. 模型泛化
- 小结
- 系列链接
0. 前言
卷积神经网络 (Convolutional Neural Network
, CNN
) 的提出是为了解决传统神经网络的缺陷。即使对象位于图片中的不同位置或其在图像中具有不同占比,CNN
依旧能够正确的处理这些图像,因此在对象分类/检测任务中更加有效。在本节中,我们将使用 Keras
构建卷积神经网络模型进行图像分类,介绍 CNN
的基础知识,并构建 CNN
模型。
1. 卷积神经网络基本概念
在本节中,首先介绍卷积神经网络 (Convolutional Neural Network
, CNN
) 的相关概念与组成,了解 CNN
的工作原理。
1.1 卷积
卷积是两个矩阵间的乘法——通常一个矩阵具有较大尺寸,另一个矩阵则较小。要了解卷积,首先讲解以下示例。给定矩阵 A
和矩阵 B
如下:
在进行卷积时,我们将较小的矩阵在较大的矩阵上滑动,在上述两个矩阵中,当较小的矩阵 B
需要在较大矩阵 A
的整个区域上滑动时,会得到 9
次乘法运算,过程如下。
在矩阵 A
中从第 1
个元素开始选取与矩阵 B
相同尺寸的子矩阵 [ 1 2 0 1 1 1 3 3 2 ] \left[ \begin{array}{ccc} 1 & 2 & 0\\ 1 & 1 & 1\\ 3 & 3 & 2\\\end{array}\right] 113213012 和矩阵 B
相乘并求和:
1 × 3 + 2 × 1 + 0 × 1 + 1 × 2 + 1 × 3 + 1 × 1 + 3 × 2 + 3 × 2 + 2 × 3 = 29 1\times 3+2\times 1+0\times 1+1\times 2+1\times 3+1\times 1+3\times 2+3\times 2 + 2\times 3=29 1×3+2×1+0×1+1×2+1×3+1×1+3×2+3×2+2×3=29
然后,向右滑动一个窗口,选择第 2
个与矩阵 B
相同尺寸的子矩阵 [ 2 0 2 1 1 2 3 2 1 ] \left[ \begin{array}{ccc} 2 & 0 & 2\\ 1 & 1 & 2\\ 3 & 2 & 1\\\end{array}\right] 213012221 和矩阵 B
相乘并求和:
2 × 3 + 0 × 1 + 2 × 1 + 1 × 2 + 1 × 3 + 2 × 1 + 3 × 2 + 2 × 2 + 1 × 3 = 28 2\times 3+0\times 1+2\times 1+1\times 2+1\times 3+2\times 1+3\times 2+2\times 2 + 1\times 3=28 2×3+0×1+2×1+1×2+1×3+2×1+3×2+2×2+1×3=28
然后,再向右滑动一个窗口,选择第 3
个与矩阵 B
相同尺寸的子矩阵 [ 0 2 3 1 2 0 2 1 2 ] \left[ \begin{array}{ccc} 0 & 2 & 3\\ 1 & 2 & 0\\ 2 & 1 & 2\\\end{array}\right] 012221302 和矩阵 B
相乘并求和:
0 × 3 + 2 × 1 + 3 × 1 + 1 × 2 + 2 × 3 + 0 × 1 + 2 × 2 + 1 × 2 + 2 × 3 = 25 0\times 3+2\times 1+3\times 1+1\times 2+2\times 3+0\times 1+2\times 2+1\times 2 + 2\times 3=25 0×3+2×1+3×1+1×2+2×3+0×1+2×2+1×2+2×3=25
当向右滑到尽头时,向下滑动一个窗口,并从矩阵 A
左边开始,选择第 4
个与矩阵 B
相同尺寸的子矩阵 [ 1 1 1 3 3 2 1 0 2 ] \left[ \begin{array}{ccc} 1 & 1 & 1\\ 3 & 3 & 2\\ 1 & 0 & 2\\\end{array}\right] 131130122 和矩阵 B
相乘并求和:
1 × 3 + 1 × 1 + 1 × 1 + 3 × 2 + 3 × 3 + 2 × 1 + 1 × 2 + 0 × 2 + 2 × 3 = 30 1\times 3+1\times 1+1\times 1+3\times 2+3\times 3+2\times 1+1\times 2+0\times 2 + 2\times 3=30 1×3+1×1+1×1+3×2+3×3+2×1+1×2+0×2+2×3=30
然后,继续向右滑动,并重复以上过程滑动矩阵窗口,直到滑动到最后一个子矩阵为止,得到最终的结果 [ 29 28 25 30 30 27 20 24 34 ] \left[ \begin{array}{ccc} 29 & 28 & 25\\ 30 & 30 & 27\\ 20 & 24 & 34\\\end{array}\right] 293020283024252734 :
完整的卷积计算过程如以下动图所示:
通常,我们把较小的矩阵 B
称为滤波器 (filter
) 或卷积核 (kernel
),使用 ⊗ \otimes ⊗ 表示卷积运算,较小矩阵中的值通过梯度下降被优化学习,卷积核中的值则为网络权重。卷积后得到的矩阵,也称为特征图 (feature map
)。
卷积核的通道数与其所乘矩阵的通道数相等。例如,当图像输入形状为 5 x 5 x 3
时(其中 3
为图像通道数),形状为 3 x 3
的卷积核也将具有 3
个通道,以便进行矩阵卷积运算:
可以看到无论卷积核有多少通道,一个卷积核计算后都只能得到一个通道。多为了捕获图像中的更多特征,通常我们会使用多个卷积核,得到多个通道的特征图,当使用多个卷积核时,计算过程如下:
需要注意的是,卷积并不等同于滤波,最直观的区别在于滤波后的图像大小不变,而卷积会改变图像大小,关于它们之间更详细的计算差异,并非本节重点,因此不再展开介绍。
1.2 步幅
在前面的示例中,卷积核每次计算时在水平和垂直方向只移动一个单位,因此可以说卷积核的步幅 (Strides
) 为 (1, 1)
,步幅越大,卷积操作跳过的值越多,例如以下为步幅为 (2, 2)
时的卷积过程:
1.3 填充
在前面的示例中,卷积操作对于输入矩阵的不同位置计算的次数并不相同,具体来说对于边缘的数值在卷积时,仅仅使用一次,而位于中心的值则会被多次使用,因此可能导致卷积错过图像边缘的一些重要信息。如果要增加对于图像边缘的考虑,我们将在输入矩阵的边缘周围的填充 (Padding
) 零,下图展示了用 0
填充边缘后的矩阵进行的卷积运算,这种填充形式进行的卷积,称为 same
填充,卷积后得到的矩阵大小为 ⌊ d + 2 p − k s ⌋ + 1 \lfloor\frac {d+2p-k} s\rfloor+1 ⌊sd+2p−k⌋+1,其中 s s s 表示步幅, p p p 表示填充大小, k k k 表示滤波器尺寸。而未进行填充时执行卷积运算,也称为 valid
填充。
1.4 激活函数
在传统神经网络中,隐藏层不仅将输入值乘以权重,而且还会对数据应用非线性激活函数,将值通过激活函数传递。CNN
中同样包含激活函数,包括 Sigmoid
,ReLU
,tanh
和 LeakyReLU
等。
1.5 池化
研究了卷积的工作原理之后,我们将了解用于卷积操作之后的另一个常用操作:池化 (Pooling
)。假设卷积操作的输出如下,为 2 x 2
:
[ 29 28 20 24 ] \left[ \begin{array}{cc} 29 & 28\\ 20 & 24\\\end{array}\right] [29202824]
假设使用池化块(或者类比卷积核,我们也可以称之为池化核)为 2 x 2
的最大池化,那么将会输出 29
作为池化结果。假设卷积步骤的输出是一个更大的矩阵,如下所示:
[ 29 28 25 29 20 24 30 26 27 23 26 27 24 25 23 31 ] \left[ \begin{array}{cccc} 29 & 28 & 25 & 29\\ 20 & 24 & 30 & 26\\ 27 & 23 & 26 & 27\\ 24 & 25 & 23 & 31\\\end{array}\right] 29202724282423252530262329262731
当池化核为 2 x 2
,且步幅为 2
时,最大池化会将此矩阵划分为 2 x 2
的非重叠块,并且仅保留每个块中最大的元素值,如下所示:
[ 29 28 ∣ 25 29 20 24 ∣ 30 26 — — — — — 27 23 ∣ 26 27 24 25 ∣ 23 31 ] = [ 29 30 27 31 ] \left[ \begin{array}{ccccc} 29 & 28 & | & 25 & 29\\ 20 & 24 & | & 30 & 26\\ —&—&—&—&—\\ 27 & 23 & | & 26 & 27\\ 24 & 25 & | & 23 & 31\\\end{array}\right]=\left[ \begin{array}{cc} 29 & 30\\ 27 & 31\\\end{array}\right] 2920—27242824—2325∣∣—∣∣2530—26232926—2731 =[29273031]
从每个池化块中,最大池化仅选择具有最高值的元素。除了最大池化外,也可以使用平均池化,其将输出每个池化块中的平均值作为结果,在实践中,与其他类型的池化相比,最常使用的池化为最大池化。
2. 使用 Keras 构建卷积神经网络
在本节中,我们在 Fashion-MNIST
数据集上执行图像分类,Fashion-MNIST
是一个基本测试数据集,可以对其进行裁剪,减少用于训练或推理的数据量,以减少进化所需的运行时间。
(1) 加载 Fashion
数据集,对数据进行归一化并将其整形为形状为 (28,28,1)
的张量,其中 1
表示通道,这是因为数据集中的 2D
数组未定义通道,我们从原始数据集中提取前 1,000
个样本进行训练和 100
个用于测试:
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import numpy as np
import math
import timeimport matplotlib.pyplot as plt
from livelossplot import PlotLossesKerasdataset = datasets.fashion_mnist
(x_train, y_train), (x_test, y_test) = dataset.load_data()# normalize and reshape data
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1).astype("float32") / 255.0
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1).astype("float32") / 255.0x_train = x_train[:1000]
y_train= y_train[:1000]
x_test = x_test[:100]
y_test= y_test[:100]class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat','Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']def plot_data(num_images, images, labels):grid = math.ceil(math.sqrt(num_images))plt.figure(figsize=(grid*2,grid*2))for i in range(num_images):plt.subplot(grid,grid,i+1)plt.xticks([])plt.yticks([])plt.grid(False) plt.imshow(images[i].reshape(28,28))plt.xlabel(class_names[labels[i]]) plt.show()plot_data(25, x_train, y_train)
减小数据集规模并非理想方案,但当我们尝试优化数千甚至数万个个体时,这样做可以节省大量时间。
(2) 构建模型, 每个 Conv2D
层定义了应用于输入的卷积操作。在连续应用卷积层的过程中,滤波器或通道的数量从上一层扩展。例如,第一个 Conv2D
层将输入通道从 1
扩展到 64
。然后,后续层将其缩小到 32
,然后到 16
,其中每个卷积层都添加一个 MaxPooling
层,用于总结特征:
model = models.Sequential()
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding="same", input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2), padding="same"))
model.add(layers.Conv2D(32, (3, 3), activation='relu', padding="same"))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(16, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))model.summary()
通过在图像上滑动滤波器块来生成相应的输出,其中每次卷积核滑动操作得到一个输出值,滤波器中的卷积核值或权重/参数是可以学习的。通常卷积操作的输出非常大,每个滤波器都会产生类似图像的输出块。减少数据量可以通过使用池化层,除了最大池化,还可以使用其他变体来获取收集特征的最小值或平均值。设置模型的卷积和最大池化层之后,使用 model.summary()
打印模型摘要。
(3) 展平 CNN
层的输出,并输入到全连接层中,该层包含 10
个神经元(输出为 10
个类别):
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(10))model.summary()
(4) 训练模型,训练后输出结果如下所示。通常,在此数据集的优化后的性能达到 98%
左右,由于使用完整数据集进行训练非常耗时,我们仅抽取了少量数据样本:
model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['accuracy'])history = model.fit(x_train, y_train, epochs=10, validation_data=(x_test, y_test),callbacks=[PlotLossesKeras()],verbose=0)test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)
可以看到,在验证数据上的准确率稳定在 81%
左右。由于同一类别中的样本变化很小,在 Fashion-MNIST
数据集上使用简单 CNN
就可以得到较高准确率,但对于像 CIFAR-10
或 CIFAR-100
同一类别中样本变化较大的数据集,情况将有所不同。
观察训练和测试的损失和准确率之间的差异。可以看到,模型在第 3
个 epoch
时在测试数据上的推理能力开始下降。这可能与数据规模缩小或模型构建有关。在之后的学习中,我们将介绍一些经典的 CNN
架构。
3. CNN 层的问题
接下来,我们将进一步探索 CNN
架构,并了解了 CNN
的局限性。当正确使用时,CNN
是一个很好的工具,但如果使用不当,也会引发一系列问题,了解问题有助于更好的理解进化优化。
(1) 构建模型,只使用一个 CNN
层。定义一个具有 64
个滤波器和 3×3
卷积核的层,模型摘要输入如下所示,模型总参数量超过 600
万:
model = models.Sequential()
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding="same", input_shape=(28, 28, 1)))
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(10))model.summary()
(2) 训练模型,训练结果输出如下。可以看到,模型在训练数据上的表现非常好,但在验证/测试数据上的表现很差。这是因为具有超过 600
万参数的模型会记住训练数据集,无法很好的泛化到模型未见到的数据集上,即过拟合现象。可以看到训练集的准确率接近 100%
,然而在测试/验证集的准确率大幅下降:
model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['accuracy'])history = model.fit(x_train, y_train, epochs=10, validation_data=(x_test, y_test),callbacks=[PlotLossesKeras()],verbose=0)
4. 模型泛化
我们通常希望构建能够泛化的模型,因此,将数据分成训练集和测试集来验证模型的泛化能力。为了提高模型的泛化能力,可以应用例如批归一化和 dropout
等技术。然而,在某些情况下,泛化可能并非最终目标,我们可能希望识别特定的数据集,在这种情况下,就需要模型能够记住数据。
(1) 接下来,我们研究池化对卷积输出的影响,构建包含池化层的卷积神经网络,为了提高模型的泛化能力,还在池化层之间添加了批归一化层:
model = models.Sequential()
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding="same", input_shape=(28, 28, 1)))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2), padding="same"))
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(10))model.summary()
模型摘要如下所示。可以看到,由于添加了池化,此模型的参数量约为上一模型的四分之一。
(2) 对模型进行 10
个 epoch
的训练,输出结果如下所示。虽然该模型仍存在过拟合的现象,但模型已经具有很好的泛化能力,可以看到模型验证准确率得到提升且损失得到降低:
model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['accuracy'])history = model.fit(x_train, y_train, epochs=10, validation_data=(x_test, y_test),callbacks=[PlotLossesKeras()],verbose=0)
我们可以通过调整多个超参数改进模型,例如添加更多的 CNN
层、批归一化层、dropout
、池化层,或修改卷积层的核大小或滤波器数量等。
小结
卷积神经网络 (Convolutional Neural Network
, CNN
) 是一种深度学习模型,特别适用于图像和视频等数据。它的设计灵感来源于生物学中对动物视觉皮层的理解,通过多层次的卷积和池化操作来实现对图像特征的学习和提取。在本节中,我们介绍了 CNN
的基本组件,并使用 Keras
实现了 CNN
模型。
系列链接
遗传算法与深度学习实战(1)——进化深度学习
遗传算法与深度学习实战(2)——生命模拟及其应用
遗传算法与深度学习实战(3)——生命模拟与进化论
遗传算法与深度学习实战(4)——遗传算法(Genetic Algorithm)详解与实现
遗传算法与深度学习实战(5)——遗传算法中常用遗传算子
遗传算法与深度学习实战(6)——遗传算法框架DEAP
遗传算法与深度学习实战(7)——DEAP框架初体验
遗传算法与深度学习实战(8)——使用遗传算法解决N皇后问题
遗传算法与深度学习实战(9)——使用遗传算法解决旅行商问题
遗传算法与深度学习实战(10)——使用遗传算法重建图像
遗传算法与深度学习实战(11)——遗传编程详解与实现
遗传算法与深度学习实战(12)——粒子群优化详解与实现
遗传算法与深度学习实战(13)——协同进化详解与实现
遗传算法与深度学习实战(14)——进化策略详解与实现
遗传算法与深度学习实战(15)——差分进化详解与实现
遗传算法与深度学习实战(16)——神经网络超参数优化
遗传算法与深度学习实战(17)——使用随机搜索自动超参数优化
遗传算法与深度学习实战(18)——使用网格搜索自动超参数优化
遗传算法与深度学习实战(19)——使用粒子群优化自动超参数优化
遗传算法与深度学习实战(20)——使用进化策略自动超参数优化
遗传算法与深度学习实战(21)——使用差分搜索自动超参数优化
遗传算法与深度学习实战(22)——使用Numpy构建神经网络
遗传算法与深度学习实战(23)——利用遗传算法优化深度学习模型
遗传算法与深度学习实战(24)——在Keras中应用神经进化优化
相关文章:

遗传算法与深度学习实战(25)——使用Keras构建卷积神经网络
遗传算法与深度学习实战(25)——使用Keras构建卷积神经网络 0. 前言1. 卷积神经网络基本概念1.1 卷积1.2 步幅1.3 填充1.4 激活函数1.5 池化 2. 使用 Keras 构建卷积神经网络3. CNN 层的问题4. 模型泛化小结系列链接 0. 前言 卷积神经网络 (Convolution…...

pytest+allure生成报告显示loading和404
pytestallure执行测试脚本后,通常会在电脑的磁盘上建立一个临时文件夹,里面存放allure测试报告,但是这个测试报告index.html文件单独去打开,却显示loading和404, 这个时候就要用一些办法来解决这个报告显示的问题了。 用命令产生…...
为何划分 Vue 项目结构组件?划分结构和组件解决了什么问题?为什么要这么做?
在一个大型 Vue 项目中,合理的目录结构和组件划分至关重要。良好的结构可以提高开发效率,减少维护成本,并使得团队合作更加顺畅。下面我将详细讲解如何在 Vue 项目中进行目录结构和组件划分,并结合实际项目代码示例进行说明。 1. 为什么要划分结构和组件? 1.1 提高可维护…...

springboot中使用mongodb完成评论功能
pom文件中引入 <!-- mongodb --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> yml中配置连接 data:mongodb:uri: mongodb://admin:1234561…...
Dubbo的RPC泛化调用
目录 一、RPC泛化调用的应用场景 二、Dubbo RPC泛化调用的实现原理 三、Dubbo RPC泛化调用的实现步骤 四、示例代码 五、泛化调用怎么发现提供该接口的服务及服务的IP和端口? Dubbo的RPC泛化调用是一种在调用方没有服务方提供的API的情况下,对服务方…...
【k8s深入理解之 Scheme】全面理解 Scheme 的注册机制、内外部版本、自动转换函数、默认填充函数、Options等机制
参考 【k8s基础篇】k8s scheme3 之序列化_基于schema进行序列化-CSDN博客【k8s基础篇】k8s scheme4 之资源数据结构与资源注册_kubernetes 的scheam-CSDN博客常见问题答疑 【k8s深入理解之 Scheme 补充-1】理解 Scheme 中资源的注册以及 GVK 和 go 结构体的映射-CSDN博客【k8s深…...

接口性能优化宝典:解决性能瓶颈的策略与实践
目录 一、直面索引 (一)索引优化的常见场景 (二)如何检查索引的使用情况 (三)如何避免索引失效 (四)强制选择索引 二、提升 SQL 执行效率 (一)避免不必…...

雨晨 Windows Server 2025 数据中心 极简 26311.5000
文件: 雨晨 Windows Server 2025 数据中心 极简 26311.5000 install.esd 大小: 1740910278 字节 修改时间: 2024年11月29日, 星期五, 19:00:20 MD5: 5B946B9DED569E04917E804B25A0F736 SHA1: E78BB430B3E0397F6ACFEB821CF85EA7CFB5A00F CRC32: B3F76BD7 常规制作旨在测试YCDIS…...

关于IDE的相关知识之三【插件安装、配置及推荐的意义】
成长路上不孤单😊😊😊😊😊😊 【14后😊///C爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于ide插件安装、配置及推荐意义的相关内容…...
JSP+Servlet实现列表分页功能
分享一种最简单的JSPServlet实现分页的方式! 旧:无分页功能的查询列表功能,仅供参考! Servlet try {Connection conn null;PreparedStatement ps null;ResultSet rs null;List<Dept> arrayList null;conn DBUtil.get…...
操作系统存储器相关习题
1 为什么要配置层次式存储器? 设置多个存储器可以使存储器两端的硬件能并行工作; 采用多级存储系统特别是Cache技术,是减轻存储器带宽对系统性能影响的最佳结构方案; 在微处理机内部设置各种缓冲存储器,减轻对存储器存取的压力。…...

QUICK 调试camera-xml解析
本文主要介绍如何在QUICK QCS6490使能相机模组。QCS6490的相机基于CameraX的框架,只需通过配置XML文件,设置相机模组的相关参数,就可以点亮相机。本文主要介绍Camera Sensor Module XML和Camera Sensor XML配置的解析,这中间需要c…...
【linux】shell脚本编写基础
shell 脚本关键字: 1、变量定义:前后不能空格 输入: zhao"Joe" echo ${zhao} echo "I am ${zhao}" 输出: yuxin I am Joe2、echo 输出 输入: echo "123" 输出: 1233、readonly 定义变…...
STM32 外设简介
STM32 外设简介 STM32 是由意法半导体 (STMicroelectronics) 开发的一系列基于 ARM Cortex 内核的微控制器,广泛应用于嵌入式系统中。STM32 系列的一个重要特点是其丰富而强大的外设模块,支持多种接口和功能,能满足工业控制、物联网、消费电…...
Django-Vue3-Admin - 现代化的前后端分离权限管理系统
项目介绍 Django-Vue3-Admin是一个基于RBAC(Role-Based Access Control)模型的综合性基础开发平台,专注于权限控制,支持列级别的细粒度权限管理。该项目采用前后端分离架构,技术栈包括: 后端: Django Django REST …...

Cesium K-means自动聚合点的原理
Cesium K-means自动聚合点的原理 Cesium 是一个开源的 JavaScript 库,用于在 Web 环境中创建 3D 地球和地图应用。它能够处理地理空间数据,并允许开发者对大规模的地理数据进行可视化展示。在一些应用中,尤其是当处理大量地理坐标点时&#…...
Vue 项目中如何解决组件之间的循环依赖
前言 在大型 Vue 项目中,组件之间的关系可能会变得非常复杂,甚至会出现循环依赖的问题。循环依赖是指两个或多个模块互相依赖,形成一个闭环。这类问题会导致项目无法正常编译或运行,甚至可能引发意想不到的错误。本文将通过通俗易…...

交通流量预测:基于交通流量数据建立模型
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...

Hot100 - 搜索二维矩阵II
Hot100 - 搜索二维矩阵II 最佳思路: 利用矩阵的特性,针对搜索操作可以从右上角或者左下角开始。通过判断当前位置的元素与目标值的关系,逐步缩小搜索范围,从而达到较高的效率。 从右上角开始:假设矩阵是升序排列的&a…...
uart_pl011.c驱动API的zephyr测试
API概述 本次测试针对uart的uart_poll_in和uart_poll_outAPI进行测试, uart_poll_in static int pl011_poll_in(const struct device *dev, unsigned char *c)这是一个轮询方式的接收函数: 功能:检查 UART 是否有新数据到达,如…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...