【人工智能Ⅰ】实验11:支持向量机

实验11 支持向量机

一、实验目的

1:了解支持向量机的结构和原理。

2:应用支持向量机建立训练模型,对模型进行评估。

二、实验内容和要求

【实验内容】

选择支持向量机,对花卉图像或玉米果穗图像进行分类。花卉图像包括玫瑰,向日葵和蒲公英;玉米果穗图像包括虫蛀,损伤,发霉。

(1)可针对这些特点对图像的颜色、纹理、形状进行分析,从而进行特征选择与提取;

(2)也可以尝试不提取特征,直接将图像作为输入,对比效果;

(3)调整人工神经网络的参数,观察不同的参数对分类结果的影响;

(4)实现对花卉图像的分类。

【实验要求】

1:完成对花卉数据集的分类任务。

2:调整不同的参数,通过对分类结果的对比,选取合适的参数。

3:使用不同的样本数量,查看是否对分类结果产生影响。可对样本进行扩增(例如:反转、平移、缩放、亮度变化)。

4:进行人工神经网络和支持向量机的方法对比。

三、实验结果与分析

1:基于sklearn依赖的SVM多分类

【1】代码任务解析:

(1)初始化数据集路径和分类标签

(2)读取数据集图像信息

(3)将图像提取的像素转成numpy数组

(4)按照8:2的比例划分训练集和测试集

(5)调用sklearn中的SVM-Classifier,实例化模型

(6)输入训练集进行训练,并输出训练集的准确率

(7)输入测试集进行预测,并输出测试集的准确率

【2】程序输出结果:


上述程序打印了SVM多分类的训练集准确率和测试集准确率,在花卉数据集上的结果如下图所示。


在玉米数据集上的结果如下图所示。

综上所述,在花卉数据集上SVM的训练集准确率是1.00、测试集准确率是0.83;在玉米数据集上SVM的训练集准确率是1.00、测试集准确率是0.50。

2:基于数学原理手动实现的SVM多分类代码

【1】代码任务解析:

(1)构建SimpleSVM类,定义初始化函数init、训练函数fit(包含损失曲线的绘制)、预测函数predict,各个函数的代码如下图所示。


init函数:


fit函数:


predict函数:

(2)读取数据集图像信息

(3)将图像提取的像素转成numpy数组

(4)按照8:2的比例划分训练集和测试集
(5)调用SimpleSVM类,实例化模型

(6)输入训练集进行训练,并输出训练集的准确率

(7)输入测试集进行预测,并输出测试集的准确率


(8)从测试集中随机抽样,输出真实标签和预测标签

【2】程序输出结果:

上述程序在训练过程中跟踪了模型的损失,并绘制出了损失曲线。在花卉数据集上的结果如下图所示。可以发现,随着迭代次数epoch的增加,模型的损失loss在逐渐稳定。


SVM模型训练完成后,计算了训练集准确率和测试集准确率,结果如下图所示。

综上所述,在花卉数据集上SVM的训练集准确率是1.00、测试集准确率是0.67。

同时,上述程序中展示了模型的预测性能,对5张测试集图像进行了抽样展示,结果如下图所示。

【测试1:真实标签——2,预测标签——2,二者相同】


【测试2:真实标签——1,预测标签——1,二者相同】


【测试3:真实标签——3,预测标签——3,二者相同】


【测试4:真实标签——2,预测标签——2,二者相同】


【测试5:真实标签——2,预测标签——3,二者不相同】

3:进行人工神经网络和支持向量机的方法对比

在这两次的实验过程中,从训练过程来看,SVM的训练速度明显优于ANN的训练速度,且SVM的模型参数明显少于ANN的模型参数。从训练结果来看,SVM的准确率明显高于ANN的准确率。

同时,当ANN在训练集上表现出较高的准确率时,往往会在测试集上表现不佳,这表明模型存在过拟合问题。而支持向量机通常具有更好的泛化能力,对过拟合的抵抗能力较强。

