当前位置: 首页 > news >正文

机器学习实验----支持向量机(SVM)实现二分类

目录

一、介绍

(1)解释算法

(2)数据集解释

二、算法实现和代码介绍

1.超平面

2.分类判别模型

3.点到超平面的距离

4.margin 间隔

5.拉格朗日乘数法KKT不等式

(1)介绍

(2)对偶问题

(3)惩罚参数

(4)求解

6.核函数解决非线性问题

7.SMO

(1)更新w

(2)更新b

三、代码解释及其运行结果截图

(1)svm(拉格朗日、梯度、核函数)

(2)测试集预测

(3)画出超平面

四、实验中遇到的问题

五、svm的优缺点

优点:

缺点: 

六、实验中还需要改进的地方

七、总代码展现


一、介绍

(1)解释算法

支持向量机(Support Vector Machine, SVM)是一类按监督学习(supervised learning)方式对数据进行二元分类的广义线性分类器(generalized linear classifier),其决策边界是对学习样本求解的最大边距超平面                                                                 ------------百度百科

 本实验采取的数据集依旧是鸢尾花数据集,实现的是二分类,为了使得数据可以在坐标轴上展示出来,实验中取的是鸢尾花数据集的setosa和versicolor类别。

支持向量机SVM的目标是找到一个能够将两类数据点分隔开的超平面,使得两侧距离最近的数据点到超平面的距离最大。这些最靠近超平面的数据点被称为支持向量。

(2)数据集解释

data = pd.read_csv(r"C:\\Users\\李烨\\Desktop\\ljhg.txt", sep=' ')
X_train = data.iloc[:, :2].values
y_train = np.where(data.iloc[:, -1].values == 'setosa', 1, -1)test_data = pd.read_csv("C:\\Users\\李烨\\Desktop\\ljhgtest.txt", sep='\s+')
X_test = test_data[["Sepal.Length", "Sepal.Width"]].values

 采用鸢尾花数据集,为了可以在二维图上显示,所以我截取了部分数据,"Sepal.Length", "Sepal.Width"两列来表示横纵坐标,把setosa判断为正类1,把versicolor判断为负类-1

二、算法实现和代码介绍

1.超平面

两侧距离最近的数据点到超平面的距离最大。超平面被用来划分特征空间,以便实现对数据进行分类或回归。

在多分类实验中,是n元空间中,超平面就是一个n-1维的空间。 我们实现的是二分类,就得到的是一条直线。

给定样本数据集,假设样本特征为X,样本标签为y。其中y 的取值只能有+1和-1。表示样本正类和负类。

公式:w^{T}x+b=0

其中w代表每个特征前的系数,也就是超平面的法向量

2.分类判别模型

公式:f(w)=sign(w^{T}x+b)

当f(w)>0时,判定为正类,否则判别为负类。

3.点到超平面的距离

得到样本点到超平面距离的公式:\text{dis} = \frac{|w^T x + b|}{||w||}

在二维空间里面,也就是两个特征中,我们可以把超平面也就是直线的公式写成ax+by+c=0

将一个点代入,这个点可能在直线的上方,直线上,和直线的下方。那么对于分类为正类1和负类-1,我们可以得到新的公式:

\text{dis} = \frac{w^T x + b}{||w||}y_{i}

其中||w||=\sqrt{w_{1}^{2}+...+w_{i}^{2}+...w_{n}^{2}}

4.margin 间隔

从网上找了张图便于理解

支持向量:在支持向量机中起关键作用的训练数据点。在SVM中,超平面由这些支持向量确定,它们是离分隔超平面最近的那些点。

图中l1和l3直线的确定就是按照支持向量来确定的,查找正类和负类中距离超平面最近的点,找到超平面使得这个间隔最大,以此来确定超平面。

w,b都是未知参数,所以我们就将l1和l3等比例缩放

最后得到l1:w^{T}x+b=-1

              l3:l1:w^{T}x+b=1

那么这两条直线到超平面l1:w^{T}x+b=0的距离就可以表示为d=\frac{1}{||w||}

