AIGC实战——深度学习 (Deep Learning, DL)
AIGC实战——深度学习
- 0. 前言
- 1. 深度学习基本概念
- 1.1 基本定义
- 1.2 非结构化数据
- 2. 深度神经网络
- 2.1 神经网络
- 2.2 学习高级特征
- 3. TensorFlow 和 Keras
- 4. 多层感知器 (MLP)
- 4.1 准备数据
- 4.2 构建模型
- 4.3 检查模型
- 4.4 编译模型
- 4.5 训练模型
- 4.6 评估模型
- 小结
- 系列链接
0. 前言
深度学习 (Deep Learning
, DL
) 是贯穿所有生成模型 (Generative Model
) 的共同特征,几乎所有复杂的生成模型都以深度神经网络为核心,深度神经网络能够学习数据结构中的复杂关系,而不需要预先提取数据特征。在本节中,我们将介绍深度学习基本概念,并利用 Keras
构建深度神经网络。
1. 深度学习基本概念
1.1 基本定义
深度学习 (Deep Learning
, DL
) 是一类机器学习算法,使用多个堆叠的处理单元层从非结构化数据中学习高级表示。
为了充分理解深度学习,尤其是理解深度学习在生成建模中的重要性,我们将首先介绍深度学习中常见的非结构化数据,然后探讨如何构建多个堆叠的处理单元层解决分类任务。
1.2 非结构化数据
多数类型的机器学习算法需要结构化的表格数据作为输入,表格数据中的每一列都用于描述观测数据的特征。例如,一个人的年龄、收入和上个月购物网站访问等特征有助于预测此人在下个月网络购物的金额,可以使用这些特征的结构化表格来训练逻辑回归、随机森林或 XGBoost
等模型,并使用这些模型预测连续空间的响应变量(模型预测输出结果),即此人的网购消费金额。在此示例中,每个特征都包含观测数据的一部分信息,模型将学习这些特征如何相互作用以影响响应变量。
非结构化数据指的是不能自然地将特征组织成列形式的数据,例如图像、音频、文本和视频等。其中,图像具有空间结构,音频或文本具有时间结构,而视频数据兼具空间和时间结构,但由于数据不是以特征列的形式组织,因此称为是非结构化数据,如下图所示。
在非结构化数据中,单个像素、频率或字符几乎不含任何信息。例如,知道一张图像的第 3
行、第 4
列的像素是白色并不能帮助我们确定这张图像是一只狗还是一只猫,知道一个句子的第 5
个单词是字母 that
也不能帮助我们预测这段文本是关于电影还是体育的。
实际上,像素或字符只是嵌入到更高级信息特征(例如小狗图像或 “football
” 单词)的一部分。无论图像中的小狗被放置屋子里或马路边,图像仍然包含小狗,只不过该信息将由不同的像素传递;无论文本中的 “football
” 稍早或稍晚出现,该文本仍然是关于足球的,只是该信息将由不同的字符位置提供。数据的细粒度和高度的空间依赖性破坏了像素或字符作为独立信息特征的意义。
因此,如果我们对原始像素值训练逻辑回归、随机森林或 XGBoost
模型,则训练后的模型通常只能处理最简单的分类任务,而在其他较复杂的任务中通常表现不佳。这些模型依赖于输入特征具有的信息量且不具有空间依赖性。而深度学习模型可以直接从非结构化数据中自行学习如何构建高级信息特征。
深度学习也可以应用于结构化数据,但其真正的作用(尤其在生成模型领域)来自于其处理非结构化数据的能力。通常,我们希望生成非结构化数据,比如新的图像或文本,这就是为什么深度学习对于生成模型领域有如此深远的影响的原因。
2. 深度神经网络
目前,大部分深度学习系统通过堆叠多个隐藏层构建人工神经网络 (Artificial Neural Networks
, ANNs
)。因此,深度学习现在几乎已经成为了深度神经网络的同义词。但需要注意的是,任何使用多个层来学习输入数据的高级表示的系统都是深度学习(例如深度信念网络和深度玻尔兹曼机)。
首先,我们详细介绍神经网络的基本概念,然后了解它们如何用于从非结构化数据中学习高级特征。
2.1 神经网络
神经网络是由一系列堆叠的层组成的,每一层包含多个单位,这些单元通过一组权重与前一层的单位相连接。有多种不同类型的层,其中最常见的是全连接层 (fully connected layer
),也称密集层 (dense layer
),它将该层的所有单位直接连接到前一层的每个单位。所有相邻层都是全连接层的神经网络被称为多层感知器 (Multilayer Perceptron
, MLP
)。
输入(例如图像)依次通过网络的每一层进行传递直到达到输出层,这一过程称为网络的前向传播过程。具体而言,每个单元对其输入的加权求和结果应用非线性变换,并将输出传递到下一层。前向传播过程的最终输出层是该过程的最终结果,其中每个单元输出原始输入属于特定类别(例如微笑)的概率。
深度神经网络通过寻找每个层的权重集,以产生最准确的预测,寻找最优权重的过程就是网络训练 (training
)。
在训练过程中,图像会按批 (batch
) 传递给神经网络,然后将预测输出与实际结果进行比较。例如,网络可能对一个微笑的人脸图像输出 80%
的概率,对一个不微笑的人脸的图像输出 23%
的概率,而实际结果应输出 100%
和 0%
,因此预测输出和实际结果存在误差。预测中的误差会向后传播到整个神经网络中,并沿着能够最显著改善预测的方向微调网络权重,这个过程称为反向传播 (backpropagation
)。每个神经网络单元都能够逐渐识别出一个特定的特征,最终帮助神经网络做出更准确的预测。
2.2 学习高级特征
神经网络的关键特性是能够在没有人工指导的情况下从输入数据中学习特征。换句话说,我们不需要进行任何特征工程,仅仅通过最小化预测误差的指导,模型就可以自动学习最优权重。
例如,在上一小节介绍的神经网络中,假设它已经完成训练能够准确地预测给定输入面部是否微笑:
- 单元
A
接收输入像素值 - 单元
B
将其输入值组合起来,当某个低级特征(如边缘)存在时,它会被激活 - 单元
C
与单元D
等将低级特征组合在一起,当图像中出现更高级别的特征(如眼睛)时,它会被激活 - 单元
E
将高级特征组合在一起,当图像中的人物出现微笑时,它会被激活
每个网络层中的单元能够通过组合前一层的低级特征表示学习到原始输入的复杂特征,这是在网络训练过程自动学习的,我们不需要告诉每个单元要学习什么,或者它要学习高级特征还是低级特征。
输入层和输出层之间的层被称为隐藏层 (hidden layers
),深度神经网络可以拥有任意数量的隐藏层。通过堆叠大量的网络层,神经网络可以逐渐从浅层的低级特征中捕捉信息,学习越来越高级别的特征。例如,ResNet
是设计用于图像识别的深度神经网络,包含 152
层。
接下来,我们将深入介绍深度学习中的常用技术,并使用 TensorFlow
和 Keras
库构建深度神经网络。
3. TensorFlow 和 Keras
TensorFlow
是由 Google
开发的用于机器学习的开源 Python
库。TensorFlow
是构建机器学习解决方案最常用的框架之一,其因张量 (tensor
) 操作而得名。在深度学习中,张量只是存储流经神经网络的数据的多维数组。它提供了训练神经网络所需的底层功能,例如高效计算任意可微表达式的梯度和执行张量操作。
Keras
是建立在 TensorFlow
上的高级 API
,它非常灵活且拥有非常易于使用的 API
,是入门深度学习的理想选择。此外,Keras
通过其函数式 API
提供了许多有用的构建模块,可以通过将它们连接在一起来创建复杂的深度学习架构。
使用 TensorFlow
和 Keras
组合能够在生产环境中构建复杂网络,可以快速实现所设计的网络模型。接下来,我们使用 Keras
构建多层感知器(Multilayer Perceptron
,MLP
)。
4. 多层感知器 (MLP)
在本节中,我们将使用监督学习训练一个 MLP
来对指定图像进行分类。监督学习是一种机器学习算法,通过带有标记的数据集进行训练,监督学习仍然在许多类型的生成模型中扮演重要角色。换句话说,用于训练的数据集包括带有输入数据相应的输出标签。算法的目标是学习输入数据和输出标签之间的映射关系,以便它可以对新的、未见过的数据进行预测。
4.1 准备数据
在本节中,我们将使用 CIFAR-10
数据集,这是一个 Keras
内置的数据集,其包含 60,000
张 32×32
像素的彩色图像,每张图片都被分类到其所属的类别(共有 10
个类别)。
默认情况下,图像数据中每个像素的默认值为在 0
到 255
之间的整数。我们首先需要通过将这些值缩放到 0
到 1
之间来预处理图像,因为神经网络在每个输入的绝对值小于 1
时效果最好。
我们还需要将图像的整数标签转换为独热编码 (one-hot
) 向量,因为神经网络的输出是图像属于每个类别的概率。如果图像的类别整数标签是 i
,则它的独热编码是长度为 10
(类别数量)的向量,除第 i
个元素值为 1
外,其他所有位置上元素值都为 0
。
(1) 导入所需库:
import numpy as np
import matplotlib.pyplot as plt
from keras import layers, models, optimizers, utils, datasets
NUM_CLASSES = 10
(2) 加载 CIFAR-10
数据集,其中 x_train
和 x_test
分别是形状为 [50000, 32, 32, 3]
和 [10000, 32, 32, 3]
的 numpy
数组,y_train
和 y_test
分别是形状为 [50000, 1]
和 [10000, 1]
的 numpy
数组,包含每个图像的类别标签,范围在 0
到 9
之间:
(x_train, y_train), (x_test, y_test) = datasets.cifar10.load_data()
(3) 对每张图像进行缩放,使得像素值介于 0
和 1
之间:
x_train = x_train.astype("float32") / 255.0
x_test = x_test.astype("float32") / 255.0
(4) 对标签进行独热编码,修改后的 y_train
和 y_test
的形状分别为 [50000, 10]
和 [10000, 10]
:
y_train = utils.to_categorical(y_train, NUM_CLASSES)
y_test = utils.to_categorical(y_test, NUM_CLASSES)
训练图像数据 (x_train
) 存储在形状为 [50000, 32, 32, 3]
的张量中。这个数据集没有列或行的概念,而是一个具有四个维度的张量,张量只是一个多维数组,它是矩阵超过两个维度的扩展。这个张量的第一个维度引用了数据集中图像的索引,第二和第三个维度与图像的尺寸相关,最后一个维度是通道(对于 RGB
图像而言是红色、绿色或蓝色通道)。使用以下方式可以获取图像中指定像素的通道值:
# 获取第100个图像中像素 (10,10) 的绿色通道值
print(x_train[100, 10, 10, 1])
4.2 构建模型
在 Keras
中,可以使用 Sequential
模型或函数 API
来定义神经网络的结构。
Sequential
模型用于快速定义一系列线性堆叠层(即一层直接紧随着下一层,没有任何分支)。我们可以使用 Sequential
类来定义 MLP
模型:
model = models.Sequential([layers.Flatten(input_shape=(32,32,3)),layers.Dense(200, activation='relu'),layers.Dense(150, activation='relu'),layers.Dense(10, activation='softmax'),
])
但许多模型需要从一个层传递输出到多个后续层,或者一个层接收其上多个层的输入。对于这些模型,Sequential
类就不再适用,我们需要使用更加灵活的函数 API
。随着神经网络的架构变得越来越复杂,函数 API
将能够更好的满足需求,给予我们随心所欲设计深度神经网络的自由。
接下来,我们使用使用函数 API
构建相同 MLP
,在使用函数 API
时,使用 Model
类来定义模型的整体输入和输出层:
input_layer = layers.Input((32, 32, 3))
x = layers.Flatten()(input_layer)
x = layers.Dense(200, activation="relu")(x)
x = layers.Dense(150, activation="relu")(x)
output_layer = layers.Dense(NUM_CLASSES, activation="softmax")(x)
model = models.Model(input_layer, output_layer)
使用以上两种方法可以得到相同的模型:
神经网络层
为了构建 MLP
,我们使用了三种不同类型的层:Input
、Flatten
和 Dense
。接下来,我们详细地介绍在 MLP
中使用的不同层和激活函数。
Input
层是神经网络的入口,以元组形式告诉网络每个数据元素的形状,不需要显式地指定批大小,因为我们可以同时传递任意数量的图像到 Input
层。
接下来,使用 Flatten
层将输入展平成一个向量,得到一个长度为 32 × 32 × 3=3,072
的向量。这是由于后续的 Dense
层要求其输入是一维的,而不是多维数组。而有些类型的层需要多维数组作为输入,因此需要了解每种类型的层所需的输入和输出形状,以理解何时需要使用 Flatten
。
Dense
层是神经网络中最基本的层类型之一。它包含给定数量的单元,该层中的每个单元与前一层中的每个单元通过一个权重连接。给定单元的输出是它从前一层接收到的输入的加权和,然后通过非线性激活函数传递给下一层。激活函数用于确保神经网络能够学习复杂函数,而不仅仅输出其输入的线性组合。
激活函数
有多种类型的激活函数,我们主要介绍以下三种激活函数:ReLU
、sigmoid
和 softmax
。
ReLU
(Rectified Linear Unit
) 激活函数在输入为负时定义为 0
,否则等于输入值。LeakyReLU
激活函数与 ReLU
非常相似,关键区别在于:ReLU
激活函数对于小于 0
的输入值返回 0
,而 LeakyReLU
函数返回与输入成比例的一个小的负数。如果 ReLU
单元始终输出 0
,则梯度同样为 0
,因此误差无法通过该单元反向传播。LeakyReLU
激活通过始终确保梯度非零来解决此问题。基于 ReLU
的函数是在深度网络的层之间使用的最可靠的激活函数之一,可以确保模型稳定的训练。
如果我们希望某一层的输出介于 0
到 1
之间,则可以使用 sigmoid
激活函数,例如用于具有一个输出单元的二分类问题。下图为 ReLU
、LeakyReLU
和 sigmoid
激活函数的函数图像:
如果我们希望某一网络层的输出总和等于 1
,则可以使用 softmax
激活函数,例如在多类别分类问题中,每个观测样本只属于一个类别,函数定义如下:
y i = e x i ∑ j = 1 J e x j y_i = \frac {e^{x_i}}{∑_{j=1}^J e^{x_j}} yi=∑j=1Jexjexi
其中, J J J 是层中的单元总数。在上述构建的神经网络中,我们在最后一层使用 softmax
激活函数,以确保输出包含 10
个概率值,这些概率值相加为 1
,可表示图像属于每个类别的可能性。
在 Keras
中,可以在层内定义激活函数或将其作为单独的层定义:
# 方法1
x = layers.Dense(units=200, activation = 'relu')(x)
# 方法2
x = layers.Dense(units=200)(x)
x = layers.Activation('relu')(x)
在以上代码中,我们将输入通过两个 Dense
层,第一层有 200
个单元,第二层有 150
个单元,两层均使用 ReLU
激活函数。
4.3 检查模型
我们可以使用 model.summary()
方法来检查神经网络每一层的形状:
print(model.summary())
可以看到,输入层 Input
的形状与 x_train
的形状相匹配,而输出层的形状与 y_train
的形状匹配。Keras
使用 None
作为标记,表示它尚不明确将传递给网络的观测样本数量。实际上,它也不需要知道,因为一次只传递 1
个观测样本对象或 1000
个观测样本对象给网络是一样的。这是由于张量操作使用线性代数在所有观测样本对象上同时进行。这也是为什么在 GPU
上训练深度神经网络比 CPU
上训练可以提高效率的原因之一,因为 GPU
针对大型张量操作进行了优化。
summary
方法还会给出每个层中需要进行训练的参数(权重)数量。如果模型训练速度过慢,可以使用 summary
查看是否有包含大量权重的层。如果有此类层,可以考虑减少层中的单元数量以加速训练。
最后,我们介绍如何计算每个层中的参数数量。默认情况下,给定层中的每个单元会连接到一个额外的偏置单元,用于确保即使来自前一层的所有输入为 0
,单元的输出仍然可以是非零值。因此,在一个包含 200
个单元的 Dense
层中(假设输入像素数为 3072
),参数数量为 200 * (3072 + 1) = 614,600
。
4.4 编译模型
使用优化器和损失函数编译模型:
opt = optimizers.Adam(learning_rate=0.0005)
model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"]
)
接下来,我们详细介绍损失函数和优化器。
损失函数
损失函数 (loss function
) 用于神经网络将其预测输出与真实值进行比较。它为每个观测样本对象返回一个值,值越大,表明神经网络针对该观测样本对象所得出的输出结果就越差。
Keras
提供了许多内置的损失函数可供选择,我们也可以创建自定义损失函数。常用的损失函数包括均方误差 (mean squared error
)、分类交叉熵 (categorical cross-entropy
) 和二元交叉熵 (binary cross-entropy
)。我们需要根据实际问题选择合适的损失函数。
如果神经网络旨在解决回归问题(即输出是连续值),那么可以使用均方误差损失。均方误差是每个输出单元的实际值 y i y_i yi 与预测值 p i p_i pi 之差的平方的均值,其中均值是在所有 n n n 个输出单元上进行计算:
M S E = 1 n Σ i = 1 n ( y i − p i ) 2 MSE = \frac1 n Σ_{i=1}^n {(y_i - p_i)^2} MSE=n1Σi=1n(yi−pi)2
如果需要处理分类问题,其中每个观测样本对象只属于一个类别,那么可以使用分类交叉熵是作为损失函数。其定义如下:
− Σ i = 1 n y i l o g ( p i ) -Σ_{i=1}^n{y_ilog(p_i)} −Σi=1nyilog(pi)
如果需要处理具有一个输出单元的二分类问题,或者每个观测样本可以同时属干多个类别的多分类问题,则应该使用二元交叉熵:
− 1 n Σ i = 1 n ( y i l o g ( p i ) + ( 1 − y i ) l o g ( 1 − p i ) ) -\frac 1 n Σ_{i=1}^n {(y_ilog(p_i) + (1-y_i)log(1-p_i))} −n1Σi=1n(yilog(pi)+(1−yi)log(1−pi))
优化器
优化器 (optimizer
) 是根据损失函数的梯度来更新神经网络权重的算法。Adam
是最常用且稳定的优化器之一,在大多数情况下,除了学习率 (learning rate
) 外,我们不需要调整 Adam
优化器的默认参数。学习率越大,每个训练步骤中权重的改变就越大。虽然使用较大的学习率在初始时训练速度更快,但缺点是可能导致训练不稳定,并且可能无法找到损失函数的全局最小值。因此需要在训练过程中调整该参数。
另一个常见的优化器是 RMSProp
,同样,我们不需要过多调整此优化器的默认参数。
我们将损失函数和优化器都传递给模型的 compile
方法,并通过 metrics
参数指定我们在训练期间希望监测的其他指标,例如准确率。
4.5 训练模型
到目前为止,我们还没有向模型传递任何数据,只是构建了模型架构,并使用损失函数和优化器编译了模型。要传递数据训练模型,只需调用 fit
方法:
model.fit(x_train, y_train, batch_size=32, epochs=20, shuffle=True)
其中,x_train
表示原始图像数据,y_train
表示 one-hot
编码的类别标签,batch_size
决定每个训练步骤中将传递给网络的观测样本数量,epochs
决定将完整的训练数据展示给网络的次数,shuffle = True
表示每个训练步骤中都会以无放回的方式从训练数据中随机抽取批数据。
训练深度神经网络,用于预测 CIFAR-10
数据集中的图像类别。训练过程如下:
首先,将神经网络的权重初始化为很小的随机值。然后,网络执行一系列的训练步骤。在每个训练步骤中,通过网络传递一批图像,并进行误差反向传播以更新权重。batch_size
决定每个训练步骤的批数据中包含多少图像。批大小越大,梯度计算越稳定,但每个训练步骤速度越慢。如果在每个训练步骤中都使用整个数据集计算梯度,将非常耗时且计算量过大,因此通常将批大小设置在 32
到 256
之间。
这个过程一直持续到数据集中的所有观测样本都被处理过 1
次为止,这样就完成了第一个 epoch
。然后在第二个 epoch
中,数据再次以批的形式通过网络进行传递。重复以上过程,直到完整指定的 epoch
次数。
在训练过程中,Keras
输出训练过程的进展情况,如下图所示。可以看到训练数据集被分成 1,563
个批(每批包含 32
个图像),并且它已经在网络中展示了 10
次(即经历了 10
个 epoch
),每批的处理速率约为 2
毫秒。分类交叉熵损失从 1.8534
下降到 1.2557
,准确率从 33.20%
增加到 55.20%
。
4.6 评估模型
该模型在训练集上的准确率为 55.50%
,为了评估模型在从未见过的数据上表现,可以使用 Keras
提供的 evaluate
方法:
model.evaluate(x_test, y_test)
# 313/313 [==============================] - 0s 826us/step - loss: 1.3732 - accuracy: 0.5118
输出是我们监测的指标列表:分类交叉熵和准确率。可以看到,即使对于从未见过的图像,该模型的准确率仍然为 51.18%
,考虑到我们仅仅使用了一个非常基本的神经网络,49.0%
可以说是一个很好的结果。
可以使用 predict
方法查看测试集上的预测结果:
CLASSES = np.array(["airplane","automobile","bird","cat","deer","dog","frog","horse","ship","truck",]
)preds = model.predict(x_test)
preds_single = CLASSES[np.argmax(preds, axis=-1)]
actual_single = CLASSES[np.argmax(y_test, axis=-1)]
preds
是一个形状为 [10000, 10]
的数组,即每个观测样本对应一个包含 10
个类别概率的向量。
使用 numpy
的 argmax
函数将这个概率数组转换回单个预测结果。其中,使用 axis = -1
指定数组在最后一个维度(即类别维度)上压缩,因此 preds_single
的形状为 [10000, 1]
。
我们可以使用以下代码查看图片以及它们的标签和预测结果:
n_to_show = 10
indices = np.random.choice(range(len(x_test)), n_to_show)fig = plt.figure(figsize=(15, 3))
fig.subplots_adjust(hspace=0.4, wspace=0.4)for i, idx in enumerate(indices):img = x_test[idx]ax = fig.add_subplot(1, n_to_show, i + 1)ax.axis("off")ax.text(0.5,-0.35,"pred = " + str(preds_single[idx]),fontsize=10,ha="center",transform=ax.transAxes,)ax.text(0.5,-0.7,"act = " + str(actual_single[idx]),fontsize=10,ha="center",transform=ax.transAxes,)ax.imshow(img)plt.show()
下图展示了模型的对随机选择数据的预测结果及其真实标签:
小结
深度学习是一种机器学习算法,它通过构建多层神经网络模型,自动地从输入数据中进行特征学习,并输出对应的预测结果。深度神经网络是构建生成模型的基础,几乎所有复杂的生成模型都以深度神经网络为核心。构建生成模型时,其核心思想在于正确组合损失函数、激活函数和层形状等。在本节中,介绍了生成模型与深度学习之间的联系,以及深度神经网络模型中的各种基本组件,并使用 Keras
构建了一个简单的多层感知器。
系列链接
AIGC实战——生成模型简介
AIGC实战——卷积神经网络(Convolutional Neural Network, CNN)
AIGC实战——自编码器(Autoencoder)
AIGC实战——变分自编码器(Variational Autoencoder, VAE)
AIGC实战——使用变分自编码器生成面部图像
AIGC实战——生成对抗网络(Generative Adversarial Network, GAN)
AIGC实战——WGAN(Wasserstein GAN)
相关文章:

AIGC实战——深度学习 (Deep Learning, DL)
AIGC实战——深度学习 0. 前言1. 深度学习基本概念1.1 基本定义1.2 非结构化数据 2. 深度神经网络2.1 神经网络2.2 学习高级特征 3. TensorFlow 和 Keras4. 多层感知器 (MLP)4.1 准备数据4.2 构建模型4.3 检查模型4.4 编译模型4.5 训练模型4.6 评估模型 小结系列链接 0. 前言 …...

Django_基本增删改查
一、前提概述 通过项目驱动来学习,以图书管理系统为例,编写接口来实现对图书信息的查询,图书的添加,图书的修改,图书的删除等功能。(不包含多重信息的校验,只为了熟悉增删改查接口的实现流程&a…...

数仓治理-存储资源治理
目录 一、存储资源治理的背景 二、存储资源治理的流程及思路 三、治理前如何评估 3.1 无用数据表/临时数据表下线评估 3.2 表及分区的生命周期评估 3.3 存储及压缩格式评估 3.4 根据业务场景实现节省存储评估 四、治理后的成效如何评估 一、存储资源治理的背景 由于早…...

Linux系统安全:安全技术 和 防火墙
一、安全技术 入侵检测系统(Intrusion Detection Systems):特点是不阻断任何网络访问,量化、定位来自内外网络的威胁情况,主要以提供报警和事后监督为主,提供有针对性的指导措施和安全决策依据,类 似于监控…...

3dmatch-toolbox详细安装教程-Ubuntu14.04
3dmatch-toolbox详细安装教程-Ubuntu14.04 前言docker搭建Ubuntu14.04安装第三方库安装cuda/cundnn安装OpenCV安装Matlab 安装以及运行3dmatch-toolbox1.安装测试3dmatch-toolbox(对齐两个点云) 总结 前言 paper:3DMatch: Learning Local Geometric Descriptors from RGB-D Re…...

Hadoop与Spark横向比较【大数据扫盲】
大数据场景下的数据库有很多种,每种数据库根据其数据模型、查询语言、一致性模型和分布式架构等特性,都有其特定的使用场景。以下是一些常见的大数据数据库: NoSQL 数据库:这类数据库通常用于处理大规模、非结构化的数据。它们通常…...

软件工程知识梳理5-实现和测试
编码和测试统称为实现。 编码:把软件设计结果翻译成某种程序设计语言书写的程序。是对设计的进一步具体化,是软件工程过程的一个阶段。 测试:单元测试和集成测试,软件测试往往占软件开发总工作量的40%以上。 编码:选…...

WebRTC系列-自定义媒体数据加密
文章目录 1. 对外加密接口2. 对外加密实现前面的文章都有提过WebRTC使用的加密方式是SRTP这个库提供的,这个三方库这里就不做介绍,主要是对rtp包进行加密;自然的其调用也是WebRTC的rtp相关模块;同时在WebRTC里也提供一个自定义加密的接口,本文将围绕这个接口做介绍及分析;…...

golang的sqlite驱动不使用cgo实现 更换gorm默认的SQLite驱动
golang的sqlite驱动不使用cgo实现 更换gorm默认的SQLite驱动 最近在开发一个边缘物联网程序时使用Golang开发,用到GORM来操作SQLite数据库,GORM默认使用gorm.io/driver/sqlite这个库作为SQLite驱动,该库用CGO实现,在使用过程中遇…...

Linux 系统 ubuntu22.04 发行版本 固定 USB 设备端口号
前言: 项目中为了解决 usb 设备屏幕上电顺序导致屏幕偏移、触屏出现偏移等问题。 一、方法1:使用设备 ID 号 步骤: 查看 USB 设备的供应商ID和产品ID Bus 001 Device 003: ID 090c:1000 Silicon Motion, Inc. - Taiwan (formerly Feiya Te…...

Vue - 面试题持续更新
1.Vue路由模式 总共有Hash和History两种模式 Hash模式:在浏览器里面的符号 “#”,以及"#"后面的字符称之为Hash,用window.location.hash读取。 Hash模式的特点:hash是和浏览器对话的,和服务器没有关系&…...

Django的web框架Django Rest_Framework精讲(二)
文章目录 1.自定义校验功能(1)validators(2)局部钩子:单字段校验(3)全局钩子:多字段校验 2.raise_exception 参数3.context参数4.反序列化校验后保存,新增和更新数据&…...

VR视频编辑解决方案,全新视频内容创作方式
随着科技的飞速发展,虚拟现实(VR)技术正逐渐成为各个领域的创新力量。而美摄科技,作为VR技术的引领者,特别推出了一套全新的VR视频编辑方案,为企业提供了一个全新的视频内容创作方式。 美摄科技的VR视频编…...

有趣的CSS - 输入框选中交互动效
页面效果 此效果主要使用 css 伪选择器配合 html5 required 属性来实现一个简单的输入框的交互效果。 此效果可适用于登录页入口、小表单提交等页面,增强用户实时交互体验。 核心代码部分,简要说明了写法思路;完整代码在最后,可直…...

Unknown custom element:<xxx>-did you register the component correctly解决方案
如图所示控制台发现了爆红(大哭): 报错解释: 当我们看到报错时,我们需要看到一些关键词,比如显眼的“component”和“name”这两个单词, 因此我们就从此处切入,大概与组件有关系。…...

计算机网络自顶向下Wireshark labs-HTTP
我直接翻译并在题目下面直接下我的答案了。 1.基本HTTP GET/response交互 我们开始探索HTTP,方法是下载一个非常简单的HTML文件 非常短,并且不包含嵌入的对象。执行以下操作: 启动您的浏览器。启动Wireshark数据包嗅探器,如Wir…...

解决pandas写入excel时的ValueError: All strings must be XML compatible报错
报错内容: ValueError: All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control characters 报错背景 用pands批量写入excel文件,发生编码报错。检索了很多方案,都不能解决。 导致报错的原因是存在违法字符&…...

华为手表应用APP开发:watch系列 GT系列 1.配置调试设备
表开发:GT3(1)配置调试设备 初环境与设备获取手表UUID登录 AppGallery Connect 点击用户与访问初 希望能写一些简单的教程和案例分享给需要的人 鸿蒙可穿戴开发 支持外包开发:xkk9866@yeah.net 环境与设备 系统:window 设备:HUAWEI WATCH 3 Pro 开发工具:DevEco St…...

Vue(十九):ElementUI 扩展实现树形结构表格组件的勾父选子、半勾选、过滤出半勾选节点功能
效果 原理分析 从后端获取数据后,判断当前节点是否勾选,从而判断是否勾选子节点勾选当前节点时,子节点均勾选全勾选与半勾选与不勾选的样式处理全勾选和全取消勾选的逻辑筛选出半勾选的节点定义变量 import {computed, nextTick, reactive, ref} from vue; import {tree} f…...

SpringBoot RestTemplate 设置挡板
项目结构 代码 BaffleConfig /*** Description 记录配置信息* Author wjx* Date 2024/2/1 14:47**/ public interface BaffleConfig {// 是否开启挡板的开关public static boolean SWITCH true;// 文件根目录public static String ROOT_PATH "D:\\TIS\\mock";// …...

arcgis javascript api4.x加载非公开或者私有的arcgis地图服务
需求: 加载arcgis没有公开或者私有的地图服务,同时还想实现加载时不弹出登录窗口 提示: 下述是针对独立的arcgis server,没有portal的应用场景; 如果有portal可以参考链接:https://mp.weixin.qq.com/s/W…...

2024年美赛数学建模A题思路分析 - 资源可用性和性别比例
# 1 赛题 问题A:资源可用性和性别比例 虽然一些动物物种存在于通常的雄性或雌性性别之外,但大多数物种实质上是雄性或雌性。虽然许多物种在出生时的性别比例为1:1,但其他物种的性别比例并不均匀。这被称为适应性性别比例的变化。…...

UDP和TCP的区别和联系
传输层:定义传输数据的协议端口号,以及流控和差错校验。 协议有:TCP、UDP等 UDP和TCP的主要区别包括以下几个方面: 1、连接性与无连接性:TCP是面向连接的传输控制协议,而UDP提供无连接的数据报服务。这意…...

delete、truncate和drop区别
一、从执行速度上来说 drop > truncate >> DELETE 二、从原理上讲 1、DELETE DELETE from TABLE_NAME where xxx1.1、DELETE属于数据库DML操作语言,只删除数据不删除表的结构,会走事务,执行时会触发trigger( 触发器…...

946. 验证栈序列
946. 验证栈序列 描述 : 给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false 。 题目 : LeetCode 94…...

Linux系统管理和Shell脚本笔试题
1、写一个sed命令,修改/tmp/input.txt文件的内容,要求:(1) 删除所有空行;(2) 在非空行前面加一个"AAA",在行尾加一个"BBB",即将内容为11111的一行改为:AAA11111BBB #写入内…...

docker 搭建 Seafile 集成 onlyoffice
docker-compose一键部署yaml文件 version: "3"services:db:image: mariadb:10.11container_name: seafile-mysqlenvironment:- MYSQL_ROOT_PASSWORDdb_dev # Requested, set the roots password of MySQL service.- MYSQL_LOG_CONSOLEtruevolumes:- /share/ZFS18_D…...

【Spring Boot 3】【JPA】嵌入式对象
【Spring Boot 3】【JPA】嵌入式对象 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花费或…...

STM32控制DS18B20温度传感器获取温度
时间记录:2024/1/28 一、DS18B20温度传感器介绍 (1)测温范围-55℃~125℃,在-10℃到85℃范围内误差为0.4 (2)返回的温度数据为16位二进制数据 (3)STM32和DS18B20通信使用单总线协议…...

服务器常遇的响应状态码
服务器常遇的响应状态码 状态码 500 表示服务器内部错误。 这种状态码意味着服务器在尝试执行请求时遇到了意外情况。在处理这种状态码时,我们需要联系服务器管理员或服务提供商以获取更多信息。 处理方法:联系服务器管理员或服务提供商以获取更多信息…...