综上所述,两种方法的对比总结如下。

(1)学习方式:

ANN:人工神经网络是一种基于神经元模型的机器学习方法,通过前向传播和反向传播来学习权重和参数,是一种端到端的学习方法,可以适应各种不同的任务。

SVM:支持向量机是一种监督学习方法,它寻找一个最优的超平面来分隔不同类别的数据点,是一种判别式学习方法,主要用于分类问题。

(2)可解释性:

ANN:神经网络通常被认为是黑盒模型,难以解释其内部的决策过程。

SVM:支持向量机的决策边界由支持向量确定,相对较容易解释和可视化。

(3)计算复杂度:

ANN:神经网络通常需要更多的计算资源和时间来训练。

SVM:支持向量机通常具有较低的计算复杂度,例如线性核情况。

(4)鲁棒性:

ANN:神经网络对于数据中的噪声和异常值较为敏感,需要大量数据来训练稳定的模型。

SVM:支持向量机对异常值有一定的鲁棒性,主要依赖于支持向量来确定决策边界。

(5)参数调整:

ANN:神经网络通常有很多参数需要调整,包括层数、神经元数量、学习率、激活函数等。

SVM:支持向量机的参数通常较少,主要是正则化参数C和核函数的选择。

4:基于实验指导的SVM模型实现(针对mnist手写数据集)

【1】代码任务解析:


(1)将csv文件转化为npy文件


(2)修改SVM代码中main函数部


【2】程序输出结果:

四、遇到的问题和解决方法


问题1:在针对图像数据集运行实验指导中提供的代码时,实例化模型会出现以下的报错。

解决1:未解决,如果对矩阵进行flatten(平整化),则会继续出现dim不符合的报错。最后直接重新实现了新的代码,如SimpleSVM类所示。

五、实验总结

1:SVM是一种有监督学习算法,能够找到在高维空间中有效分隔不同类别的超平面,在高维问题中表现出色,适用于处理具有大量特征的数据集。SVM对异常值具有一定的鲁棒性,因为它主要依赖于支持向量来确定超平面,而不是全部数据点。同时,SVM有一些参数需要调整,如正则化参数C、核函数的类型和参数等。

2: SVM最初是用于二元分类问题的,但也可以通过一对多(One-vs-Rest,OvR)或一对一(One-vs-One,OvO)等策略扩展到多元分类问题。

3:最大间隔:能够最大化两个不同类别之间的间隔的超平面。最大间隔有助于提高模型的泛化性能。

4:SVM可以使用核函数来处理非线性可分的数据。常用的核函数包括线性核、多项式核和径向基函数(RBF)核。

六、程序源代码

1:基于sklearn依赖的SVM多分类代码

import os

import numpy as np

import cv2

from sklearn.model_selection import train_test_split

from sklearn.svm import SVC

from sklearn.metrics import accuracy_score

# 图像数据所在的根目录

data_root = r'C:\Users\86158\Desktop\dataset\data1'

# 遍历每个类别的文件夹

class_labels = []

X = []

y = []

for class_label in os.listdir(data_root):

    class_path = os.path.join(data_root, class_label)

   

    # 确保当前路径是一个目录

    if os.path.isdir(class_path):

        class_labels.append(class_label)

       

        # 分配一个唯一的整数标签给每个类别

        label = len(class_labels) - 1  

       

        # 遍历当前类别的图像文件

        for image_file in os.listdir(class_path):

            image_path = os.path.join(class_path, image_file)

           

            # 使用OpenCV加载图像

            image = cv2.imread(image_path)

           

            # 调整图像大小为统一的尺寸 100x100

            image = cv2.resize(image, (100, 100))

           

            # 展平图像数据

            image_flat = image.flatten()

           

            # 将图像数据和标签添加到Xy

            X.append(image_flat)

            y.append(label)

