经典机器学习模型(一)感知机模型

经典机器学习模型(一)感知机模型

感知机可以说是一个相当重要的机器学习基础模型,是神经网络和支持向量机的基础。

感知机是一个二分类的线性分类模型,之所以说是线性,是因为它的模型是线性形式的。

从《统计学习方法》中,我们知道学习方法的三要素为模型、策略、算法,我们就从三要素来了解下感知机。

1 感知机模型的三要素

1.1 模型

1.1.1 感知机模型

在这里插入图片描述

  • 输入空间

    • 这里 χ \chi χ代表 n n n维实数空间的一个子集
    • 输入的每一个实例 x x x,用一个 n n n维的特征向量表示,它是属于输入空间 χ \chi χ的。
    • 实例 x = ( x ( 1 ) , x ( 2 ) , . . . , x ( n ) ) T x=(x^{(1)},x^{(2)},...,x^{(n)})^T x=(x(1),x(2),...,x(n))T
  • 输出空间

    • 由于这是一个二分类模型,所以这里输出空间是一个只包含+1和-1的一个集合。

    • 1 代表的是正类,-1 代表的是负类,具体的输出则是代表实例 x x x所对应的类别。

  • 感知机

    • 我们定义一个从输入空间到输出空间的函数,这个函数就称作感知机。

    • 这个函数 s i g n ( x ) sign(x) sign(x)叫做符号函数

    • w ⋅ x = ( w ( 1 ) x ( 1 ) , w ( 2 ) x ( 2 ) , . . . , w ( n ) x ( n ) ) T w\cdot x=(w^{(1)}x^{(1)},w^{(2)}x^{(2)},...,w^{(n)}x^{(n)})^T wx=(w(1)x(1),w(2)x(2),...,w(n)x(n))T

  • 假设空间

    • 特征空间里面所有可能的线性函数就称为假设空间。
  • 参数空间

    • 参数 w w w b b b的所有组合,就得到一个 n n n维的空间,也就是参数空间。

1.1.2 感知机模型的几何意义

我们从几何角度来解释一下感知器,如下图所示:

  • 线性方程 w ⋅ x + b = 0 w\cdot x +b = 0 wx+b=0代表着 n n n维特征空间里面的一个超平面 S S S

  • w w w是法向量,垂直于超平面 S S S b b b是相应的截距项。

  • 通过超平面 S S S我们就可以将整个特征空间分为两部分

    • 一部分是正类,其中的实例所对应的输出为 +1;
    • 一部分为负类,它里面的实例所对应的输出为 -1。所以这个超平面被称为分离超平面。
  • 超平面的理解。

    • 如果我们现在的特征空间是一维的,那么想区分正负类实例点,用实数轴上的一个点就可以了,比如零点。
    • 如果特征空间是两维的,实例应该就是二维空间中的一个点,要区分正负类,它的分离超平面对应的应该是一条直线(如下图)。
    • 如果可能空间是三维的,分离超平面应该就是一个二维平面了。
    • 依此类推,如果环境空间是 n n n维的,那么它所对应的超平面其实就是一个 n − 1 n-1 n1维的子空间。
  • 原点到超平面的距离为 − b ∣ ∣ w ∣ ∣ -\frac{b}{||w||} ∣∣w∣∣b

在这里插入图片描述

1.2 策略

如果假设训练数据集线性可分,我们的目标则是希望寻求到一个的分离超平面,把这些实例点完全划分为正负类

但是,要求得这样一个超平面,就需要确定模型的参数,即w和b,这就需要制定一定的学习策略。换而言之,就是要合理地定义感知机相应的损失函数

1.2.1 线性可分数据集

感知机模型,有一个比较严苛的条件,就是要求数据集必须是线性可分的。

线性可分的意思如下:

对于给定的数据集,如果存在某个超平面,使得这个数据集的所有实例点可以完全划分到超平面的两侧,也就是正类和负类。我们就称这个数据集是线性可分的,否则线性不可分。

1.2.2 感知机的损失函数

