支持向量机——pytorch与paddle实现支持向量机

支持向量机——pytorch与paddle实现支持向量机

本文将深入探讨支持向量机的理论基础,并通过PyTorch和PaddlePaddle两个深度学习框架来展示如何实现支持向量机模型。我们将首先介绍支持向量机、优化的基本概念,这些数学工具是理解和实现支持向量机的基础。通过PyTorch和PaddlePaddle的代码示例,我们将展示如何设计、训练和评估一个支持向量机模型,从而让读者能够直观地理解并掌握这两种框架在机器学习问题中的应用。

本文部分为torch框架以及部分理论分析,paddle框架对应代码可见支持向量机paddle
感兴趣的uu可以看看本专栏的往期内容哦~:
深度强化学习开端——DQN算法求解车杆游戏
强化学习的适应性改进——策略梯度算法求解山地车游戏
线性回归——pytorch与paddle实现线性回归的详细过程
接下来我们进入正题!

import torch
print("pytorch version:",torch.__version__)
pytorch version: 2.2.2+cu121

支持向量机(SVM)理论分析

支持向量机(Support Vector Machine, SVM)是一种广泛使用的分类器,特别适合于高维数据分类问题。SVM 的主要思想是寻找一个最优超平面,以最大化两个类别之间的边界(即“间隔”)。

基本概念

给定训练数据集 { ( x i , y i ) } i = 1 N \{(x_i, y_i)\}_{i=1}^{N} {(xi,yi)}i=1N,其中 x i ∈ R n x_i \in \mathbb{R}^n xiRn y i ∈ { − 1 , + 1 } y_i \in \{-1, +1\} yi{1,+1}。SVM 旨在找到一个超平面 w ⋅ x + b = 0 w \cdot x + b = 0 wx+b=0,使得该超平面能最好地将两类数据分开。

对于线性可分的数据集,最优超平面可以通过解决以下优化问题来找到:

min ⁡ w , b 1 2 ∥ w ∥ 2 s.t. y i ( w ⋅ x i + b ) ≥ 1 , i = 1 , 2 , … , N \begin{align*} &\min_{w, b} \frac{1}{2} \|w\|^2 \\ &\text{s.t.} \quad y_i(w \cdot x_i + b) \geq 1, \quad i = 1, 2, \ldots, N \end{align*} w,bmin21w2s.t.yi(wxi+b)1,i=1,2,,N
这里, ∥ w ∥ \|w\| w 是向量 w w w 的欧几里得范数,代表超平面的法向量; b b b 是偏置项。约束条件确保了每个数据点都被正确分类,并且距离超平面至少有一定的“间隔”。

训练优化方法

解决上述优化问题通常使用拉格朗日乘子法和对偶理论。引入拉格朗日乘子 α i ≥ 0 \alpha_i \geq 0 αi0,我们可以得到拉格朗日函数:

L ( w , b , α ) = 1 2 ∥ w ∥ 2 − ∑ i = 1 N α i [ y i ( w ⋅ x i + b ) − 1 ] L(w, b, \alpha) = \frac{1}{2} \|w\|^2 - \sum_{i=1}^{N} \alpha_i [y_i(w \cdot x_i + b) - 1] L(w,b,α)=21w2i=1Nαi[yi(wxi+b)1]
L ( w , b , α ) L(w, b, \alpha) L(w,b,α) 关于 w w w b b b 求偏导,并令其等于 0,我们可以将对 w w w b b b 的优化问题转化为对 α \alpha α 的优化问题:

max ⁡ α ∑ i = 1 N α i − 1 2 ∑ i = 1 N ∑ j = 1 N α i α j y i y j x i ⋅ x j s.t. α i ≥ 0 , ∑ i = 1 N α i y i = 0 \begin{align*} &\max_{\alpha} \sum_{i=1}^{N} \alpha_i - \frac{1}{2} \sum_{i=1}^{N} \sum_{j=1}^{N} \alpha_i \alpha_j y_i y_j x_i \cdot x_j \\ &\text{s.t.} \quad \alpha_i \geq 0, \quad \sum_{i=1}^{N} \alpha_i y_i = 0 \end{align*} αmaxi=1Nαi21i=1Nj=1Nαiαjyiyjxixjs.t.αi0,i=1Nαiyi=0
这是一个二次规划问题,可以使用标准的优化算法(如 SMO,Sequential Minimal Optimization)来解决。