# 将图像数据转换为NumPy数组

X = np.array(X)

y = np.array(y)

# 数据集划分为训练集和测试集

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建SVM分类器

svm_classifier = SVC(kernel='linear', C=1.0, random_state=42)

# 训练分类器

svm_classifier.fit(X_train, y_train)

# 在训练集上进行预测

y_train_pred = svm_classifier.predict(X_train)

# 计算训练集准确率

train_accuracy = accuracy_score(y_train, y_train_pred)

print("训练集准确率:")

print(f'Training Accuracy: {train_accuracy}')

# 在测试集上进行预测

y_pred = svm_classifier.predict(X_test)

# 计算准确率

accuracy = accuracy_score(y_test, y_pred)

print("测试集准确率:")

print(f'Accuracy: {accuracy}')

2:基于数学原理手动实现的SVM多分类代码

import numpy as np

import os

import cv2

from sklearn.model_selection import train_test_split

from sklearn.metrics import accuracy_score

import matplotlib.pyplot as plt

import random

class SimpleSVM:

    def __init__(self):

        self.weights = None

        self.classes = None

    def fit(self, X, y, epochs=100, lr=0.001, lambda_param=0.01):

        self.classes = np.unique(y)

        n_samples, n_features = X.shape

        n_classes = len(self.classes)

        # 初始化权重

        self.weights = np.zeros((n_classes, n_features))

        # 训练过程

        for _ in range(epochs):

            for idx, x_i in enumerate(X):

                class_index = np.where(self.classes == y[idx])[0][0]

                for c in range(n_classes):

                    if c == class_index:

                        continue

                    margin = 1 - np.dot(x_i, self.weights[class_index]) + np.dot(x_i, self.weights[c])

                    if margin > 0:

                        self.weights[class_index] -= lr * (-2 * lambda_param * self.weights[class_index] - x_i)

                        self.weights[c] -= lr * (-2 * lambda_param * self.weights[c] + x_i)

    def predict(self, X):

        predictions = np.dot(X, self.weights.T)

        return self.classes[np.argmax(predictions, axis=1)]

   

    # 重新定义fit函数,在训练过程中输出loss

    def fit(self, X, y, epochs=100, lr=0.001, lambda_param=0.01):

        self.classes = np.unique(y)

        n_samples, n_features = X.shape

        n_classes = len(self.classes)

        # 初始化权重

        self.weights = np.zeros((n_classes, n_features))

       

        # 用于存储损失值

        losses = []

        # 训练过程

        for epoch in range(epochs):

            for idx, x_i in enumerate(X):

                class_index = np.where(self.classes == y[idx])[0][0]

                for c in range(n_classes):

                    if c == class_index:

                        continue

                    margin = 1 - np.dot(x_i, self.weights[class_index]) + np.dot(x_i, self.weights[c])

                    if margin > 0:

                        self.weights[class_index] -= lr * (-2 * lambda_param * self.weights[class_index] - x_i)

                        self.weights[c] -= lr * (-2 * lambda_param * self.weights[c] + x_i)

           

            # 计算损失并添加到列表中

            loss = 0.5 * np.sum(self.weights ** 2) + np.sum(np.maximum(0, 1 - np.dot(X, self.weights.T)))

            losses.append(loss)

       

        # 绘制损失曲线

        plt.plot(range(1, epochs + 1), losses, marker='o')

        plt.xlabel('Epochs')

        plt.ylabel('Loss')

        plt.title('Loss Curve')

        plt.show()

data_root = r'C:\Users\86158\Desktop\dataset\data1'

# 遍历每个类别的文件夹

class_labels = []

X = []

y = []