那我们就可以得到预测为正类的公式w^{T}x_{i}+b>=1(y=1)

                                        负类的公式w^{T}x_{i}+b<=-1(y=-1)

合并后得到y_{i}(w^{T}x_{i}+b)>=1

我们确定超平面是为了分隔两个类别,所以需要找到超平面到支持向量的最大距离,也就是margin间隔。也就是求两条直线到超平面距离的最大值d,也就是求||w||的最大值,为了方便计算,也就是求的\frac{1}{2}||w||^{2}的最大值。

5.拉格朗日乘数法KKT不等式

(1)介绍

拉格朗日乘数法的主要是将有等式约束条件优化问题转换为无约束条件,求解带约束条件下的极值。因为拉格朗日是求解等式约束条件,而要求解带不等式约束条件下的求解,所以引入KKT不等式约束。

  对于 求解min f(x) \, \, \, \, \, \, \,\, \, s.t\, \, \, \, \, \, \, \, h(x)<=0

我们可以考虑加入alpha使得h(x)+\alpha ^{2}=0,这样就可以了利用拉格朗日乘数法得到

拉格朗日得到min \, L(x,\lambda ,\alpha)=f(x)+\lambda (h(x)+\alpha ^{2})\, \, \, \lambda >=0,求解该式子对应的极值。

对该式子求导得到

\frac{\partial L}{\partial x}=\frac{\partial f(x)}{\partial x}+\lambda \frac{\partial h(x)}{\partial x}=0\\\frac{\partial L}{\partial \lambda }=h(x)+\alpha ^{2}=0\\\frac{\partial L}{\partial \alpha }=2\lambda \alpha \\\lambda >=0

为了求解f(x)在s.t条件下的极值,我们先求得不在约束条件下的极值p,然后在约束条件下查找合适的x使得他尽可能的靠近极值点,也就是说alpha就没影响等式。那么就把问题转化为

min_{x}max_{\lambda } L(x,\lambda )\;\lambda >=0

(2)对偶问题

对于求解min_{x}max_{\lambda } L(x,\lambda )\;\lambda >=0等效于 求解max_{\lambda}min_{x } L(x,\lambda )\;\lambda >=0

当然这样交换是假设成立。情况分为强对偶和弱对偶

如果是弱对偶,因为是先求解最小值的x,就会使得求最大值是在小中选择较大的,那么max_{\lambda}min_{x } L(x,\lambda )<=min_{x}max_{\lambda } L(x,\lambda )。而如果等价的话,那么就是该交换成立。特别的是,在本实验中下凸满足Slater条件,所以对于所有下凸函数都是满足强对偶性。

(3)惩罚参数

惩罚参数C控制了分类器对错误分类样本的容忍程度。较大的C值会导致分类器试图尽量减少误分类样本的数量,这可能会导致模型在训练数据上表现得更好,但也可能导致过拟合的风险增加;而较小的C值则对误分类样本的惩罚较小,允许一些样本被错分,从而使得决策边界更加平滑,减少了过拟合的风险。

我们可以预料到,数据中肯定存在一些点会影响到超平面的选择从而造成超平面的分类效果不理想,这时候就引入惩罚参数,当该点的误差超过一定界限的对其惩罚较大,就减少该样本点造成的误差。

(4)求解

最后求解极值就是用到和之前逻辑回归算法一样的梯度上升和梯度下降算法,这里就不多做介绍。 

6.核函数解决非线性问题

用升维的方法来解决线性不可分的问题。

假设原始特征为x1,x2,x3,那么将这三个特征两两组合的得到:

x1^{2},x1x2,x1x3,x2^{2},x2x3,x3^{2}在训练模型的适合将这些参与到训练模型中。

对于两个数据m和n,将m和n内积,然后平方得到

公式:K(m\cdot n)=\phi m\cdot \phi n=(m\cdot n)^{2}

这个公式是多项式核函数,当时他的完整公式是K(m\cdot n)=\phi m\cdot \phi n=(m\cdot n+c)^{r}

