支持向量机——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) + b
    y += 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为服从标准正态分布的随机数,此处我们生成一个随机向量作为参数w
        self.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,b
        if 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 H
    elif a < L:
        return L
    else:
        return a

class 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.b
    
    def 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_i
        E_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_ij
        if eta <= 0:
            print('WARNING  eta <= 0')
            return
        alpha_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:
            return
        self.alpha[i], self.alpha[j] = alpha_i_new, alpha_j_new
        # 更新阈值b
        b_i = -E_i - y_i*k_ii*(alpha_i_new - alpha_i_old) - y_j*k_ij*(alpha_j_new - alpha_j_old) + self.b
        b_j = -E_j - y_i*k_ij*(alpha_i_new - alpha_i_old) - y_j*k_jj*(alpha_j_new - alpha_j_old) + self.b
        if 0 < alpha_i_new < self.C:
            self.b = b_i
        elif 0 < alpha_j_new < self.C:
            self.b = b_j
        else:
            self.b = (b_i + b_j)/2
    
    def refresh_params(self, x, y):
        # 利用SMO算法更新参数w,b,alpha
        if 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.9963333333333333


C:\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.mfbz.cn/a/581545.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【人工智能基础】逻辑回归实验分析

实验环境&#xff1a;anaconda、jutpyter Notebook 实验使用的库&#xff1a;numpy、matplotlib 一、逻辑回归 逻辑回归是一个常用于二分类的分类模型。本质是&#xff1a;假设数据服从这个分布&#xff0c;然后使用极大似然估计做参数的估计。 二、实验准备 引入库、预设值…

C++-DAY5

有以下类&#xff0c;完成特殊成员函数 #include <iostream>using namespace std; class Person {string name;int *age; public://有参构造Person(string name,int age):name(name),age(new int(age)){}//析构函数~Person(){delete age;}//拷贝构造Person(const Person …

FreeRTOS-系统时钟节拍和时间管理

一、前言 任何操作系统都需要提供一个时钟节拍&#xff0c;以供系统处理诸如延时&#xff0c;超时等与时间相关的事件。时钟节拍是特定的周期性中断&#xff0c; 这个中断可以看做是系统心跳。 中断之间的时间间隔取决于不同的应用&#xff0c;一般是 1ms – 100ms。时钟的节拍…

GQA分组注意力机制

一、目录 定义demo 二、实现 定义 grouped query attention&#xff08;GQA&#xff09; 1 GQA 原理与优点&#xff1a;将query 进行分组&#xff0c;每组query 参数共享一份key,value, 从而使key, value 矩阵变小。 2. 优点&#xff1a; 降低内存读取模型权重的时间开销&am…

无缝迁移:从阿里云WAF到AWS的成功转变之路

在当今数字化浪潮中&#xff0c;网络安全已经成为企业发展的重要组成部分。阿里云WAF&#xff08;Web 应用防火墙&#xff09;作为一种重要的网络安全解决方案&#xff0c;帮助企业保护其 Web 应用免受各种网络攻击。 然而&#xff0c;随着企业业务的扩展和需求的变化&#xf…

可替代IBM DOORS的现代化需求管理解决方案Jama Connect,支持数据迁移及重构、实时可追溯性、简化合规流程

作为一家快速发展的全球性公司&#xff0c;dSPACE一直致力于寻找保持领先和优化开发流程的方法。为推进其全球现代化计划&#xff0c;dSPACE开始寻找可以取代传统需求管理平台&#xff08;IBM DOORS&#xff09;的需求管理解决方案。 通过本次案例&#xff0c;您将了解dSPACE为…

数据结构-简单队列

1.简介 队列为一个有序列表&#xff0c;可以用数组或链表来实现。 先进先出原则。先存入队列的数据先取出&#xff0c;后存进队列的数据后取出。 这里对比一下&#xff0c;栈是后来者居上 下面使用数组来模拟队列&#xff0c;用数组的结构来存储队列的数据&#xff1a; Que…

Stable Diffusion教程:额外功能/后期处理/高清化

"额外功能"对应的英文单词是Extras&#xff0c;算是直译。但是部分版本中的翻译是“后期处理”或者“高清化”&#xff0c;这都是意译&#xff0c;因为它的主要功能是放大图片、去噪、修脸等对图片的后期处理。注意这里边对图片的处理不是 Stable Diffusion 本身的能…

微软开源了 MS-DOS 4.00