for class_label in os.listdir(data_root):

    class_path = os.path.join(data_root, class_label)

   

    # 确保当前路径是一个目录

    if os.path.isdir(class_path):

        class_labels.append(class_label)

        label = len(class_labels) - 1  # 分配一个唯一的整数标签给每个类别

       

        # 遍历当前类别的图像文件

        for image_file in os.listdir(class_path):

            image_path = os.path.join(class_path, image_file)

           

            # 使用OpenCV加载图像

            image = cv2.imread(image_path)

           

            # 调整图像大小为统一的尺寸 100x100

            image = cv2.resize(image, (100, 100))

           

            # 展平图像数据

            image_flat = image.flatten()

           

            # 将图像数据和标签添加到Xy

            X.append(image_flat)

            y.append(label)

# 将图像数据转换为NumPy数组

X = np.array(X)

y = np.array(y)

# 数据集划分为训练集和测试集

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

model = SimpleSVM()

model.fit(X_train,y_train)

y_pred = model.predict(X_test)

# 计算准确率

accuracy = accuracy_score(y_test, y_pred)

print(f'Accuracy: {accuracy}')

# 从测试集中随机选择5个样本

sample_indices = random.sample(range(len(X_test)), 5)

for idx in sample_indices:

    sample_image = X_test[idx].reshape(100, 100, 3)

    true_label = class_labels[y_test[idx]]

    predicted_label = class_labels[y_pred[idx]]

    plt.imshow(sample_image)

    plt.title(f'True Label: {true_label}, Predicted Label: {predicted_label}')

    plt.show()

3:实验指导中的参考代码(修改后)

from numpy import *

import numpy as np

import random

# calulate kernel value

def calcKernelValue(matrix_x, sample_x, kernelOption):

    kernelType = kernelOption[0]

    numSamples = matrix_x.shape[0]

    kernelValue = mat(zeros((numSamples, 1)))

    if kernelType == 'linear':

        kernelValue = matrix_x * sample_x.T

    elif kernelType == 'rbf':

        sigma = kernelOption[1]

        if sigma == 0:

            sigma = 1.0

        for i in range(numSamples):

            diff = matrix_x[i, :] - sample_x

            kernelValue[i] = exp(diff * diff.T / (-2.0 * sigma ** 2))

    else:

        raise NameError('Not support kernel type! You can use linear or rbf!')

    return kernelValue

# calculate kernel matrix given train set and kernel type

def calcKernelMatrix(train_x, kernelOption):

    numSamples = train_x.shape[0]

    kernelMatrix = mat(zeros((numSamples, numSamples)))

    for i in range(numSamples):

        kernelMatrix[:, i] = calcKernelValue(train_x, train_x[i, :], kernelOption)

    return kernelMatrix

# define a struct just for storing variables and data

class SVMStruct:

    def __init__(self, dataSet, labels, C, toler, kernelOption):

        self.train_x = dataSet

        self.train_y = labels

        self.C = C

        self.toler = toler

        self.numSamples = dataSet.shape[0]

        self.alphas = mat(zeros((self.numSamples, 1)))

        self.b = 0

        self.errorCache = mat(zeros((self.numSamples, 2)))

        self.kernelOpt = kernelOption

        self.kernelMat = calcKernelMatrix(self.train_x, self.kernelOpt)

# calculate the error for alpha k

def calcError(svm, alpha_k):

    output_k = float(multiply(svm.alphas, svm.train_y).T * svm.kernelMat[:, alpha_k] + svm.b)

    error_k = output_k - float(svm.train_y[alpha_k])

    return error_k

# update the error cache for alpha k after optimize alpha k

def updateError(svm, alpha_k):

    error = calcError(svm, alpha_k)

    svm.errorCache[alpha_k] = [1, error]

# select alpha j which has the biggest step