# 接下来我们将使用PyTorch实现线性支持向量机过程
# 我们首先生成一些数据用于分类问题
def synthetic_data_classfier(w, b, num_examples):"""生成y=Xw+b+噪声"""X = torch.normal(-1, 1, (num_examples, len(w)))y = torch.matmul(X, w) + by += torch.normal(-0.00001, 0.00001, y.shape)# 将大于0的元素设置为1  y[y > 0] = 1.  # 将小于0的元素设置为-1  y[y < 0] = -1.return X, y.reshape((-1, 1))true_w = torch.tensor([-0.1, -0.2, -0.3, -0.4, -0.5, -1.0, 1, 0.5, 0.4, 0.3, 0.2, 0.1])  # 参数这样设置是为了让数据期望变为0
true_b = 0
features, labels = synthetic_data_classfier(true_w, true_b, 10000)
# 将数据放置在迭代器里边
from sklearn.model_selection import train_test_split  
from torch.utils.data import Dataset, DataLoader  class CustomDataset(Dataset):  def __init__(self, features, labels):  self.features = features  self.labels = labels  def __len__(self):  return len(self.labels)  def __getitem__(self, idx):  return self.features[idx], self.labels[idx]  def create_data_loaders(features, labels, batch_size=32, test_size=0.2, random_state=42):  # 划分数据集  X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=test_size, random_state=random_state)  # 创建Dataset对象  train_dataset = CustomDataset(X_train, y_train)  test_dataset = CustomDataset(X_test, y_test)  # 创建DataLoader对象  train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)  test_loader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)  return train_loader, test_loader  train_loader, test_loader = create_data_loaders(features, labels, batch_size=64)
# 让我们来设计一个线性支持向量模型吧
class LinearSVM(torch.nn.Module):def __init__(self, input_dim):  super(LinearSVM, self).__init__()  self.w = torch.nn.Parameter(torch.randn(input_dim))  # randn为服从标准正态分布的随机数,此处我们生成一个随机向量作为参数wself.b = torch.nn.Parameter(torch.randn(1))  # 偏置项self.Loss = None  # 损失函数self.optimizer = None  # 优化器def forward(self, x):return torch.matmul(x, self.w) + self.b  # 前向传播获得输出def refresh_params(self, x, y):# 利用x,y数据更新参数w,b out = self.forward(x)if self.Loss is None:self.Loss = torch.nn.MSELoss()L = self.Loss(out.reshape(-1, 1), y)# 利用梯度下降法更新参数w,bif self.optimizer is None:self.optimezer = torch.optim.SGD([self.w, self.b], lr=0.001)  # 优化器self.optimezer.zero_grad()  # 梯度清零L.backward()  # 反向传播self.optimezer.step()  # 更新参数
# 接下来让我们进行训练和测试过程吧!
model = LinearSVM(input_dim=features.shape[1])  # 加载模型
for epoch in range(100):for features_train, labels_train in train_loader:model.refresh_params(features_train, labels_train)# 测试数据精度if epoch % 10 == 0 or epoch == 99:with torch.no_grad():for features_test, labels_test in test_loader:predictions = model.forward(features_test)predictions = torch.sign(predictions).reshape(labels_test.shape)correct = (predictions == labels_test).float()accuracy = correct.sum() / len(correct)print("Epoch: {}, Accuracy: {}".format(epoch, accuracy))break
Epoch: 0, Accuracy: 0.453125
Epoch: 10, Accuracy: 0.9375
Epoch: 20, Accuracy: 0.984375
Epoch: 30, Accuracy: 0.984375
Epoch: 40, Accuracy: 0.984375
Epoch: 50, Accuracy: 0.984375
Epoch: 60, Accuracy: 0.984375
Epoch: 70, Accuracy: 0.984375
Epoch: 80, Accuracy: 0.984375
Epoch: 90, Accuracy: 0.984375
Epoch: 99, Accuracy: 0.984375