核函数有线性核函数、多项式核函数、高斯核函数等。

def polynomial_kernel(X, Y, degree=2):return (np.dot(X, Y.T) ) ** degree

7.SMO

在SMO算法中,需要解决的优化问题是一个凸二次规划问题,其目标是最小化关于拉格朗日乘子alpha的二次函数,同时满足一些约束条件,例如 KKT 条件。通过构建拉格朗日函数,然后应用SMO算法来迭代优化,最终得到最优的 alpha 和 b

(1)更新w

选择两个样本i和j来进行更新,更新步长的计算与核函数的值以及拉格朗日乘子都有关系。

公式:\eta = 2 \cdot K_{ij} - K_{ii} - K_{jj}

这个步长有正有负。当为正数的时候意味着在更新拉格朗日乘子时,朝着梯度方向移动一个较小的步长。为负数,则可能表示算法中的错误,需要检查和调整。

 

(2)更新b

 b1 = b - E_i - y[idx] \cdot (w[idx] - \alpha _{iold}) \cdot K(x_i, x_i) - y[j] \cdot (w[j] - \alpha _{jold}) \cdot K(x_i, x_j)

b2 = b - E_j - y[idx] \cdot (w[idx] - \alpha_{iold}) \cdot K(x_i, x_j) - y[j] \cdot (w[j] - \alpha _{jold}) \cdot K(x_j, x_j) 

0 < w_i < C时 b=b1;

0 < w_j < C时b=b2;

否则b=\frac{b1+b2}{2}

当然a和b的更新,这边学习的仅仅只是其中的一种。

三、代码解释及其运行结果截图

(1)svm(拉格朗日、梯度、核函数)

def svm_fit(X, y, C, kernel, degree=2, alpha=0.001, num=1000):n_samples, n_features = X.shapew = np.zeros(n_samples)b = 0kernel_matrix = kernel(X, X, degree)for _ in range(num):for idx, x_i in enumerate(X):E_i = np.sum(w * y * kernel_matrix[idx]) + b - y[idx]if ((y[idx] * E_i < -alpha and w[idx] < C) or (y[idx] * E_i > alpha and w[idx] > 0)):j = np.random.choice(np.delete(np.arange(n_samples), idx))E_j = np.sum(w * y * kernel_matrix[j]) + b - y[j]w_i_old, w_j_old = w[idx], w[j]if (y[idx] != y[j]):L = max(0, w[j] - w[idx])H = min(C, C + w[j] - w[idx])else:L = max(0, w[idx] + w[j] - C)H = min(C, w[idx] + w[j])if L == H:continueeta = 2 * kernel_matrix[idx, j] - kernel_matrix[idx, idx] - kernel_matrix[j, j]if eta >= 0:continuew[j] = w[j] - (y[j] * (E_i - E_j)) / etaw[j] = max(L, min(H, w[j]))if abs(w[j] - w_j_old) < 1e-5:continuew[idx] = w[idx] + y[idx] * y[j] * (w_j_old - w[j])b1 = b - E_i - y[idx] * (w[idx] - w_i_old) * kernel_matrix[idx, idx] - y[j] * (w[j] - w_j_old) * kernel_matrix[idx, j]b2 = b - E_j - y[idx] * (w[idx] - w_i_old) * kernel_matrix[idx, j] - y[j] * (w[j] - w_j_old) * kernel_matrix[j, j]if 0 < w[idx] < C:b = b1elif 0 < w[j] < C:b = b2else:b = (b1 + b2) / 2return w, b
  1.  C是惩罚参数, kernel是代表的核函数, degree是核函数的阶数, alpha是梯度的步长, num是迭代次数。用E_i来表示的是第i个样本的预测误差,也就是样本的核函数对应的数据到超平面的距离减去该样本的分类之和。
  2. if ((y[idx] * E_i < -alpha and w[idx] < C) or (y[idx] * E_i > alpha and w[idx] > 0))是来判断这个是否要更新参数,如果误差太大,那么就说明w[idx]的值不合适,就需要更新他。
  3. 先从数据中再次随机选取一个数据,判断y[idx] != y[j],对w[j]进行约束在一定范围内,使得在满足约束条件的同时,能够使得目标函数在更新后有下降较快,可以更节省时间。
  4. 如果约束到一个点上面,就无法继续优化了,如果没有,二阶导数判断一下更新的方向。if eta >= 0说明图像是下凸的,跳过再次更新,为负数就需要进行整改。
  5. 对w进行更新,但是w应该在一定范围内。如果w[j]的改变量很小,就认为他对w[idx]的更新没有贡献,跳过。
  6. 根据smo更新b的方式对b进行更新。