def selectAlpha_j(svm, alpha_i, error_i):

    svm.errorCache[alpha_i] = [1, error_i]

    candidateAlphaList = nonzero(svm.errorCache[:, 0].A)[0]

    maxStep = 0

    alpha_j = 0

    error_j = 0

    if len(candidateAlphaList) > 1:

        for alpha_k in candidateAlphaList:

            if alpha_k == alpha_i:

                continue

            error_k = calcError(svm, alpha_k)

            if abs(error_k - error_i) > maxStep:

                maxStep = abs(error_k - error_i)

                alpha_j = alpha_k

                error_j = error_k

    else:

        alpha_j = alpha_i

        while alpha_j == alpha_i:

            alpha_j = int(random.uniform(0, svm.numSamples))

        error_j = calcError(svm, alpha_j)

    return alpha_j, error_j

# the inner loop for optimizing alpha i and alpha j

def innerLoop(svm, alpha_i):

    error_i = calcError(svm, alpha_i)

    if (svm.train_y[alpha_i] * error_i < -svm.toler) and (svm.alphas[alpha_i] < svm.C) or (

            svm.train_y[alpha_i] * error_i > svm.toler) and (svm.alphas[alpha_i] > 0):

        alpha_j, error_j = selectAlpha_j(svm, alpha_i, error_i)

        alpha_i_old = svm.alphas[alpha_i].copy()

        alpha_j_old = svm.alphas[alpha_j].copy()

        if svm.train_y[alpha_i] != svm.train_y[alpha_j]:

            L = max(0, svm.alphas[alpha_j] - svm.alphas[alpha_i])

            H = min(svm.C, svm.C + svm.alphas[alpha_j] - svm.alphas[alpha_i])

        else:

            L = max(0, svm.alphas[alpha_j] + svm.alphas[alpha_i] - svm.C)

            H = min(svm.C, svm.alphas[alpha_j] + svm.alphas[alpha_i])

        if L == H:

            return 0

        eta = 2.0 * svm.kernelMat[alpha_i, alpha_j] - svm.kernelMat[alpha_i, alpha_i] - svm.kernelMat[alpha_j, alpha_j]

        if eta >= 0:

            return 0

        svm.alphas[alpha_j] -= svm.train_y[alpha_j] * (error_i - error_j) / eta

        if svm.alphas[alpha_j] > H:

            svm.alphas[alpha_j] = H

        if svm.alphas[alpha_j] < L:

            svm.alphas[alpha_j] = L

        if abs(alpha_j_old - svm.alphas[alpha_j]) < 0.00001:

            updateError(svm, alpha_j)

            return 0

        svm.alphas[alpha_i] += svm.train_y[alpha_i] * svm.train_y[alpha_j] * (alpha_j_old - svm.alphas[alpha_j])

        b1 = svm.b - error_i - svm.train_y[alpha_i] * (svm.alphas[alpha_i] - alpha_i_old) * svm.kernelMat[

            alpha_i, alpha_i] * svm.train_y[alpha_j] * (svm.alphas[alpha_j] - alpha_j_old) * svm.kernelMat[

            alpha_i, alpha_j]

        b2 = svm.b - error_j - svm.train_y[alpha_i] * (svm.alphas[alpha_i] - alpha_i_old) * svm.kernelMat[

            alpha_i, alpha_j] - svm.train_y[alpha_j] * (svm.alphas[alpha_j] - alpha_j_old) * svm.kernelMat[

            alpha_j, alpha_j]

        if (0 < svm.alphas[alpha_i]) and (svm.alphas[alpha_i] < svm.C):

            svm.b = b1

        elif (0 < svm.alphas[alpha_j]) and (svm.alphas[alpha_j] < svm.C):

            svm.b = b2

        else:

            svm.b = (b1 + b2) / 2.0

        updateError(svm, alpha_j)

        updateError(svm, alpha_i)

        return 1

    else:

        return 0

# the main training procedure