DOS的历史源远流长&#xff0c;很多现在的年轻人不知道DOS了。其实早期的windows可以看做是基于DOS的窗口界面的模拟器&#xff0c;系统的本质其实是DOS。后来DOS的漏洞还是太多了&#xff0c;微软重新写了windows的底层内核。DOS只是一个辅助终端的形式予以保留了。 微软是在…

FreeRTOS学习——FreeRTOS队列(上)

本篇文章记录我学习FreeRTOS队列的相关知识&#xff0c;主要包括队列简介、队列的结构体、队列创建等知识。 队列是为了任务与任务、任务与中断之间的通信而准备的&#xff0c;可以在任务与任务、任务与中断之间传递消息&#xff0c;队列中可以存储有限的、大小固定的数据项目。…

大白菜启动U盘想格式化但格式化不了

部分区域被修改分区表保护起来了。直接格式化的话&#xff0c;里面的文件夹都还在。根本格式化不了。特别是可用容量并未还原出来。 进入计算机管理》磁盘管理&#xff0c;看到U盘盘符。别搞错了。删除掉里面的已经分的区域和未分区区域&#xff0c;让它还原成一个整体。退出。…

分类预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测

分类预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测 目录 分类预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测&#xff08;Matlab实…

javaweb学习week6

javaweb学习 九.登录认证 5.登录后下发令牌 生成令牌&#xff1a;引入JWT令牌操作工具类&#xff0c;登录完成后&#xff0c;调用工具类生成JWT令牌&#xff0c;并返回 代码实例&#xff1a; 6.Filter入门 概念&#xff1a;Filter过滤器&#xff0c;是Javaweb三大组件之一…

在STM32上实现无线传感器网络节点

引言 无线传感器网络&#xff08;WSN&#xff09;是物联网&#xff08;IoT&#xff09;技术的关键组成部分&#xff0c;广泛应用于环境监测、智能建筑、精密农业等领域。 本教程将介绍如何在STM32微控制器上设计和实现一个无线传感器网络节点&#xff0c;包括硬件选择、网络协…

企业计算机服务器中了helper勒索病毒怎么办?Helper勒索病毒解密处理流程

网络技术的不断发展与成熟&#xff0c;为企业的生产运营提供了极大便利&#xff0c;让企业的发展速度大大提升&#xff0c;但网络毕竟是虚拟服务系统&#xff0c;虽然可以为企业提供便利&#xff0c;但也会给企业数据安全带来严重威胁。近日&#xff0c;云天数据恢复中心接到山…

visionPro链接相机

搜索Cognex GigE Vision Configura… 修改子网掩码为255.255.255.0 配置驱动程序 更新驱动&#xff08;如果能够选择9014Bytes&#xff0c;跳过此步骤&#xff09; 更新更改 相机ip配置 打开visionPro 选择照相机 查看实时画面 运行保存图像

【论文】关于网页上能打开的文章下载PDF“显示无效或损坏的 PDF 文件”的解决办法

1. 遇到的问题 今天我在 dl.acm.org/doi 下载论文时发现下载后的pdf打开出现“显示无效或损坏的 PDF 文件” 可是在原网址是可以打开并显示的 2. 解决方案 这里我用到了和之前【论文】去除PDF论文行号的完美解决方案 的相似的解决办法 就是下载的时候不直接下载&#xf…

【java9】java9新特性之接口的私有方法

在Java 9中&#xff0c;接口可以包含私有方法&#xff08;包括静态私有方法和实例私有方法&#xff09;。这允许接口的设计者创建一些辅助方法&#xff0c;这些方法只能被接口中的其他方法所使用&#xff0c;而不能被实现该接口的类直接访问。 Java7 Java7及之前 &#xff0c…

文件缓冲区

为什么要有文件缓冲区的存在&#xff1f; 假设甲在云南&#xff0c;甲的朋友乙在北京&#xff0c;甲想给乙送个东西就需要跑到北京去&#xff1a;这时候有菜鸟驿站了&#xff0c;甲就不用跑了&#xff0c;直接把包裹交给菜鸟驿站就可以了。缓冲区就类似于菜鸟驿站&#xff0c;…

【vscode环境配置系列】vscode远程debug配置

VSCODE debug环境配置 插件安装配置文件debug 插件安装 安装C/C, C/C Runner 配置文件 在项目下建立.vscode文件夹&#xff0c;然后分别建立c_cpp_properties.json&#xff0c; launch.json&#xff0c;tasks.json&#xff0c;内容如下&#xff1a; c_cpp_properties.json:…
最新文章