(2)测试集预测

def predict(w, b, X_train, y_train, X_test, kernel, degree=2):predictions = []for x in X_test:prediction = bfor i, x_i in enumerate(X_train):prediction += w[i] * y_train[i] * kernel(x_i, x, degree)predictions.append(np.sign(prediction))return predictions

 对于测试集中的数据,将他们与训练集中的数据核函数,再根据得到的值为正数和负数分类到正类和负类。

运行结果:

可以看到对于二分类的结果还是较为准确的。

(3)画出超平面

def plot_decision_boundary(X, y, w, b, kernel, degree=2):x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, 0.1), np.arange(x2_min, x2_max, 0.1))Z = predict(w, b, X, y, np.c_[xx1.ravel(), xx2.ravel()], kernel, degree)Z = np.array(Z).reshape(xx1.shape)plt.contourf(xx1, xx2, Z, alpha=0.4)plt.scatter(X[:, 0], X[:, 1], c=y, marker='o', edgecolors='k')

因为超平面中用到了核函数,所以超平面的公式就和样本数量有关,得到的公式就不再是可以像逻辑回归一样直接表示出来,需要最坐标轴上面的点用核函数表示 代入到公式中得到预测值。

这个代码是参考了网上的代码,以坐标轴的形式,把坐标轴上的点用核函数的公式拿去预测,那么他就得到了整张坐标轴上的分类。超平面就是两个分类交叉的地方。

运行结果:

 

四、实验中遇到的问题

  1. 实验中遇到的最主要的问题就是对w和b的更新上,因为和逻辑回归一点像,就没有真正理解算法,对w和b的选取和更新是都花了较大的时间来理解SMO的算法,SMO算法有许多给定的公式来更新w和b,核函数和拉格朗日乘子法KKT不等式等都是利用公式求解,公式较多较为复杂,重点就在对这些公式的掌握和理解上面。
  2. 实验中的另一个问题就是对于惩罚参数的选取上,由于刚开始看到的并没有添加惩罚参数,所以导致超平面受到的影响较大,受到个别点的影响,导致拟合效果非常不好,而且由于是利用梯度求解,所以就会导致超平面因为拟合效果不好。如图。超平面并不能很好的划分。

3.超平面的画法上面,最开始是想直接将点表示出来,但是发现用核函数得到的超平面公式与样本点的数量有关系,在画超平面的时候仍然需要对他进行核函数求解,所以在预测的时候加上核函数就可以了。

五、svm的优缺点

优点:

逻辑回归主要是处理线性问题,与之相比,支持向量机可以处理许多非线性的问题,SVM 找到最大间隔超平面,这意味着它试图最大化类别之间的间隔,拟合效果会更好。在高维空间中svm支持向量机的适应效果回归更好。

缺点: 

支持向量机svm的优化问题通常是凸优化问题,它的计算复杂度随着样本数量和特征维度的增加而增加。在处理大规模数据和高维数据时,训练时间和内存时间复杂度很大。

六、实验中还需要改进的地方

  1. 与逻辑回归一样,使用的是普通梯度,而随机梯度上升在每次迭代中只需要计算一个样本数据的梯度,因此通常比梯度上升更快。我们可以利用随机梯度来减小时间复杂度。
  2. 由于对SMO算法的不熟悉,所以我的实验中用到的是最简单的SMO,复杂度高,程序预测效果没那么好,使用更加完整成熟的SMO算法可以有效改进拟合效果。