def trainSVM(train_x, train_y, C, toler, maxIter, kernelOption=('rbf', 1.0)):

    svm = SVMStruct(mat(train_x), mat(train_y), C, toler, kernelOption)

    entireSet = True

    alphaPairsChanged = 0

    iterCount = 0

    while (iterCount < maxIter) and ((alphaPairsChanged > 0) or entireSet):

        alphaPairsChanged = 0

        if entireSet:

            for i in range(svm.numSamples):

                alphaPairsChanged += innerLoop(svm, i)

            print('---iter:%d entire set, alpha pairs changed:%d' % (iterCount, alphaPairsChanged))

            iterCount += 1

        else:

            nonBoundAlphasList = nonzero((svm.alphas.A > 0) * (svm.alphas.A < svm.C))[0]

            for i in nonBoundAlphasList:

                alphaPairsChanged += innerLoop(svm, i)

            print('---iter:%d non boundary, alpha pairs changed:%d' % (iterCount, alphaPairsChanged))

            iterCount += 1

        if entireSet:

            entireSet = False

        elif alphaPairsChanged == 0:

            entireSet = True

    return svm

# testing your trained svm model given test set

def testSVM(svm, test_x):

    test_x = mat(test_x)

    numTestSamples = test_x.shape[0]

    supportVectorsIndex = nonzero(svm.alphas.A > 0)[0]

    supportVectors = svm.train_x[supportVectorsIndex]

    supportVectorLabels = svm.train_y[supportVectorsIndex]

    supportVectorAlphas = svm.alphas[supportVectorsIndex]

    re_predict = []

    for i in range(numTestSamples):

        kernelValue = calcKernelValue(supportVectors, test_x[i, :], svm.kernelOpt)

        predict = kernelValue.T * multiply(supportVectorLabels, supportVectorAlphas) + svm.b

        re_predict.append(predict)

    return re_predict

# Standardize the data

def Standar(data):

    mean = np.mean(data, axis=1).reshape(-1, 1)

    std = np.std(data, axis=1).reshape(-1, 1)

    another_trans_data = data - mean

    return another_trans_data / std

if __name__ == '__main__':

    C, toler, maxIter = 0.6, 0.001, 40

    train_data = np.load(r'C:\Users\86158\Desktop\mnist_train_100.npy')

    test_data = np.load(r'C:\Users\86158\Desktop\mnist_test_10.npy')

    train_x, y_train, test_x, y_test = train_data[:, 1:], train_data[:, 0].reshape(-1, 1), test_data[:, 1:], test_data[:,0].reshape(-1, 1)

    X_large_train = Standar(train_x)

    X_large_test = Standar(test_x)

    print(train_x.shape, y_train.shape, test_x.shape, y_test.shape)

    svmClassifier = trainSVM(X_large_train, y_train, C, toler, maxIter, kernelOption=('linear', 0))

    print("Step 3: Testing...")

    predict = testSVM(svmClassifier, X_large_test)

    print("预测结果:", predict)

4:csv文件转换为npy文件的代码

import pandas as pd

import numpy as np

# CSV文件加载数据

csv_file = r'C:\Users\86158\Desktop\mnist_test_10.csv'

data = pd.read_csv(csv_file)

# 将数据转换为NumPy数组

data_array = data.to_numpy()

# 保存为NPY文件

npy_file = r'C:\Users\86158\Desktop\mnist_test_10.npy'

np.save(npy_file, data_array)

print(f"CSV文件 '{csv_file}' 已成功转换为 NPY文件 '{npy_file}'")

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

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

相关文章

关于LINUX操作系统异常宕机重启的分析思路

一、先搞清楚现状 当收到系统宕机告警或者故障反馈时&#xff0c;需要先对情况进行核实。比如检查系统启动时间&#xff0c;是不是真实发生了重启&#xff1f;如果重启了&#xff0c;什么时间点发生的重启&#xff1f;重启了几次&#xff1f;重启之前有无变更操作&#xff1f;…

PyTorch|构建自己的卷积神经网络——nn.Sequential()

之前在构建神经网络时&#xff0c;我们一般是采用这种方式&#xff0c;就像这样&#xff1a; class Network1(nn.Module): def __init__(self): super(Network1,self).__init__() self.conv1 nn.Conv2d(in_channels3, out_channels6, kernel_size5) …