由以上代码我们可以发现,当数据线性可分时,利用线性回归的策略都可以得到一个较好的精度。接下来我们参考机器学习算法实践-SVM中的SMO算法对SMO算法的详细介绍,设计一个标准的SVM分类器,并利用SMO算法进行优化。

def clip(a, L, H):# 对alpha进行修剪if a > H:return Helif a < L:return Lelse:return aclass SVM(torch.nn.Module):  def __init__(self, input_dim):  super(SVM, self).__init__()  self.w = torch.randn(input_dim)self.b = torch.randn(1)self.alpha = None  # 这个将在SMO中作为拉格朗日乘子的缓存  self.C = 1.0  # 正则化参数,可以根据需要调整  self.eps = 1e-3  # 用于判断数值解的容差  self.kernel_function = self.linear_kernel  # 核函数,默认为线性核  def forward(self, x):  # 前向传播return torch.matmul(x, self.w) + self.b def linear_kernel(self, x1, x2):# 线性核函数  if x1.shape[0] != x2.shape[0]:return torch.matmul(x1, x2)return torch.dot(x1, x2)  def f(self, x, data_x, data_y):# 计算目标函数return torch.sum(self.alpha * data_y * self.kernel_function(data_x, x)) + self.bdef SMO(self, x, y, i, j):# SMO算法,其中输入的i,j为待优化的alpha下标# 获得没有修建的原始解# 旧的alpha值alpha_i_old = self.alpha[i].clone()alpha_j_old = self.alpha[j].clone()# 计算两个alpha下标对应的样本点x_i = x[i]x_j = x[j]# 计算两个alpha下标对应的样本点对应的标签y_i = y[i]y_j = y[j]# 计算SVM预测值与真实值的误差E_i = self.f(x_i, x, y) - y_iE_j = self.f(x_j, x, y) - y_j# 计算x_i与x_j的核函数值k_ii, k_jj, k_ij = self.kernel_function(x_i, x_i), self.kernel_function(x_j, x_j), self.kernel_function(x_i, x_j)eta = k_ii + k_jj - 2*k_ijif eta <= 0:print('WARNING  eta <= 0')returnalpha_j_new_unrestricted = alpha_j_old + (y_j * (E_i - E_j)) / eta# 对alpha进行修剪if y_i != y_j:L = max(0, alpha_j_old - alpha_i_old)H = min(self.C, self.C + alpha_j_old - alpha_i_old)else:L = max(0, alpha_i_old + alpha_j_old - self.C)H = min(self.C, alpha_j_old + alpha_i_old)alpha_j_new = clip(alpha_j_new_unrestricted, L, H)alpha_i_new = alpha_i_old + y_i*y_j*(alpha_j_old - alpha_j_new)if abs(alpha_j_new - alpha_j_old) < 0.00001:returnself.alpha[i], self.alpha[j] = alpha_i_new, alpha_j_new# 更新阈值bb_i = -E_i - y_i*k_ii*(alpha_i_new - alpha_i_old) - y_j*k_ij*(alpha_j_new - alpha_j_old) + self.bb_j = -E_j - y_i*k_ij*(alpha_i_new - alpha_i_old) - y_j*k_jj*(alpha_j_new - alpha_j_old) + self.bif 0 < alpha_i_new < self.C:self.b = b_ielif 0 < alpha_j_new < self.C:self.b = b_jelse:self.b = (b_i + b_j)/2def refresh_params(self, x, y):# 利用SMO算法更新参数w,b,alphaif self.alpha is None:self.alpha = torch.zeros(x.shape[0]).reshape(-1, 1)  # 拉格朗日乘子# 遍历样本,随机选择第二个样本进行优化  for i in range(x.shape[0]):  # 选择第二个alpha  j = torch.randint(0, x.shape[0], (1,)).item()  while j == i:  # 确保i和j不是同一个样本  j = torch.randint(0, x.shape[0], (1,)).item()  # 调用SMO来尝试更新alpha_i和alpha_j  self.SMO(x, y, i, j)  # 更新权重向量 w  self.w = torch.zeros(x.shape[1])  # 初始化 w 为零向量  for i in range(x.shape[0]):  self.w += self.alpha[i] * y[i] * x[i]  # 根据上述公式累加更新 w
# 接下来让我们选取一部分数据来看看SMO算法吧
model = SVM(input_dim=features.shape[1])  # 加载模型
# 选取数据集中前2000个数据进行训练
model.refresh_params(features[:3000,:], labels[:3000,:])# 测试数据精度
with torch.no_grad():for features_test, labels_test in test_loader:predictions = model.forward(features_test)predictions = torch.sign(predictions).reshape(labels_test.shape)correct = (predictions == labels_test).float()accuracy = correct.sum() / len(correct)print( "Accuracy: {}".format(accuracy))break
Accuracy: 0.9375