七、总代码展现

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def polynomial_kernel(X, Y, degree=2):return (np.dot(X, Y.T) ) ** degree
def svm_fit(X, y, C, kernel, degree=2, alpha=0.001, num=1000):n_samples, n_features = X.shapew = np.zeros(n_samples)b = 0kernel_matrix = kernel(X, X, degree)for _ in range(num):for idx, x_i in enumerate(X):E_i = np.sum(w * y * kernel_matrix[idx]) + b - y[idx]if ((y[idx] * E_i < -alpha and w[idx] < C) or (y[idx] * E_i > alpha and w[idx] > 0)):j = np.random.choice(np.delete(np.arange(n_samples), idx))E_j = np.sum(w * y * kernel_matrix[j]) + b - y[j]w_i_old, w_j_old = w[idx], w[j]if (y[idx] != y[j]):L = max(0, w[j] - w[idx])H = min(C, C + w[j] - w[idx])else:L = max(0, w[idx] + w[j] - C)H = min(C, w[idx] + w[j])if L == H:continueeta = 2 * kernel_matrix[idx, j] - kernel_matrix[idx, idx] - kernel_matrix[j, j]if eta >= 0:continuew[j] = w[j] - (y[j] * (E_i - E_j)) / etaw[j] = max(L, min(H, w[j]))if abs(w[j] - w_j_old) < 1e-5:continuew[idx] = w[idx] + y[idx] * y[j] * (w_j_old - w[j])b1 = b - E_i - y[idx] * (w[idx] - w_i_old) * kernel_matrix[idx, idx] - y[j] * (w[j] - w_j_old) * kernel_matrix[idx, j]b2 = b - E_j - y[idx] * (w[idx] - w_i_old) * kernel_matrix[idx, j] - y[j] * (w[j] - w_j_old) * kernel_matrix[j, j]if 0 < w[idx] < C:b = b1elif 0 < w[j] < C:b = b2else:b = (b1 + b2) / 2return w, bdef predict(w, b, X_train, y_train, X_test, kernel, degree=2):predictions = []for x in X_test:prediction = bfor i, x_i in enumerate(X_train):prediction += w[i] * y_train[i] * kernel(x_i, x, degree)predictions.append(np.sign(prediction))return predictionsdef plot_decision_boundary(X, y, w, b, kernel, degree=2):x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, 0.1), np.arange(x2_min, x2_max, 0.1))Z = predict(w, b, X, y, np.c_[xx1.ravel(), xx2.ravel()], kernel, degree)Z = np.array(Z).reshape(xx1.shape)plt.contourf(xx1, xx2, Z, alpha=0.4)plt.scatter(X[:, 0], X[:, 1], c=y, marker='o', edgecolors='k')data = pd.read_csv(r"C:\\Users\\李烨\\Desktop\\ljhg.txt", sep=' ')
X_train = data.iloc[:, :2].values
y_train = np.where(data.iloc[:, -1].values == 'setosa', 1, -1)test_data = pd.read_csv("C:\\Users\\李烨\\Desktop\\ljhgtest.txt", sep='\s+')
X_test = test_data[["Sepal.Length", "Sepal.Width"]].values
y_test = test_data[["Species"]].values;C = 1.0
degree = 2
tol = 0.001
max_iter = 1000w, b = svm_fit(X_train, y_train, C, polynomial_kernel, degree, tol, max_iter)predictions = predict(w, b, X_train, y_train, X_test, polynomial_kernel, degree)cnt=0.0
for i, prediction in enumerate(predictions):if prediction == 1:ans='setosa'else :ans='versicolor'print(f"第{i}个数据{X_test[i]}预测结果为{ans},实际结果为{y_test[i]}")if ans==y_test[i]:cnt+=1print(f"准确率为{cnt/len(predictions)}")plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(10, 6))
plot_decision_boundary(X_train, y_train, w, b, polynomial_kernel, degree)
plt.title('SVM支持向量机')
plt.xlabel('Sepal Length')
plt.ylabel('Sepal Width')
plt.show()