【控制篇 / 策略】(7.4) ❀ 03. 地理地址对象在路由中的应用 ❀ FortiGate 防火墙

【简介】如何做到访问国内走Wan1&#xff0c;访问国际走Wan2 &#xff1f;当企业有多条宽带&#xff0c;特别是有国际专线的时候&#xff0c;这个需求就很普遍了。通过地理地址对象可以快速的解决这些问题。 策略路由 当我们有多条宽带的时候&#xff0c;我们有两种方法分流&am…

C++的虚基类

前言 本文介绍C的虚基类 先看一个问题 先看一段代码 #include <iostream> class A { public:int a 1; };class B1:public A { public:int b1 2; };class B2 :public A { public:int b2 3; };class C1:public B1,public B2 { public:int c1 4; };int main(int arg…

每日汇评:黄金多头能否在美国CPI数据发布后占有主动权?

黄金价格再次在2020美元附近找到支撑&#xff0c;因为所有人都在关注美国的通胀数据&#xff1b; 尽管最近美国国债收益率有所上升&#xff0c;但美元仍进一步下跌&#xff1b; 金价保持在21日移动均线和50日移动均线之间&#xff0c;等待区间突破&#xff1b; 在周四早盘的亚洲…

SIT1050ISO具有隔离功能,1Mbps,高速 CAN 总线收发器

➢ 完全兼容“ ISO 11898 ”标准&#xff1b; ➢ 内置过温保护&#xff1b; ➢ 100kV/s 瞬态抗扰度&#xff1b; ➢ 显性超时功能&#xff1b; ➢ -40V 至 40V 的总线故障保护&#xff1b; ➢ I/O 电压范围支持 3.3V 和 5V MCU &#xff1b; ➢ 低环路延迟…

解决原生微信小程序获取关联公众号的code(不是wx.login的code)来获取公众号的openId

解决步骤 以下是使用 web-view 并配配合微信公众号提供的 网页授权 来实现 1、在小程序中做一个web-view页面&#xff0c;页面中只需要写微信 网页授权的链接就行了&#xff0c;注意appid请自行替换&#xff08;公众号的&#xff09;。 onLoad() {this.setData({src: https://o…

Android SDK环境搭建[图解]; 解决问题Done. Nothing was installed.

安装SDK Android SDK环境搭建 依赖java环境,需要自备Java环境 (100%实操成功) 目录 1. 解压&#xff1a;解压到非中文无特殊字符的目录 2. 双击&#xff1a;SDK Manager.exe&#xff0c;不要选全部!不要选全部!不要选全部!(会下很久) 3. 然后勾选组件​ 4. 设置环境变量 …

UM2003A 一款200 ~ 960MHz ASK/OOK +18dBm 发射功率的单发射芯片

UM2003A 是一款工作于 200 ~ 960MHz 频段的单片集成、高性能、可独立运行的 OOK 发射器。内部集成的 OTP 方便用户对各种射频参数以及特色功能进行编程。该芯片以其高集成度和低功耗的设计&#xff0c;特别适用于低成本&#xff0c;低功耗&#xff0c;电池驱动的无线发射应用。…

【TypeScript】入门基础知识

目前在做项目的技术栈是 reacttypescript&#xff0c;之前只知道 ts 是 js 的扩展&#xff0c;增加了类型检查&#xff0c;但是没有仔细的学过&#xff0c;纯纯看别人代码上手 anyscript&#xff08;这很难评...&#xff09;。趁着最近空闲&#xff0c;就学习一下 ts 的基础知识…

章鱼网络 2023 年全回顾|暨12月进展报告