可以看到利用上述代码,我们可以得到一个精度相对较高的SVM分类器。

支持向量与间隔

在 SVM 中,“支持向量”是指那些距离超平面最近的数据点,它们对确定最优超平面起决定性作用。间隔(margin)是支持向量到超平面的距离,其大小由 1 ∥ w ∥ \frac{1}{\|w\|} w1 给出。SVM 的目标是最大化这个间隔。

核函数与非线性 SVM

对于非线性可分的数据集,我们可以通过引入核函数 K ( x , y ) K(x, y) K(x,y) 来将数据映射到一个更高维的空间,从而在新的空间中实现线性可分。常用的核函数包括多项式核、高斯核(RBF 核)等。
支持向量机(Support Vector Machine, SVM)是一种常用的监督学习模型,主要用于分类和回归分析。当数据不是线性可分时,可以引入核函数,将数据映射到更高维的空间,从而在新的空间中实现线性可分。

具有核函数的支持向量机

给定训练数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x N , y N ) } T = \{(x_1, y_1), (x_2, y_2), \ldots, (x_N, y_N)\} T={(x1,y1),(x2,y2),,(xN,yN)},其中 $ x_i \in \mathbb{R}^n,y_i \in {+1, -1} $。支持向量机的基本思想是找到一个超平面,以最大化两个类别之间的间隔。

在非线性可分的情况下,引入一个非线性映射 ϕ ( x ) \phi(x) ϕ(x) 将输入空间的数据映射到一个更高维的特征空间,然后在这个特征空间中寻找最优超平面。然而,直接计算 ϕ ( x ) \phi(x) ϕ(x) 可能是复杂的,甚至是不可能的。因此,我们引入核函数 K ( x , z ) K(x, z) K(x,z),它满足 K ( x , z ) = ϕ ( x ) ⋅ ϕ ( z ) K(x, z) = \phi(x) \cdot \phi(z) K(x,z)=ϕ(x)ϕ(z),从而避免显式地计算 ϕ ( x ) \phi(x) ϕ(x)

常用的核函数包括:

  • 线性核: K ( x , z ) = x ⋅ z K(x, z) = x \cdot z K(x,z)=xz
  • 多项式核: K ( x , z ) = ( γ x ⋅ z + r ) d K(x, z) = (\gamma x \cdot z + r)^d K(x,z)=(γxz+r)d,其中 γ , r , d \gamma, r, d γ,r,d 是参数。
  • 径向基核(RBF): K ( x , z ) = exp ⁡ ( − γ ∥ x − z ∥ 2 ) K(x, z) = \exp(-\gamma \|x - z\|^2) K(x,z)=exp(γxz2),其中 γ \gamma γ 是参数。
  • Sigmoid核: K ( x , z ) = tanh ⁡ ( γ x ⋅ z + r ) K(x, z) = \tanh(\gamma x \cdot z + r) K(x,z)=tanh(γxz+r),其中 γ , r \gamma, r γ,r 是参数。

对偶问题

在支持向量机中,对偶问题是通过拉格朗日乘数法将原问题转化为更易求解的形式。对偶问题的求解通常更高效,并且可以引入核函数来处理非线性可分的情况。