相关文章:

机器学习实验----支持向量机(SVM)实现二分类

目录 一、介绍 (1)解释算法 (2)数据集解释 二、算法实现和代码介绍 1.超平面 2.分类判别模型 3.点到超平面的距离 4.margin 间隔 5.拉格朗日乘数法KKT不等式 (1)介绍 (2)对偶问题 (3)惩罚参数 (4)求解 6.核函数解决非线性问题 7.SMO (1)更新w (2)更新b 三、代…...

STM32自己从零开始实操05:接口电路原理图

一、TTL 转 USB 驱动电路设计 1.1指路 延续使用芯片 CH340E 。 实物图 实物图 原理图与封装图 1.2数据手册重要信息提炼 1.2.1概述 CH340 是一个 USB 总线的转接芯片&#xff0c;实现 USB 与串口之间的相互转化。 1.2.2特点 支持常用的 MODEM 联络信号 RTS&#xff08;请…...

git子模块

1 子模块管理的关键文件和配置 在 Git 中使用子模块时&#xff0c;Git 会利用几个特殊的文件和配置来管理子模块。以下是涉及子模块管理的关键文件和配置&#xff1a; 1.1 .gitmodules 这是一个文本文件&#xff0c;位于 Git 仓库的根目录下。它记录了子模块的信息&#xff…...

stm32编写Modbus步骤

1. modbus协议简介&#xff1a; modbus协议基于rs485总线&#xff0c;采取一主多从的形式&#xff0c;主设备轮询各从设备信息&#xff0c;从设备不主动上报。 日常使用都是RTU模式&#xff0c;协议帧格式如下所示&#xff1a; 地址 功能码 寄存器地址 读取寄存器…...

基于 Transformer 的大语言模型

语言建模作为语言模型&#xff08;LMs&#xff09;的基本功能&#xff0c;涉及对单词序列的建模以及预测后续单词的分布。 近年来&#xff0c;研究人员发现&#xff0c;扩大语言模型的规模不仅增强了它们的语言建模能力&#xff0c;而且还产生了处理传统NLP任务之外更复杂任务…...

证照之星是一款很受欢迎的证件照制作软件

证照之星是一款很受欢迎的证件照制作软件&#xff0c;证照之星可以为用户提供“照片旋转、裁切、调色、背景处理”等功能&#xff0c;满足用户对证件照制作的基本需求。本站证照之星下载专题为大家提供了证照之星电脑版、安卓版、个人免费版等多个版本客户端资源&#xff0c;此…...

不定时更新 解决无法访问GitHub github.com 打不开 dns访问加速

1 修改hosts Windows 10为例,‪文件C:\Windows\System32\drivers\etc\hosts 管理员打开记事本来修改 文件-打开-“C:\Windows\System32\drivers\etc\hosts” 20.205.243.168 api.github.com 185.199.108.154 github.githubassets.com 185.199.108.133 raw.githubusercontent.…...

单向环形链表的创建与判断链表是否有环

单向环形链表的创建与单向链表的不同在于&#xff0c;最后一个节点的next需要指向头结点&#xff1b; 判断链表是否带环&#xff0c;只需要使用两个指针&#xff0c;一个步长为1&#xff0c;一个步长为2&#xff0c;环状链表这两个指针总会相遇。 如下示例代码&#xff1a; l…...

JVM堆栈的区别、分配内存与并发安全问题、对象定位

一、堆和栈的区别 堆&#xff08;Heap&#xff09;和栈&#xff08;Stack&#xff09;是两种基本的数据结构&#xff0c;它们在内存管理、程序执行流程控制等方面扮演着重要角色。在编程语言尤其是Java这样的高级语言环境中&#xff0c;堆和栈的概念被用来描述程序运行时的内存…...

Python教程:机器学习 - 百分位数(4)

什么是百分位数&#xff1f; 统计学中使用百分位数&#xff08;Percentiles&#xff09;为您提供一个数字&#xff0c;该数字描述了给定百分比值小于的值。 例如&#xff1a;假设我们有一个数组&#xff0c;包含住在一条街上的人的年龄。 ages [5,31,43,48,50,41,7,11,15,3…...