特征空间中的任意一点到超平面的距离公式如下:
1 ∣ ∣ w ∣ ∣ ∣ w ⋅ x 0 + b ∣ \frac{1}{||w||}|w\cdot x_0+b| ∣∣w∣∣1wx0+b
如果 x 0 x_0 x0是错误的分类点,那么容易得到下式:
1 ∣ ∣ w ∣ ∣ ∣ w ⋅ x 0 + b ∣ = { − w ⋅ x 0 + b ∣ ∣ w ∣ ∣ , y 0 = 1 w ⋅ x 0 + b ∣ ∣ w ∣ ∣ , y 0 = − 1 = − ( w ⋅ x 0 + b ) y 0 ∣ ∣ w ∣ ∣ \frac{1}{||w||}|w\cdot x_0+b|=\begin{cases} -\frac{w\cdot x_0+b}{||w||}, & y_0 = 1\\ \\ \frac{w\cdot x_0+b}{||w||}, & y_0 = -1 \end{cases}=-\frac{(w\cdot x_0+b)y_0}{||w||} ∣∣w∣∣1wx0+b= ∣∣w∣∣wx0+b,∣∣w∣∣wx0+b,y0=1y0=1=∣∣w∣∣(wx0+b)y0
现在我们要关注的就是这里的错误分类点,设误分类点为 x i x_i xi,那么 x i x_i xi到超平面 S S S的距离为:
− ( w ⋅ x i + b ) y i ∣ ∣ w ∣ ∣ -\frac{(w\cdot x_i+b)y_i}{||w||} ∣∣w∣∣(wxi+b)yi
如果用 M M M代表所有误分类点的集合,我们可以写出所有误分类点到超平面 S S S的距离的总和:
− 1 ∣ ∣ w ∣ ∣ ∑ x i ∈ M ( w ⋅ x i + b ) y i -\frac{1}{||w||}\sum\limits_{x_i\in M}(w\cdot x_i+b)y_i ∣∣w∣∣1xiM(wxi+b)yi
很明显, M M M中所含有的误分类点越少的时候,总距离和应该越小。在没有误分类点的时候, 这个距离和应该为 0。我们希望通过最小化总距离和来求参数。

因此,我们就得到了感知机模型的损失函数如下:
L ( w , b ) = − ∑ x i ∈ M ( w ⋅ x i + b ) y i , M 为误分类点的集合 L(w,b)=-\sum\limits_{x_i\in M}(w\cdot x_i+b)y_i,M为误分类点的集合 L(w,b)=xiM(wxi+b)yiM为误分类点的集合

1.3 算法(原始形式)

  • 假如给定训练数据集,我们通过最小化损失函数,就可以估计得到模型参数。

  • 如何求参数 w w w b b b呢?这就是一个优化问题,寻找使损失函数最小的参数

在这里插入图片描述

想求这个损失函数的极小值,可以先求梯度,即分别求偏导数,得到梯度向量,然后用梯度下降法对参数更新。

需要注意的是,梯度下降法用的是负梯度,所以我们求梯度的时候得到的负号就抵消掉了

  • 如果是批量更新,就需要每次使用所有的误分类点,这会致使每一轮的迭代都需要大量的时间。

  • 随机梯度下降法,每一轮随机选择一个误分类点,迭代的速度会快一些。

    • 这是因为,如果通过这个误分类点进行参数的更新,有可能误分类点就会减少,那么下一步我们可用来选择更新参数的实例点就会减少,这在一定程度上简化计算,节约了时间。
  • 小批量梯度下降法既不是像批量梯度下降法中那样选择了所有的样本点,也不是像随机梯度下降法中随机选取了一个样本点,而是选择部分样本点进行参数更新。

    • 但是,小批量梯度下降法,也面临许多问题,比如每次需要选择多少个样本点?选择哪些样本才合适呢?

损失函数 L ( w , b ) = − ∑ x i ∈ M ( w ⋅ x i + b ) y i , M 为误分类点的集合 对 w 和 b 分别求偏导数,可得梯度为: ∇ w L ( w , b ) = − ∑ x i ∈ M x i y i ∇ b L ( w , b ) = − ∑ x i ∈ M y i 批量梯度下降法: w ← w + η ∑ x i ∈ M x i y i , b ← b + η ∑ x i ∈ M y i 随机梯度下降法 : w ← w + η x i y i , b ← b + η y i 其中, η ( 0 < η < = 1 ) 为步长 损失函数L(w,b)=-\sum\limits_{x_i\in M}(w\cdot x_i+b)y_i,M为误分类点的集合 \\ 对w和b分别求偏导数,可得梯度为: \\ \nabla_w L(w,b)=-\sum\limits_{x_i\in M}x_iy_i \\ \nabla_b L(w,b)=-\sum\limits_{x_i\in M}y_i \\ 批量梯度下降法:w\leftarrow w + \eta\sum\limits_{x_i\in M}x_iy_i,b\leftarrow b + \eta\sum\limits_{x_i\in M}y_i \\ 随机梯度下降法: w\leftarrow w + \eta x_iy_i,b\leftarrow b + \eta y_i\\ 其中,\eta(0<\eta<=1)为步长 \\ 损失函数L(w,b)=xiM(wxi+b)yiM为误分类点的集合wb分别求偏导数,可得梯度为:wL(w,b)=xiMxiyibL(w,b)=xiMyi批量梯度下降法:ww+ηxiMxiyi,bb+ηxiMyi随机梯度下降法:ww+ηxiyi,bb+ηyi其中,η(0<η<=1)为步长

1.3.1 随机梯度下降法

现在我们以随机梯度下降法来讲解感知机的算法,如下:

在这里插入图片描述

  • 首先选择初始值。
  • 接下来,在训练集中随机选取一个实例点,用 y i ( w x i + b ) y_i(wx_i+b) yi(wxi+b)来判断这个点被分离超平面正确分类还是错误分类。
    • 如果被正确分类, y i ( w x i + b ) y_i(wx_i+b) yi(wxi+b)就是大于零的,我们不用管这个实例点了;
    • 如果被错误分类, y i ( w x i + b ) y_i(wx_i+b) yi(wxi+b)就是小于零的,我们可以把这个实例点拿来更新参数。
    • 最麻烦的就是,如果这个实例点恰好位于分离超平面上,那么 y i ( w x i + b ) y_i(wx_i+b) yi(wxi+b)就直接等于零,无法知道此时这个实例点到底是被正确分类还是错误分类。所以,本着宁肯错杀也不能放过的原则,我们把这个实例点拿来更新参数。
  • 这样第三步就完成了。
  • 接着就是步骤的重复,直到所有的实例点都确定被正确分类。

1.3.2 感知机算法例题

在这里插入图片描述

我们这里使用python代码求解该例题:

完整代码可参考:Statistical_Learning_Methods_Impl: 《统计学习方法》第二版 python代码实现

import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
%matplotlib inline# 1、加载数据
data = np.array([[3, 3, 1],[4, 3, 1],[1, 1, -1]
])
# 获取X和y
X, y = data[:,:-1], data[:,-1]# 2、画图
plt.scatter(X[:2][0], X[:2][1], label='1')
plt.scatter(X[2:][0], X[2:][0], label='-1')
plt.xlabel('x0')
plt.ylabel('x1')
# 设置x轴和y轴范围
plt.xlim(0, 7)
plt.ylim(0, 7)
plt.legend()

在这里插入图片描述

# 3、创建模型
class Perceptron(object):def __init__(self, num_features, l_rate=1, w='0'):# 初始化参数w、b以及学习率l_rateif w == '0':self.w = np.zeros(num_features, dtype=np.float32)elif w == '1':self.w = np.ones(num_features, dtype=np.float32)else:raise Exception('Unsupported parameter w')self.b = 0self.l_rate = l_ratedef sign(self, x, w, b):# 计算:xw + breturn np.dot(x, w) + bdef fit(self, X_train, y_train):# 随机梯度下降法is_wrong = Falsewhile not is_wrong:# 误分类点的个数wrong_count = 0for index in range(len(X_train)):# 取出一个点X = X_train[index]y = y_train[index]# 如果该点为误分类点,就进行迭代if y * self.sign(X, self.w, self.b) <= 0:# 更新wself.w += self.l_rate * np.dot(y, X)# 更新bself.b += self.l_rate * y# 误分类点+1wrong_count += 1print(f'取出的误分类点为x{index + 1}, 更新后w = {self.w}, b = {self.b},  wx+b = {self.w[0]}x1 + {self.w[1]}x2 + {self.b}')# 一次循环迭代结束后,如果没有误分类点,就结束if wrong_count == 0:is_wrong = Truereturn 'Perceptron Model'def predict(self,X_predict):y = np.dot(X_predict, self.w) + self.breturn np.sign(y)def score(self):pass
# 进行训练
num = len(X[0])
net1 = Perceptron(num_features=num)
net1.fit(X, y)
取出的误分类点为x1, 更新后w = [3. 3.], b = 1,   wx+b = 3.0x1 + 3.0x2 + 1
取出的误分类点为x3, 更新后w = [2. 2.], b = 0,   wx+b = 2.0x1 + 2.0x2 + 0
取出的误分类点为x3, 更新后w = [1. 1.], b = -1,  wx+b = 1.0x1 + 1.0x2 + -1
取出的误分类点为x3, 更新后w = [0. 0.], b = -2,  wx+b = 0.0x1 + 0.0x2 + -2
取出的误分类点为x1, 更新后w = [3. 3.], b = -1,  wx+b = 3.0x1 + 3.0x2 + -1
取出的误分类点为x3, 更新后w = [2. 2.], b = -2,  wx+b = 2.0x1 + 2.0x2 + -2
取出的误分类点为x3, 更新后w = [1. 1.], b = -3,  wx+b = 1.0x1 + 1.0x2 + -3

可以看到和书籍上迭代过程一样:

在这里插入图片描述

经过上述迭代,我们就得到最终模型:
f ( x ) = s i g n ( x ( 1 ) + x ( 2 ) − 3 ) f(x)=sign(x^{(1)}+x^{(2)}-3) f(x)=sign(x(1)+x(2)3)
需要注意的是,感知机模型并不唯一,不同的初值或者说不同的误分类点的顺序,可以得到不同的分离超平面。

我们可以实验下,将w的初始值设置为1,就得到了另一个超平面。

# 进行训练
num = len(X[0])
net2 = Perceptron(num_features=num, w='1')
net2.fit(X, y)
取出的误分类点为x3, 更新后w = [0. 0.], b = -1,  wx+b = 0.0x1 + 0.0x2 + -1
取出的误分类点为x1, 更新后w = [3. 3.], b = 0,  wx+b = 3.0x1 + 3.0x2 + 0
取出的误分类点为x3, 更新后w = [2. 2.], b = -1,  wx+b = 2.0x1 + 2.0x2 + -1
取出的误分类点为x3, 更新后w = [1. 1.], b = -2,  wx+b = 1.0x1 + 1.0x2 + -2
取出的误分类点为x3, 更新后w = [0. 0.], b = -3,  wx+b = 0.0x1 + 0.0x2 + -3
取出的误分类点为x1, 更新后w = [3. 3.], b = -2,  wx+b = 3.0x1 + 3.0x2 + -2
取出的误分类点为x3, 更新后w = [2. 2.], b = -3,  wx+b = 2.0x1 + 2.0x2 + -3
取出的误分类点为x3, 更新后w = [1. 1.], b = -4,  wx+b = 1.0x1 + 1.0x2 + -4

在这里插入图片描述

2 感知机的对偶形式算法

2.1 理解对偶算法

在之前讲解的原始形式的学习算法中,如果实例点 ( x i , y i ) (x_i,y_i) (xi,yi)是误分类点,可以用它更新参数,即
w ← w + η x i y i b ← b + η y i w\leftarrow w + \eta x_iy_i \\ b\leftarrow b + \eta y_i\\ ww+ηxiyibb+ηyi
假如,每一个实例点对于参数更新,做了 n i n_i ni次贡献,那么每个实例点作用到初始参数 w 0 、 b 0 w_0、b_0 w0b0上的增量分别为 a i y i x i a_iy_ix_i aiyixi a i y i a_iy_i aiyi,其中 a i = n i η a_i=n_i\eta ai=niη

还是之前的例子:

在这里插入图片描述

  • 在这个过程中,实例 ( x 1 , y 1 ) (x_1,y_1) (x1,y1)作为误分类点出现两次,所以 n 1 = 2 n_1=2 n1=2,即第一个实例点在迭代中贡献了 2 次。

  • ( x 2 , y 2 ) (x_2,y_2) (x2,y2)并没有出现,所以 n 2 = 0 n_2=0 n2=0,即第二个实例点在迭代中没有贡献。

  • ( x 3 , y 3 ) (x_3,y_3) (x3,y3)出现了5次,所以 n 3 = 5 n_3=5 n3=5,即第三个实例点在迭代中贡献了 5 次。

  • 恰好 n 1 + n 3 = 7 n_1 + n_3=7 n1+n3=7,就是实际迭代的次数。综合所有贡献的增量,就得到最终参数了,与原始算法的结果是相同的。

  • 对偶形式,基本思想就是通过实例点的线性组合来更新参数,其权重由贡献的大小决定的

根据以上的例子,很容易得出下面式子:

在这里插入图片描述

2.2 对偶算法

下面是感觉机学习算法对偶形式的具体步骤,可以看到把 w w w换为了 ∑ j = 1 N a i y i x j \sum\limits_{j=1}^N a_iy_ix_j j=1Naiyixj,梯度下降时候也变成了更新 a i a_i ai

在这里插入图片描述

与原始形式相比,对偶形式有什么优势呢? 这需要,仔细分析对偶形式的迭代条件。

在这里插入图片描述

  • 将迭代条件展开,我们发现,如果训练数据集固定,那么有些值是不需要重复计算的,也就是我们红框里的这 N N N个内积。

  • 如果 ( x i , y i ) (x_i, y_i) (xi,yi)是误分类点,只要读取Gram矩阵第 i i i行的值即可。

  • 我们要做的,就是在得到训练数据集之后,把这 N × N N×N N×N个内积计算出来储存到Gram矩阵,之后每次更新参数的时候读取就可以,这能节省许多计算量。

2.3 对偶算法的案例

还是之前的案例,我们使用对偶算法进行求解。

在这里插入图片描述

  • 先设置初始值,不妨还是取零向量,然后计算Gram矩阵,把9个内积的值都储存下来。

  • 接下来就是判断误分类点,可以选取 ( x 1 , y 1 ) (x_1,y_1) (x1,y1)带入迭代条件中,计算得到零,可以用来更新参数,得到一个新的分离超平面。

在这里插入图片描述

  • 用这个新得到的分离超平面,对三个实例点分类,选取错误分类点,继续进行更新。
    在这里插入图片描述

  • 之后,重复步骤,直到没有误分类点,停止迭代。

在这里插入图片描述

2.4 上述过程的代码实现

Statistical_Learning_Methods_Impl: 《统计学习方法》第二版 python代码实现

import numpy as npclass PerceptronDuality(object):def __init__(self, num_features, eta=1):# 初始化参数G、α、w、bself.G = np.zeros([num_features, num_features], dtype=np.float32)self.α = np.zeros(num_features)self.b = 0self.eta = eta# w[0] * x + w[1] * y + b = 0self.w = [0., 0.]def fit(self, data, label):# 1、计算 Gram 矩阵for i in range(0, len(data)):for j in range(0, len(data)):self.G[i][j] = data[i][0] * data[j][0] + data[i][1] * data[j][1]print('Gram矩阵:\n', self.G)separated = False  # 标记是否完全分离while not separated:separated = True# 遍历训练集,每次取出点 (data[i][0], data[i][1])for i in range(0, len(data)):sum = 0for j in range(0, len(data)):# 计算 ∑(α*yj*xj)x的值,相当于原始形式中的 wxsum += self.α[j] * label[j] * self.G[j][i]# 判断是否为误分类点if (sum + self.b) * label[i] <= 0:self.α[i] += self.eta          # 更新 α 的值self.b += self.eta * label[i]  # 更新 b 的值print(f'误分类点为x{i + 1},α = {self.α}, b = {self.b}')separated = False  # 置回标记# 求出 w 的值for i in range(0, len(self.α)):self.w[0] += self.α[i] * label[i] * data[i][0]self.w[1] += self.α[i] * label[i] * data[i][1]return 'PerceptronDuality Model'if __name__ == '__main__':data = np.array([[3, 3, 1],[4, 3, 1],[1, 1, -1]])X, y = data[:, :-1], data[:, -1]# 进行训练num = len(X)net = PerceptronDuality(num_features=num)net.fit(X, y)

可以看到和之前手动计算的一致。

Gram矩阵:[[18. 21.  6.][21. 25.  7.][ 6.  7.  2.]]
误分类点为x1,α = [1. 0. 0.], b = 1
误分类点为x3,α = [1. 0. 1.], b = 0
误分类点为x3,α = [1. 0. 2.], b = -1
误分类点为x3,α = [1. 0. 3.], b = -2
误分类点为x1,α = [2. 0. 3.], b = -1
误分类点为x3,α = [2. 0. 4.], b = -2
误分类点为x3,α = [2. 0. 5.], b = -3

参考书籍:
李航老师《统计学习方法》第二版

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

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

相关文章

Docker Compose基本配置及使用笔记

Docker Compose基本配置及使用笔记 简介 Docker Compose 是一个用于定义和运行多个 Docker 容器应用程序的工具。它使用 YAML 文件来配置应用程序的服务&#xff0c;并通过简单的命令集管理这些服务的生命周期。 1.步骤1 代码如下&#xff1a;docker-compose.yml放在虚拟机roo…

前端项目,个人笔记(一)【Vue-cli - 定制化主题 + 路由设计】

目录 1、项目准备 1.1、项目初始化 1.2、elementPlus按需引入 注&#xff1a;使用cnpm安装elementplus及两个插件&#xff0c;会报错&#xff1a;vueelement-plus报错TypeError: Cannot read properties of null (reading isCE ) &#xff0c;修改&#xff1a; 测试&#…

Swin—Transformer学习笔记

一、网络框架 二、Patch Merging 图像长和宽减半&#xff0c;通道数增加一倍 三、W-MSA 目的&#xff1a;减少计算量 缺点&#xff1a;窗口之间无法进行信息交互 四、SW-MSA 目的&#xff1a;实现不同window之间的信息交互 为了不增加计算量&#xff0c;移动window并增加Ma…

【数据结构】二叉树OJ题(C语言实现)

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ &#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1…

【C#】int+null=null

C#语法&#xff0c;这玩意不报错 intnullnull&#xff0c;有点不合逻辑 (Int32)(bizRepair0rder.CreateTime. Value - regues.Mlodifylime.Value).TotalMinutes (Int32)(bizRepair0rder.CreateTime. Value - reques.llodifylime.Value).TotalMinutes nullstring是引用类型&…

机器学习-04-分类算法-03KNN算法

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中分类算法&#xff0c;本篇为分类算法与knn算法部分。 本门课程的目标 完成一个特定行业的算法应用全过程&#xff1a; 懂业务会选择合适的算法数据处理算法训练算法调优算法融合 算法评估持续调优工程化…

冲动是魔鬼,工作不顺心时不要把坏脾气带给家人

今天与一个跟踪了很久的客户准备签合同了&#xff0c;客户突然反悔&#xff0c;为此与他周旋了一整天&#xff0c;忙碌得一口水都没有喝。回到小区坐在车里抽着烟&#xff0c;久久不愿回家&#xff0c;只想一个人坐着&#xff0c;疲惫、无奈。这个月的奖金似乎又将成为泡影。 …

AI - 决策树模型

&#x1f914;决策树算法 决策树的思想来源可以追溯到古希腊时期&#xff0c;当时的哲学家们就已经开始使用类似于决策树的图形来表示逻辑推理过程。然而&#xff0c;决策树作为一种科学的决策分析工具&#xff0c;其发展主要发生在20世纪。 在20世纪50年代&#xff0c;美国兰…

Machine Vision Technology:Lecture5 Local feature:Corners角点

Machine Vision Technology&#xff1a;Lecture5 Local feature&#xff1a;Corners角点 Motivation&#xff1a;panorama stitching全景图拼接提取良好特征Feature points applications特征点应用Finding Corners找角点Corner Detection&#xff1a;Basic Idea角点检测基本思想…

【数据结构和算法初阶(C语言)】队列实操(概念实现+oj题目栈和队列的双向实现以及循环链表难点题目详解!)

目录 1. 队列的概念及结构 2.队列结构存在的意义应用 3.队列实现的结构选择 4.队列实现 5.队列对数据的处理 5.1队列初始化 5.2队尾入数据 5.3队头出数据 5.4获取队列尾部元素 5.5获取队列头部元素 5.6获取队列中元素个数 5.7检测队列是否为空 5.8销毁队列 6.循环队列补充 7.使…

【AcWing】蓝桥杯集训每日一题Day5|归并排序|离散化|二分|逆序数对|505.火柴排队(C++)

火柴排队 505. 火柴排队 - AcWing题库难度&#xff1a;中等时/空限制&#xff1a;1s / 128MB总通过数&#xff1a;2058总尝试数&#xff1a;4484来源&#xff1a;NOIP2013提高组算法标签贪心离散化树状数组归并排序 题目内容 涵涵有两盒火柴&#xff0c;每盒装有 n 根火柴…

广度优先算法(一篇文章讲透)

目录 引言 一、算法概述 二、算法步骤 1 初始化 2 循环处理 三、算法应用 1 图的最短路径问题 2 网络爬虫 3 社交网络分析 4 游戏路径搜索 事例 四、算法特点与性能 五、性能优化 1 剪枝策略&#xff1a; 2 使用高效的数据结构&#xff1a; 3 并行化处理&#…

qt vs 编程 字符编码 程序从源码到编译到显示过程中存在的字符编码及隐藏的字符编码转换

理解字符编码&#xff0c;请参考&#xff1a;unicode ucs2 utf16 utf8 ansi GBK GB2312 CSDN博客 了解windows字符显示必须了解locale概念 参考&#xff1a;揭密 Windows 上的各种 locale - 知乎 汉字&#xff08;或者说多字节字符&#xff09;的存放需求&#xff0c;是计算…

理解数学概念——同伦和简单连通域

1. 同伦(homotopy) 1.1 homotopy[hɒməʊˈtɒpi] n. (1) <<The Oxford English Dictionary>>第二版&#xff1a; [数学专用术语&#xff0c;这个词由德语homotopie改造而来&#xff0c;(Dehn & Heegaard Analysis Situs in Encykl.d.math.Wiss.(1907) I…

【滤波专题-第8篇】ICA降噪方法——类EMD联合ICA降噪及MATLAB代码实现(以VMD-ICA为例)

今天来介绍一种效果颇为不错的降噪方法。&#xff08;针对高频白噪声&#xff09; 上一篇文章我们讲到了FastICA方法。在现实世界的许多情况下&#xff0c;噪声往往接近高斯分布&#xff0c;而有用的信号&#xff08;如语音、图像特征等&#xff09;往往表现出非高斯的特性。F…

测试环境搭建整套大数据系统(十一:docker部署superset,无密码登录嵌入html,http改为https)

一&#xff1a;安装docker 参考文档 https://blog.csdn.net/weixin_43446246/article/details/136554243 二&#xff1a;安装superset 下载镜像。 拉取镜像&#xff08;docker pull amancevice/superset&#xff09; 查看镜像是否下载完成&#xff08;docker images&#xf…

如何检测无源晶振过驱?晶振过驱怎么办?

无源晶振(Passive Crystal Oscillator)是一种使用晶体元件来生成稳定频率的振荡器&#xff0c;它不像有源振荡器(如时钟芯片)那样需要外部电源。检测无源晶振是否过驱通常需要通过测量其输出波形和频率&#xff0c;与期望的规格进行比较。 如何检测无源晶振过驱&#xff1a; …

Linux——线程池

线程池的概念 线程池也是一种池化技术&#xff0c;可以预先申请一批线程&#xff0c;当我们后续有任务的时候就可以直接用&#xff0c;这本质上是一种空间换时间的策略。 如果有任务来的时候再创建线程&#xff0c;那成本又要提高&#xff0c;又要初始化&#xff0c;又要创建数…

Gatling压力测试Springboot项目

Gatling压力测试Springboot项目 一、指定Java Spring 项目作为测试项二、下载Gatling三、配置测试代码四、打开bin目录下的gatling.bat文件进行测试 一、指定Java Spring 项目作为测试项 这里给出一个简单的示例&#xff1a;代码链接 下载maven依赖以后在8080端口运行这个项目…

Windows10+tensorrt+python部署yolov5

一、安装cuda 打开NVIDIA控制面板 —>帮助—>系统信息—>组件&#xff0c;找到驱动版本新&#xff0c;我这边是11.2&#xff0c; 然后去CUDA Toolkit Archive | NVIDIA Developer下载对应版本的CUDA&#xff0c;根据查看的CUDA型号确定对应的cuda Toolhit版本&#…