原问题可以表示为:
min ⁡ w , b , ξ 1 2 ∥ w ∥ 2 + C ∑ i = 1 N ξ i s.t. y i ( w ⋅ ϕ ( x i ) + b ) ≥ 1 − ξ i , ξ i ≥ 0 , i = 1 , 2 , … , N \min_{w, b, \xi} \frac{1}{2} \|w\|^2 + C \sum_{i=1}^{N} \xi_i \\ \text{s.t.} \quad y_i (w \cdot \phi(x_i) + b) \geq 1 - \xi_i, \quad \xi_i \geq 0, \quad i = 1, 2, \ldots, N w,b,ξmin21w2+Ci=1Nξis.t.yi(wϕ(xi)+b)1ξi,ξi0,i=1,2,,N
其中 w w w 是超平面的法向量, b b b 是偏置项, ξ i \xi_i ξi 是松弛变量,用于处理不可分的情况, C C C 是惩罚参数。

通过拉格朗日乘数法,我们可以得到对偶问题:
max ⁡ α ∑ i = 1 N α i − 1 2 ∑ i = 1 N ∑ j = 1 N α i α j y i y j K ( x i , x j ) s.t. ∑ i = 1 N α i y i = 0 , 0 ≤ α i ≤ C , i = 1 , 2 , … , N \max_{\alpha} \sum_{i=1}^{N} \alpha_i - \frac{1}{2} \sum_{i=1}^{N} \sum_{j=1}^{N} \alpha_i \alpha_j y_i y_j K(x_i, x_j) \\ \text{s.t.} \quad \sum_{i=1}^{N} \alpha_i y_i = 0, \quad 0 \leq \alpha_i \leq C, \quad i = 1, 2, \ldots, N αmaxi=1Nαi21i=1Nj=1NαiαjyiyjK(xi,xj)s.t.i=1Nαiyi=0,0αiC,i=1,2,,N
其中 α i \alpha_i αi 是拉格朗日乘子, K ( x i , x j ) K(x_i, x_j) K(xi,xj) 是核函数。

求解对偶问题后,我们可以得到最优的 α ∗ \alpha^* α,进而通过 α ∗ \alpha^* α 得到最优的超平面参数 w ∗ w^* w b ∗ b^* b。最终,决策函数可以表示为:
f ( x ) = sign ( ∑ i = 1 N α i ∗ y i K ( x i , x ) + b ∗ ) f(x) = \text{sign} \left( \sum_{i=1}^{N} \alpha_i^* y_i K(x_i, x) + b^* \right) f(x)=sign(i=1NαiyiK(xi,x)+b)

支持向量机的拓展:支持向量回归(SVR)

支持向量机不仅可以用于分类问题,还可以扩展到回归问题,即支持向量回归(Support Vector Regression, SVR)。在 SVR 中,目标是找到一个回归函数 f ( x ) = w ⋅ ϕ ( x ) + b f(x) = w \cdot \phi(x) + b f(x)=wϕ(x)+b,其中 ϕ ( x ) \phi(x) ϕ(x) 是将数据映射到高维空间的函数。SVR 通过引入一个不敏感损失函数 ϵ \epsilon ϵ 来实现回归,该函数只惩罚那些与预测值差距大于 ϵ \epsilon ϵ 的点。

SVR 的优化问题与 SVM 类似,但约束条件和目标函数有所不同。通过解决相应的优化问题,我们可以找到最优的回归函数。
支持向量机是一种强大的分类和回归工具,特别适合于处理高维数据和复杂模式识别问题。通过选择合适的核函数和参数,SVM 可以灵活地处理线性和非线性问题。此外,SVM 还可以通过拓展到支持向量回归来解决回归问题,进一步扩大了其应用范围。

接下来我们使用机器学习库sklearn实现支持向量机和支持向量回归