数据结构习题(快期末了)

一个数据结构是由一个逻辑结构和这个逻辑结构上的一个基本运算集构成的整体。 从逻辑关系上讲&#xff0c;数据结构主要分为线性结构和非线性结构两类。 数据的存储结构是数据的逻辑结构的存储映像。 数据的物理结构是指数据在计算机内实际的存储形式。 算法是对解题方法和…...

Http协议:Http缓存

文章目录 Cookie和Session缓存有效性检查整体流程总结Cookie和Session Cookie 客户端的缓存 Session 服务端的缓存,存储服务器与客户端一次会话的过程中的数据/资源 两者区别 是服务端与客户端的不同需求造成的 有效期 Cookie的有效期很长,Session的较短 原因:服务…...

idea插件开发之hello idea plugin

写在前面 最近一直想研究下自定义idea插件的内容&#xff0c;这样如果是想要什么插件&#xff0c;但又一时找不到合适的&#xff0c;就可以自己来搞啦&#xff01;这不终于有时间来研究下&#xff0c;但过程可谓是一波三折&#xff0c;再一次切身体验了下万事开头难。那么&…...

Sm4【国密4加密解密】

当我们开发金融、国企、政府信息系统时&#xff0c;不仅要符合网络安全的等保二级、等保三级&#xff0c;还要求符合国密的安全要求&#xff0c;等保测评已经实行很久了&#xff0c;而国密测评近两年才刚开始。那什么是密码/国密&#xff1f;什么是密评&#xff1f;本文就关于密…...

git如果将多次提交压缩成一次

将N个提交压缩到单个提交中有两种方式&#xff1a; git reset git reset的本意是版本回退&#xff0c;回退时可以选择保留commit提交。我们基于git reset的作用&#xff0c;结合新建分支&#xff0c;可以实现多次commit提交的合并。这个不需要vim编辑&#xff0c;很少有冲突。…...

android用Retrofit进行网络请求和解析

Retrofit 的原理 Retrofit的核心原理包括动态代理与Service Method的构建、注解解析与请求配置、网络请求执行与响应处理等。它是一个类型安全的HTTP客户端&#xff0c;用于Android和Java平台&#xff0c;通过将HTTP API转化为Java接口的方式&#xff0c;简化了网络请求的编写…...

list容器的基本使用

目录 前言一&#xff0c;list的介绍二&#xff0c;list的基本使用2.1 list的构造2.2 list迭代器的使用2.3 list的头插&#xff0c;头删&#xff0c;尾插和尾删2.4 list的插入和删除2.5 list 的 resize/swap/clear 前言 list中的接口比较多&#xff0c;与string和vector类似&am…...

34万汉语词语成语反义词ACCESS\EXCEL数据库

反义词就是两个意思相反的词&#xff0c;包括&#xff1a;绝对反义词和相对反义词。分为成对的意义相反、互相对立的词。如&#xff1a;真——假&#xff0c;动——静&#xff0c;拥护——反对。这类反义词所表达的概念意义互相排斥。或成对的经常处于并举、对待位置的词。如&a…...

yum方式更新Jenkins

目的 使用yum方式更新Jenkins。 步骤 查看最新可用版本 $ yum list jenkins Last metadata expiration check: 0:03:44 ago on Fri Jun 14 06:10:01 2024. Installed Packages jenkins.noarch 2.452.1-1.1 jenkins Available Pa…...

欢乐钓鱼大师保姆级教程,云手机辅助攻略解析!

在这份攻略中&#xff0c;我们将为大家详细介绍如何在《欢乐钓鱼大师》中快速提升钓鱼技能和游戏进展&#xff0c;避免常见的新手误区和不必要的资源浪费。无论是钓鱼点的选择、装备的合理使用还是技能的优化&#xff0c;我们都会一一为您详细解析&#xff0c;帮助您成为一名优…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...