2023年&#xff0c;章鱼网络轻装上阵&#xff0c;身处加密行业的低谷中砥砺前行。 12月17日&#xff0c;经过整整1年时间的开发和打磨&#xff0c;章鱼网络在重磅上线 Octopus 2.0&#xff0c;即 $NEAR Restaking 和 NEAR-IBC&#xff0c;获得了社区和市场的一致认可&#xff…

Java中多线程二

抢占调度模型 概述&#xff1a;优先让优先级高的线程使用 CPU &#xff0c;如果线程的优先级相同&#xff0c;那么随机会选择一个&#xff0c;优先级高的线程获取的 CPU 时间片相对多一些 Thread 类中一些关于线程的方法 方法简述public final int getPriority()返回此线程的优…

自动化控制面板-1Panel

一、1Panel自动化控制面板 官网地址 1Panel 可以实现&#xff1a; 快速建站、高效管理、安全可靠、一键备份、应用商店 快速建站&#xff1a;深度集成 Wordpress 和 Halo&#xff0c;域名绑定、SSL 证书配置等一键搞定&#xff1b;高效管理&#xff1a;通过 Web 端轻松管理 …

Docker启动报错:No chain/target/match by that name 处理

一、问题描述 某次OS升级重启后&#xff0c;发现docker redis实例无法启动&#xff0c;报错如下&#xff1a; Error response from daemon: driver failed programming external connectivity on endpoint vpm.redis.2 (f4b70fef65000bcacb574ee59e65d9b7a25f2abfa5dec0be9b74…

阿里云实时计算企业级状态存储引擎 Gemini 技术解读

本文整理自阿里云 Flink 存储引擎团队李晋忠&#xff0c;兰兆千&#xff0c;梅源关于阿里云实时计算企业级状态存储引擎 Gemini 的研究&#xff0c;内容主要分为以下五部分&#xff1a; 流计算状态访问的痛点企业级状态存储引擎GeminiGemini 性能评测&线上表现结语参考 一、…

2024年最新ChemiCloud优惠75%折扣WordPress外贸主机

ChemiCloud怎么样&#xff1f;ChemiCloud好不好&#xff1f;ChemiCloud是一家成立于2016年的云虚拟主机提供商&#xff0c;他们在全球范围内拥有多个机房&#xff0c;并以其出色的性价比而备受赞誉。他们整合了许多先进技术&#xff0c;包括Digital Ocean SSD云服务器、LiteSpe…

云计算任务调度仿真03

前面陆续分享了基于policy gradient和DQN实现的深度强化学习任务调度仿真&#xff0c;上次的DQN没有实现fix-qtarget和experience replay&#xff0c;这次再分享实现了这两个方法的DQN任务调度仿真。 经验重放&#xff0c;定义存储和存放次序&#xff0c;这里也可以自行修改 de…

提升测试效率,轻松并行运行测试——探秘Pytest插件pytest-xdist

在软件开发中&#xff0c;测试是确保代码质量的重要一环。然而&#xff0c;随着项目规模的增大&#xff0c;测试用例的数量也随之增多&#xff0c;测试的执行时间可能成为一个瓶颈。为了解决这个问题&#xff0c;Pytest提供了丰富的插件生态系统&#xff0c;其中 pytest-xdist …

[C#]调用tesseact-ocr的traineddata模型进行ocr文字识别

【框架地址】 https://github.com/charlesw/tesseract 【算法介绍】 Tesseract OCR是一个开源的光学字符识别引擎&#xff0c;它可以将图像中的文字转换成可编辑和可搜索的文本格式。Tesseract由惠普实验室于1985年开始开发&#xff0c;并在2005年被Google收购后成为了开源项…

api网关-kong

选型 api网关相关功能 服务的路由 动态路由负载均衡 服务发现 限流 熔断、降级 流量管理 黑白名单反爬策略 控制台&#xff1a;通过清晰的UI界面对网关集群进行各项配置。 集群管理&#xff1a;Goku网关节点是无状态的&#xff0c;配置信息自动同步&#xff0c;支持节点水…