from sklearn import svm  
from sklearn.model_selection import train_test_split  
from sklearn import datasets  
from sklearn.metrics import accuracy_score  # 加载数据集,这里以鸢尾花数据集为例  
iris = datasets.load_iris()  
X = iris.data  
y = iris.target  # 划分训练集和测试集  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)  
# 创建SVM分类器  
clf = svm.SVC(kernel='linear')  # 线性核函数,你也可以选择其他核函数,如'rbf'、'poly'、'sigmoid'等  # 训练模型  
clf.fit(X_train, y_train)  # 进行预测  
y_pred = clf.predict(X_test)  # 评估模型  
print("Accuracy:", accuracy_score(y_test, y_pred))
Accuracy: 0.9777777777777777
# 接下来我们使用之前生成的数据进行支持向量回归,看看模型精度
X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.3) 
# 创建SVM分类器  
clf = svm.SVC(kernel='linear')  # 线性核函数,你也可以选择其他核函数,如'rbf'、'poly'、'sigmoid'等   
# 训练模型  
clf.fit(X_train, y_train)  
# 进行预测  
y_pred = clf.predict(X_test)  
# 评估模型  
print("Accuracy:", accuracy_score(y_test, y_pred))
Accuracy: 0.9963333333333333C:\Users\sswun\AppData\Roaming\Python\Python311\site-packages\sklearn\utils\validation.py:1183: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().y = column_or_1d(y, warn=True)

可以看到,利用sklearn设计的支持向量机分类器,我们可以得到一个很高的分类精度。接下来我们实现一下支持向量回归的过程。

# 支持向量回归过程
from sklearn.metrics import mean_squared_error  # 加载California housing数据集  
boston = datasets.fetch_california_housing()
X = boston.data  
y = boston.target  # 划分训练集和测试集  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 创建SVR模型  
svr = svm.SVR(kernel='rbf', C=1e3, gamma=0.1)  # 这里使用了RBF核函数  # 训练模型  
svr.fit(X_train, y_train)  # 进行预测  
y_pred = svr.predict(X_test)  # 评估模型  
mse = mean_squared_error(y_test, y_pred)  
print("Mean Squared Error:", mse)  
Mean Squared Error: 1.1010094730131161

支持向量机(SVM)的发展历程可以追溯到上个世纪60年代。1963年,Vapnik在解决模式识别问题时首次提出了支持向量方法,其中起决定性作用的样本被称为支持向量。然后在1971年,Kimeldorf提出了基于支持向量构建核空间的方法。然而,SVM的真正发展和普及是在1995年,当Vapnik等人正式提出统计学习理论之后。从那时起,SVM逐渐成为一种广泛使用的机器学习算法。

在SVM的发展历程中,还出现了许多改进和变种。例如,模糊支持向量机、最小二乘支持向量机、加权支持向量机、主动学习的支持向量机、以及基于决策树的支持向量机等,都是对原始SVM的改进和扩展。这些改进使得SVM能够更灵活地处理各种不同类型的数据和问题。

至于SVM的未来发展道路,虽然目前SVM已经在许多领域取得了显著的成功,但随着数据科学和机器学习领域的快速发展,SVM仍面临一些挑战和机遇。

一方面,随着大数据时代的到来,如何高效地处理海量数据成为SVM面临的一个重要问题。未来的研究可能会集中在开发更高效的优化算法,以提高SVM在处理大数据时的性能和效率。

另一方面,随着深度学习技术的快速发展,如何将深度学习的思想与方法融入SVM中,以进一步提升其性能,也是未来研究的一个重要方向。例如,可以利用深度学习的特征提取能力来优化SVM的输入特征,或者借鉴深度学习的训练方法来改进SVM的训练过程。

此外,随着越来越多的复杂应用场景的出现,如何对SVM进行改进以适应这些场景也是未来研究的一个重要课题。例如,在处理不平衡数据集、多类别分类、以及在线学习等问题时,SVM可能需要进行相应的改进和优化。

总的来说,虽然SVM已经是一种非常成熟和有效的机器学习算法,但随着技术的不断进步和应用场景的不断拓展,SVM仍然有着广阔的发展空间和潜力。
本文部分为torch框架以及部分理论分析,paddle框架对应代码可见支持向量机paddle

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

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

相关文章

数据结构-二叉树的遍历

二叉树的遍历广义上是指下面我们说的七种遍历 广度优先搜索 : 递归完成 前序 中序 后序 的遍历 深度优先搜索 : 层序遍历(借助队列) 非递归的迭代法完成前中后遍历(借助栈) 代码合集如下 package TreeDemo; import java.util.*; public class BinaryTreeTest {public static c…

怎么给字符串字段加索引?

怎么给字符串字段加索引&#xff1f; 现在&#xff0c;几乎所有的系统都支持邮箱登录&#xff0c;如何在邮箱这样的字段上建立合理的索引&#xff0c;是我们今天要讨论的问题。 假设&#xff0c;你现在维护一个支持邮箱登录的系统&#xff0c;用户表是这么定义的&#xff1a; …

美富特 | 邀您参加2024全国水科技大会暨技术装备成果展览会

王涛 四川美源环能科技有限公司 技术总监 报告题目&#xff1a;绿色智慧水岛如何助力工业园区污水及再生水资源化利用降碳增效 拥有十余年的环保行业从业经验&#xff0c;对各类前沿物化、生化及膜技术均有丰富的研发、设计及应用经验&#xff0c;先后参与多项重点核心技术…

日本宇宙航空研究“Int-Ball2”自由飞行相机机器人采用的Epson IMU

IMU有助于飞行的稳定控制和电池充电的自动对接- 精工爱普生公司&#xff08;TSE:6724&#xff0c;“Epson”&#xff09;很高兴地宣布&#xff0c;日本宇宙航空研究开发机构&#xff08;JAXA&#xff09;选择了爱普生M-G370系列的惯性测量单元&#xff08;IMU&#xff09;&…

开源相机管理库Aravis例程学习(五)——camera-api

开源相机管理库Aravis例程学习&#xff08;五&#xff09;——camera-api 简介例程代码函数说明arv_camera_get_regionarv_camera_get_pixel_format_as_stringarv_camera_get_pixel_formatARV_PIXEL_FORMAT_BIT_PER_PIXEL 简介 本文针对官方例程中的&#xff1a;03-camera-api…

揭密 scaling laws

Scaling laws OpenAI 在其早期的关于 scaling laws 的论文 [1] 中提出了基础理论&#xff0c;但该文缺乏一些具体的求解过程&#xff0c;且未能在更大规模的模型上进行验证。与此同时&#xff0c;后续研究&#xff0c;例如 DeepMind 的 ChinChilla [2] 还提出了不同的结论。 论…

Swift - 可选项(Optional)

文章目录 Swift - 可选项&#xff08;Optional&#xff09;1. 可选项&#xff08;Optional&#xff09;2. 强制解包&#xff08;Forced Unwrapping&#xff09;3. 判断可选项是否包含值4. 可选项绑定&#xff08;Optional Binding&#xff09;5. 等价写法6. while循环中使用可选…

「PHP系列」PHP 过滤器

文章目录 一、PHP过滤器二、PHP函数和过滤器1. 过滤器示例FILTER_VALIDATE_BOOLEANFILTER_VALIDATE_EMAILFILTER_VALIDATE_FLOATFILTER_VALIDATE_INTFILTER_VALIDATE_IPFILTER_VALIDATE_REGEXPFILTER_SANITIZE_STRINGFILTER_SANITIZE_ENCODEDFILTER_SANITIZE_FULL_SPECIAL_CHAR…

django运行配置

Setting.py # Internationalization # https://docs.djangoproject.com/en/5.0/topics/i18n/# 较早版本的 Django 可以尝试改为zh-CN,具体可查看 # “python/site-packages/django/conf/locale/”中的语言名称 LANGUAGE_CODE zh-Hans# Windows环境中此项的时区必须和系统一致…

在 Web3 方向有哪些工作,需要掌握哪些知识呢?

作者&#xff1a;0xrayyu 在Web3方向工作需要掌握的知识 投身Web3行业&#xff0c;无论您选择何种岗位&#xff0c;都需要构建一套涵盖基础理论、核心技术、生态应用与前沿趋势的知识体系。本文将对Web3工作者所需的整体知识进行阐述&#xff0c;并针对不同岗位的专业技能进行…

【论文阅读】互连网络的负载平衡路由算法 (CQR, Channel Queue Routing 通道队列路由)

Channel Queue Routing (CQR) 通道队列路由 1. Channel Queue Routing (CQR) 的动机 (1) 排队论(queueing theory)模型(2) GAL’s latency on tornado traffic(3) Routing tornado traffic with CQR 2. Channel Queue Routing 通道队列路由3. CQR 的性能4. 总结 Channel Queu…

滑动窗口DWA_planner

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言(1)DWA_planner算法基本原理1.DWA_planner图例2.DWA_planner输入输出3.DWA算法过程(直观理解)4.DWA_planner源码的主要接口及原理(2)move_ba…

Rust特征

一、Rust特征是什么、怎么用 1、Rust特征是什么 我认为Rust特征和Java中的接口类似&#xff0c;但是扩展了语义 特征定义了一组可以被共享的行为&#xff0c;只要实现了特征&#xff0c;你就能使用这组行为 2、Rust特征怎么使用 &#xff08;1&#xff09;特征定义 pub tra…

白话机器学习1:分类问题中的评价指标

机器学习中的评价指标非常多&#xff0c;它们用来衡量模型的性能和预测能力。不同类型的机器学习任务可能需要不同的评价指标。以下是一些常见的评价指标&#xff0c;按照不同类型的机器学习任务分类&#xff1a; 对于分类问题&#xff1a; 准确率&#xff08;Accuracy&#…

[NeurIPS-23] GOHA: Generalizable One-shot 3D Neural Head Avatar

[pdf | proj | code] 本文提出一种基于单图的可驱动虚拟人像重建框架。基于3DMM给粗重建、驱动结果&#xff0c;基于神经辐射场给细粒度平滑结果。 方法 给定源图片I_s和目标图片I_t&#xff0c;希望生成图片I_o具有源图片ID和目标图片表情位姿。本文提出三个分支&#xff1a;…

WPF —— MVVM command如何传递参数

点击按钮把窗体关闭 把页面的控件传递到自定义指令的函数中 FindAncestor 找到该组件的祖先元素 AncestorType{x:Type Window} 祖先元素类型为window CommandParameter 自定义指令传递参数 自定义指令 public class MyCommand : ICommand {public event Ev…

pytorch中创建maskrcnn模型

0.模型输入/输出参数参见 链接: pytorch的mask-rcnn的模型参数解释 核心代码 GeneralizedRCNN(这里以mask-rcnn来解释说明) # 通过输入图像获取fpn特征图,注意这里的backbone不是直接的resnet,而是fpn化后的 features self.backbone(images.tensors) # 由于是mask-rcnn,故而…

SpringCloud系列(10)--Eureka集群原理及搭建

前言&#xff1a;当注册中心只有一个&#xff0c;而且当这个注册中心宕机了&#xff0c;就会导致整个服务环境不可用&#xff0c;所以我们需要搭建Eureka注册中心集群来实现负载均衡故障容错 Eureka架构原理图 1、Eureka集群原理 2、创建Eureka Server端服务注册中心模块 (1)在…

R语言使用sjPlot包优雅绘制回归模型的交互效应图

交互作用效应(p for Interaction)在SCI文章中可以算是一个必杀技&#xff0c;几乎在高分的SCI中必出现&#xff0c;因为把人群分为亚组后再进行统计可以增强文章结果的可靠性&#xff0c;进行可视化后可以清晰的表明变量之间的关系。不仅如此&#xff0c;交互作用还可以使用来进…

Dockerfile实战(SSH、Systemctl、Nginx、Tomcat)

目录 一、构建SSH镜像 1.1 dockerfile文件内容 1.2 生成镜像 1.3 启动容器并修改root密码 二、构建Systemctl镜像 2.1 编辑dockerfile文件 ​编辑2.2 生成镜像 2.3 启动容器&#xff0c;并挂载宿主机目录挂载到容器中&#xff0c;然后进行初始化 2.4 进入容器验证 三、…