第6章 支持向量机

SVM(Support Vector Machine, 支持向量机)有很多实现,但是本章其中最流行的一种实现,即序列最小优化(Sequence Minimal Optimization, SMO)算法。
最小优化(Sequence Minimal Optimization, SMO)算法 一种求解支持向量机二次规划的算法。

6.1 基于最大间隔分隔数据

支持向量机
优点:泛化错误率低,计算开销不大,结果易解释。
缺点:对参数调节和核函数的选择敏感,原始分类器不加修改仅使用于处理二类问题。
使用数据类型:数值型和标称型数据。

线性可分(linearly separable):
两类点被一条直线完全分开
数学定义:
D 0 D_0 D0 D 1 D_1 D1 n n n维度欧氏空间中的两个点集。如果存在 n n n维向量 w ⃗ \vec w w 和实数 b b b,使得所有属于 D 0 D_0 D0的点 x i x_i xi都有 w x i + b > 0 wx_i + b > 0 wxi+b>0,而对于所有属于 D 1 D_1 D1的点 x j x_j xj则有 w x i + b < 0 wx_i + b < 0 wxi+b<0,则我们称 D 0 D_0 D0 D 1 D_1 D1线性可分。

分割超平面(seqarating hyperplane):
数据集分割开来的直线

超平面(hyperplane):
n维欧氏空间中余维度等于一的线性子空间,也就是必须是(n-1)维度。也就是分类的决策边界。

间隔(margin):
点到分割面的距离。

支持向量(support vector):
离分割超平面最近的那些点。

6.2 寻找最大间隔

分隔超平面的形式可以写成 w T x + b \textbf {w}^T \textbf {x} + b wTx+b
要计算A到分割超平面的距离,就必须给出点到分隔面的法线或垂线的长度,该值为 ∣ w T x + b ∣ / ∥ w ∥ |\textbf {w}^T \textbf {x} + b| / \Vert{\textbf {w}\Vert} wTx+b∣/∥w

6.2.1 分类器求解的优化问题

6.2.2 SVM应用的一般框架

SVM的一般流程:

  1. 收集数据:可以使用任意方法。
  2. 准备数据:需要数值型数据。
  3. 分析数据:有助于可视化分隔超平面。
  4. 训练算法:SVM的大部分时间都源自于训练,该过程主要实现两个参数的调优。
  5. 测试算法:十分简单的计算过程就可以实现。
  6. 使用算法:几乎所有分类问题都可以使用SVM,值得一提的是,SVM本身是一个二类分类器,对多分类问题应用SVM需要对代码做一些修改。

6.3 SMO高效优化算法

6.3.1 Platt的SMO算法

SMO用于训练SVM。SMO表示序列最小优化(Sequence Minimal Optimization)。
SMO算法是将最大优化问题分解为多个小优化问题来求解的。
SMO算法的工作原理是:每次循环中选择两个alpha进行优化处理。一旦找到一对合适的alpha,那么就增大其中一个同时减小另一个。
这里所谓的‘合适’就是指两个alpha必须要符合一定的条件,条件之一就是这两个alpha必须要在间隔边界之外,而其第二个条件则是这两alpha还没进行过区间化处理或者不在边界上。

6.3.2 应用简化版SMO算法处理小规模数据集

SMO算法中的辅助函数:

    import randomdef loadDataSet(fileName):dataMat = []labelMat = []fr = open(fileName)for line in fr.readlines():lineArr = line.strip().split('\t')dataMat.append([float(lineArr[0]), float(lineArr[1])])labelMat.append(float(lineArr[2]))return dataMat, labelMatdef selectJrand(i, m):''':param i: alpha的下标:param m: 所有alpha的数目:return:'''j = iwhile(j == i):j = int(random.uniform(0, m))return jdef clipAlpha(aj, H, L):'''用于调整大于H或小于L的alpha值:param aj::param H::param L::return:'''if aj > H:aj = Hif L > aj:aj = Lreturn ajif __name__ == '__main__':dataArr, labelArr = loadDataSet('./resource/testSet.txt')print(dataArr)print(labelArr)

该SMO函数的伪代码大致如下:

创建一个alpha向量并将其初始化为0向量
当迭代次数小于最大迭代次数时(外循环)对数据集中的每个数据向量(内循环):如果该数据向量可以被优化:随机选择另外一个数据向量同时优化这两个向量如果两个向量都不能被优化,退出内循环
如果所有向量都没被优化,增加迭代数目,继续下一次循环.

简化版SMO算法:

def smoSimple(dataMatIn, classLabels, C, toler, maxIter):''':param dataMatIn: 数据集:param classLabels: 类别标签:param C: 常数C:param toler: 容错率:param maxIter: 退出前最大的循环次数:return:'''## 将输入转换成NumPy矩阵dataMatrix = mat(dataMatIn);labelMat = mat(classLabels).transpose()b = 0;m, n = shape(dataMatrix)alphas = mat(zeros((m, 1)))iter = 0while (iter < maxIter):alphaPairsChanged = 0for i in range(m):fXi = float(multiply(alphas, labelMat).T * (dataMatrix * dataMatrix[i, :].T)) + bEi = fXi - float(labelMat[i])  # if checks if an example violates KKT conditionsif ((labelMat[i] * Ei < -toler) and (alphas[i] < C)) or ((labelMat[i] * Ei > toler) and (alphas[i] > 0)):j = selectJrand(i, m)fXj = float(multiply(alphas, labelMat).T * (dataMatrix * dataMatrix[j, :].T)) + bEj = fXj - float(labelMat[j])alphaIold = alphas[i].copy();alphaJold = alphas[j].copy();if (labelMat[i] != labelMat[j]):L = max(0, alphas[j] - alphas[i])H = min(C, C + alphas[j] - alphas[i])else:L = max(0, alphas[j] + alphas[i] - C)H = min(C, alphas[j] + alphas[i])if L == H: print("L == H"); continueeta = 2.0 * dataMatrix[i, :] * dataMatrix[j, :].T - \dataMatrix[i, :] * dataMatrix[i, :].T - dataMatrix[j, :] * dataMatrix[j, :].Tif eta >= 0: print("eta >= 0"); continuealphas[j] -= labelMat[j] * (Ei - Ej) / etaalphas[j] = clipAlpha(alphas[j], H, L)if (abs(alphas[j] - alphaJold) < 0.00001): print("j not moving enough"); continuealphas[i] += labelMat[j] * labelMat[i] * (alphaJold - alphas[j])  # update i by the same amount as j# the update is in the oppostie directionb1 = b - Ei - labelMat[i] * (alphas[i] - alphaIold) * dataMatrix[i, :] * dataMatrix[i, :].T - labelMat[j] * (alphas[j] - alphaJold) * dataMatrix[i, :] * dataMatrix[j, :].Tb2 = b - Ej - labelMat[i] * (alphas[i] - alphaIold) * dataMatrix[i, :] * dataMatrix[j, :].T - labelMat[j] * (alphas[j] - alphaJold) * dataMatrix[j, :] * dataMatrix[j, :].Tif (0 < alphas[i]) and (C > alphas[i]):b = b1elif (0 < alphas[j]) and (C > alphas[j]):b = b2else:b = (b1 + b2) / 2.0alphaPairsChanged += 1print("iter: %d i:%d, pairs changed %d" % (iter, i, alphaPairsChanged))if (alphaPairsChanged == 0):iter += 1else:iter = 0print("iteration number: %d" % iter)return b, alphasif __name__ == '__main__':dataArr, labelArr = loadDataSet('./resource/testSet.txt')b, alphas = smoSimple(dataArr, labelArr, 0.6, 0.001, 40)print(b)print(alphas[alphas > 0])print(shape(alphas[alphas > 0]))

6.4 利用完整Platt SMO算法加速优化

完整版Platt SMO的支持函数:

class optStructK:def __init__(self,dataMatIn, classLabels, C, toler):  # Initialize the structure with the parameters self.X = dataMatInself.labelMat = classLabelsself.C = Cself.tol = tolerself.m = shape(dataMatIn)[0]self.alphas = mat(zeros((self.m,1)))self.b = 0self.eCache = mat(zeros((self.m,2))) #first column is valid flagdef calcEk(oS, k):fXk = float(multiply(oS.alphas, oS.labelMat).T * oS.K[:, k] + oS.b)Ek = fXk - float(oS.labelMat[k])return Ekdef selectJ(i, oS, Ei):         #this is the second choice -heurstic, and calcs EjmaxK = -1; maxDeltaE = 0; Ej = 0oS.eCache[i] = [1,Ei]  #set valid #choose the alpha that gives the maximum delta EvalidEcacheList = nonzero(oS.eCache[:,0].A)[0]if (len(validEcacheList)) > 1:for k in validEcacheList:   #loop through valid Ecache values and find the one that maximizes delta Eif k == i: continue #don't calc for i, waste of timeEk = calcEk(oS, k)deltaE = abs(Ei - Ek)if (deltaE > maxDeltaE):maxK = k; maxDeltaE = deltaE; Ej = Ekreturn maxK, Ejelse:   #in this case (first time around) we don't have any valid eCache valuesj = selectJrand(i, oS.m)Ej = calcEk(oS, j)return j, Ej

完整Platt SMO算法中的优化例程:

def innerL(i, oS):Ei = calcEk(oS, i)if ((oS.labelMat[i]*Ei < -oS.tol) and (oS.alphas[i] < oS.C)) or ((oS.labelMat[i]*Ei > oS.tol) and (oS.alphas[i] > 0)):j,Ej = selectJ(i, oS, Ei) #this has been changed from selectJrandalphaIold = oS.alphas[i].copy(); alphaJold = oS.alphas[j].copy();if (oS.labelMat[i] != oS.labelMat[j]):L = max(0, oS.alphas[j] - oS.alphas[i])H = min(oS.C, oS.C + oS.alphas[j] - oS.alphas[i])else:L = max(0, oS.alphas[j] + oS.alphas[i] - oS.C)H = min(oS.C, oS.alphas[j] + oS.alphas[i])if L==H: print("L==H"); return 0eta = 2.0 * oS.K[i,j] - oS.K[i,i] - oS.K[j,j] #changed for kernelif eta >= 0: print("eta>=0"); return 0oS.alphas[j] -= oS.labelMat[j]*(Ei - Ej)/etaoS.alphas[j] = clipAlpha(oS.alphas[j],H,L)updateEk(oS, j) #added this for the Ecacheif (abs(oS.alphas[j] - alphaJold) < 0.00001): print("j not moving enough"); return 0oS.alphas[i] += oS.labelMat[j]*oS.labelMat[i]*(alphaJold - oS.alphas[j])#update i by the same amount as jupdateEk(oS, i) #added this for the Ecache                    #the update is in the oppostie directionb1 = oS.b - Ei- oS.labelMat[i]*(oS.alphas[i]-alphaIold)*oS.K[i,i] - oS.labelMat[j]*(oS.alphas[j]-alphaJold)*oS.K[i,j]b2 = oS.b - Ej- oS.labelMat[i]*(oS.alphas[i]-alphaIold)*oS.K[i,j]- oS.labelMat[j]*(oS.alphas[j]-alphaJold)*oS.K[j,j]if (0 < oS.alphas[i]) and (oS.C > oS.alphas[i]): oS.b = b1elif (0 < oS.alphas[j]) and (oS.C > oS.alphas[j]): oS.b = b2else: oS.b = (b1 + b2)/2.0return 1else: return 0

完整版Platt SMO的外循环代码:

def smoP(dataMatIn, classLabels, C, toler, maxIter, kTup=('lin', 0)):  # full Platt SMOoS = optStruct(mat(dataMatIn), mat(classLabels).transpose(), C, toler, kTup)iter = 0entireSet = True;alphaPairsChanged = 0while (iter < maxIter) and ((alphaPairsChanged > 0) or (entireSet)):alphaPairsChanged = 0if entireSet:  # go over allfor i in range(oS.m):alphaPairsChanged += innerL(i, oS)print("fullSet, iter: %d i:%d, pairs changed %d" % (iter, i, alphaPairsChanged))iter += 1else:  # go over non-bound (railed) alphasnonBoundIs = nonzero((oS.alphas.A > 0) * (oS.alphas.A < C))[0]for i in nonBoundIs:alphaPairsChanged += innerL(i, oS)print("non-bound, iter: %d i:%d, pairs changed %d" % (iter, i, alphaPairsChanged))iter += 1if entireSet:entireSet = False  # toggle entire set loopelif (alphaPairsChanged == 0):entireSet = Trueprint("iteration number: %d" % iter)return oS.b, oS.alphasif __name__ == '__main__':dataArr, labelArr = loadDataSet('./resource/testSet.txt')b, alphas = smoP(dataArr, labelArr, 0.6, 0.001, 0.4)print(b)print(alphas[alphas > 0])print(shape(alphas[alphas > 0]))

实现分类:

def calcWs(alphas, dataArr, classLabels):X = mat(dataArr);labelMat = mat(classLabels).transpose()m, n = shape(X)w = zeros((n, 1))for i in range(m):w += multiply(alphas[i] * labelMat[i], X[i, :].T)return wif __name__ == '__main__':dataArr, labelArr = loadDataSet('./resource/testSet.txt')b, alphas = smoP(dataArr, labelArr, 0.6, 0.001, 0.4)ws = calcWs(alphas, dataArr, labelArr)dataMat = mat(dataArr)print(ws)print(dataMat[0] * mat(ws) + b)

6.5 在复杂数据上应用核函数

6.5.1 利用核函数将数据映射到高维空间

从某个特征空间到另外一个特征空间的映射是通过核函数来实现的。
核函数想象成一个包装器(wrapper)或者接口(interface),它能把数据从某个很难处理的形式转换成为另一个较容易的处理的形式。

6.5.2 径向基核函数

径向基函数:一个采用向量作为自变量的函数,能够基于向量距离运算输出一个标量。
径向基函数的高斯版本:
k ( x , y ) = e x p ( − ∥ x − y ∥ 2 2 α 2 ) k(x, y) = exp(\frac {-\Vert x- y \Vert^2} {2 \alpha ^2}) k(x,y)=exp(2α2xy2)

其中, α \alpha α是用户定义的用于确定到达率(reach)或者说函数值跌落到0的速度参数。

核转换函数:

def kernelTrans(X, A, kTup):  # calc the kernel or transform data to a higher dimensional spacem, n = shape(X)K = mat(zeros((m, 1)))if kTup[0] == 'lin':K = X * A.T  # linear kernelelif kTup[0] == 'rbf':for j in range(m):deltaRow = X[j, :] - AK[j] = deltaRow * deltaRow.TK = exp(K / (-1 * kTup[1] ** 2))  # divide in NumPy is element-wise not matrix like Matlabelse:raise NameError('Houston We Have a Problem -- \That Kernel is not recognized')return Kclass optStruct:def __init__(self,dataMatIn, classLabels, C, toler, kTup):  # Initialize the structure with the parameters self.X = dataMatInself.labelMat = classLabelsself.C = Cself.tol = tolerself.m = shape(dataMatIn)[0]self.alphas = mat(zeros((self.m,1)))self.b = 0self.eCache = mat(zeros((self.m,2))) #first column is valid flagself.K = mat(zeros((self.m,self.m)))for i in range(self.m):self.K[:,i] = kernelTrans(self.X, self.X[i,:], kTup)

6.5.3在测试中使用核函数:

利用核函数进行分类的径向基测试函数:

def testRbf(k1=1.3):dataArr,labelArr = loadDataSet('./resource/testSetRBF.txt')b,alphas = smoP(dataArr, labelArr, 200, 0.0001, 10000, ('rbf', k1)) #C=200 importantdatMat=mat(dataArr); labelMat = mat(labelArr).transpose()svInd=nonzero(alphas.A>0)[0]sVs=datMat[svInd] #get matrix of only support vectorslabelSV = labelMat[svInd];print("there are %d Support Vectors" % shape(sVs)[0])m,n = shape(datMat)errorCount = 0for i in range(m):kernelEval = kernelTrans(sVs,datMat[i,:],('rbf', k1))predict=kernelEval.T * multiply(labelSV,alphas[svInd]) + bif sign(predict)!=sign(labelArr[i]): errorCount += 1print("the training error rate is: %f" % (float(errorCount)/m))dataArr,labelArr = loadDataSet('./resource/testSetRBF2.txt')errorCount = 0datMat=mat(dataArr); labelMat = mat(labelArr).transpose()m,n = shape(datMat)for i in range(m):kernelEval = kernelTrans(sVs,datMat[i,:],('rbf', k1))predict=kernelEval.T * multiply(labelSV,alphas[svInd]) + bif sign(predict)!=sign(labelArr[i]): errorCount += 1print("the test error rate is: %f" % (float(errorCount)/m))

6.6 示例:手写识别问题回顾

示例:基于SVM的数字识别:

  1. 收集数据:提供的文本。
  2. 准备数据:基于二值图像构造向量。
  3. 分析数据:对图像向量进行目测。
  4. 训练算法:采用两种不同的核函数,并对径向基核函数采用不同的的设置来运行SMO算法。
  5. 测试算法:编写一个测试函数来测试不同的核函数并计算错误率。
  6. 使用算法:一个图像识别的完整应用含需要一些图像处理的知识,这里并不打算深入介绍。

基于SVM的手写数字识别:

def loadImages(dirName):from os import listdirhwLabels = []trainingFileList = listdir(dirName)           #load the training setm = len(trainingFileList)trainingMat = zeros((m,1024))for i in range(m):fileNameStr = trainingFileList[i]fileStr = fileNameStr.split('.')[0]     #take off .txtclassNumStr = int(fileStr.split('_')[0])if classNumStr == 9: hwLabels.append(-1)else: hwLabels.append(1)trainingMat[i,:] = img2vector('%s/%s' % (dirName, fileNameStr))return trainingMat, hwLabelsdef testDigits(kTup=('rbf', 10)):dataArr,labelArr = loadImages('./resource/trainingDigits')b,alphas = smoP(dataArr, labelArr, 200, 0.0001, 10000, kTup)datMat=mat(dataArr); labelMat = mat(labelArr).transpose()svInd=nonzero(alphas.A>0)[0]sVs=datMat[svInd]labelSV = labelMat[svInd];print("there are %d Support Vectors" % shape(sVs)[0])m,n = shape(datMat)errorCount = 0for i in range(m):kernelEval = kernelTrans(sVs,datMat[i,:],kTup)predict=kernelEval.T * multiply(labelSV,alphas[svInd]) + bif sign(predict)!=sign(labelArr[i]): errorCount += 1print("the training error rate is: %f" % (float(errorCount)/m))dataArr,labelArr = loadImages('./resource/testDigits')errorCount = 0datMat=mat(dataArr); labelMat = mat(labelArr).transpose()m,n = shape(datMat)for i in range(m):kernelEval = kernelTrans(sVs,datMat[i,:],kTup)predict=kernelEval.T * multiply(labelSV,alphas[svInd]) + bif sign(predict)!=sign(labelArr[i]): errorCount += 1print("the test error rate is: %f" % (float(errorCount)/m))if __name__ == '__main__':testDigits(('rbf', 20))

6.7 本章小结

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

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

相关文章

PDF批量加水印 与 去除水印实践

本文主要目标是尝试去除水印&#xff0c;但是为了准备测试数据&#xff0c;我们需要先准备好有水印的pdf测试文件。 注意&#xff1a;本文的去水印只针对文字悬浮图片悬浮两种特殊情况&#xff0c;即使是这两种情况也不代表一定都可以去除水印。 文章目录 批量添加透明图片水印…

Pspark从hive读数据写到Pgsql数据库

前提条件 要使用PySpark从Hive读取数据并写入到PostgreSQL数据库&#xff0c;你需要确保以下几点&#xff1a; 你的PySpark环境已经配置好&#xff0c;并且能够连接到你的Hive数据。 PostgreSQL JDBC驱动程序已经添加到你的PySpark环境中。 你已经在PostgreSQL中创建好了相应…

【Web API DOM10】日期(时间)对象

一&#xff1a;实例化 1 获取系统当前时间即创建日期对象 const date new Date() console.log(date) 2024年6月5日周三 2 获取指定的时间 以获取2025年6月29日为例 const date new Date(2025-6-29) console.log(date) 二&#xff1a;日期对象方法 1 使用场景&#xf…

关于信号翻转模块(sig_flag_mod)的实现

关于信号翻转模块(sig_flag_mod)的实现 语言 &#xff1a;Verilg HDL 、VHDL EDA工具&#xff1a;ISE、Vivado、Quartus II 关于信号翻转模块(sig_flag_mod)的实现一、引言二、实现信号翻转模块的方法&#xff08;1&#xff09;输入接口&#xff08;2&#xff09;输出接口&…

新手学习编程网站一站式合集

LTPP在线开发平台 探索编程世界的新天地&#xff0c;为学生和开发者精心打造的编程平台&#xff0c;现已盛大开启&#xff01;这个平台汇集了近4000道精心设计的编程题目&#xff0c;覆盖了C、C、JavaScript、TypeScript、Go、Rust、PHP、Java、Ruby、Python3以及C#等众多编程语…

力扣904.水果成篮

力扣904.水果成篮 哈希表记录水果种类 超过两个就把之前的去了 class Solution {public:int totalFruit(vector<int>& fruits) {int res0,n fruits.size();unordered_map<int,int> cnt;for(int i0,j0;i<n;i){cnt[fruits[i]] ;while(cnt.size() > 2){…

【javaEE初阶】

&#x1f308;&#x1f308;&#x1f308;关于java ⚡⚡⚡java的由来 我们这篇文章主要是来介绍javaEE&#xff0c;一般称为java企业版&#xff0c;实际上java的历史可以追溯到上个世纪90年代&#xff0c;当时主要的语言主流的还是C语言和C&#xff0c;但是在那个时期嵌入式初…

小熊家务帮day13-day14 门户管理(ES搜索,Canal+MQ同步,索引同步)

目录 1 服务搜索1.1 需求分析1.2 技术方案1.2.1 使用Elasticsearch进行全文检索&#xff08;为什么数据没有那么多还要用ES&#xff1f;&#xff09;1.2.2 索引同步方案1.2.2.1 Canal介绍1.2.2.1 Canal工作原理 1 服务搜索 1.1 需求分析 服务搜索的入口有两处&#xff1a; 在…

c# 学习 2

常量 转义字符 类型转换

深入对比:Transformer与LSTM的详细解析

在深度学习和自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;Transformer和长短时记忆网络&#xff08;LSTM&#xff09;是两个备受瞩目的模型。它们各自拥有独特的优势&#xff0c;并在不同的任务中发挥着重要作用。本文将对这两种模型进行详细对比&#xff0c;帮助…

Java 基础面试300题 (231-260)

Java 基础面试300题 &#xff08;231-260&#xff09; 231 String::toUpperCase是什么类型的方法引用&#xff1f; String::toUpperCase是任意方法引用的示例。它指的是String 类的toUpperCase方法&#xff0c;但不是指任何特定对象。 通常在遍历集合或流时使用。例如&#x…

强化训练:day12(删除公共字符、两个链表的第一个公共结点、mari和shiny)

文章目录 前言1. 删除公共字符1.1 题目描述1.2 解题思路1.3 代码实现 2. 两个链表的第一个公共结点2.1 题目描述2.2 解题思路2.3 代码实现 3. mari和shiny3.1 题目描述3.2 解题思路3.3 代码实现 总结 前言 1. 删除公共字符   2. 两个链表的第一个公共结点   3. mari和shiny…

编译原理总结

编译器构成 1. 前端分析部分 1.1 词法分析 确定词性&#xff0c;输出为token序列 1.2 语法分析 识别短语 1.3 语义分析 分析短语在句子中的成分 IR中间代码生成 2. 机器无关代码优化 3. 后端综合部分 目标代码生成 机器相关代码优化 4. 其他 全局信息表 异常输出

一个思维狂赚20万+?揭秘电商平台隐藏的流量认知!

你想要的流量&#xff0c;资源&#xff0c;人脉&#xff0c;都已经有人为你准备&#xff0c;你只需要找到拥有这些资源的人。对于流量和信息&#xff0c;也是一样&#xff0c;你想找的客户和产品&#xff0c;都已经有人为你准备在淘宝、拼多多等电商平台&#xff0c;你只需要找…

IO流,文件操作

参考 Java IO 基础知识总结 | JavaGuide 史上最骚最全最详细的IO流教程&#xff0c;没有之一&#xff01; - 宜春 - 博客园 零、io-流简介 IO 即 Input/Output&#xff0c;输入和输出。数据输入到计算机内存的过程即输入&#xff0c;反之输出到外部存储&#xff08;比如数据…

2024年OceanBase数据库中级培训课程

课程概述 本课程主要讲解 OceanBase 的高级特性&#xff08;全局索引、全局数据一致性、负载均衡策略、SQL 引擎优化&#xff09;&#xff0c;以及 OceanBase 内存构成、内存数据落盘策略和 HTAP 等知识&#xff0c;同时提供了进阶实验课程。通过培训&#xff0c;学员将深入了…

[沫忘录]MySQL InnoDB引擎

[沫忘录]MySQL InnoDB引擎 逻辑存储结构 InnoDB采用 “表、段&#xff0c;区&#xff0c; 页、行” 这样的层级结构进行存储。 **表空间(tablespace)**ibd文件&#xff0c;主要用于存储记录、索引等数据&#xff0c;一个mysql实例可有多个表空间&#xff0c;甚至能通过innodb…

【机器学习】深度探索:从基础概念到深度学习关键技术的全面解析——梯度下降、激活函数、正则化与批量归一化

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、机器学习的基本概念与原理二、深度学习与机器学习的关系2.1 概念层次的关系2.2 技术特点差异2.3 机器学习示例&#xff1a;线性回归&#xff08;使用Python和scikit-learn库&#xff09;2.4 深度学习示例&#xff1a;简…

Cookie,Session与Token解析

前言 在进行用户的授权认证时主要可以有三种方式&#xff0c;分别是Cookie&#xff0c;Session与Token&#xff0c;本文将对它们进行简要的介绍并总结他们三者之间的区别。 Cookie 首先&#xff0c;什么是Cookie? 简而言之&#xff0c;Cookie就是是一些数据&#xff0c;类型…

在cmd菜单中使用自定义命令通过bat和powershell命令调用翻译API

先说一个血淋淋的结果&#xff0c;这个小功能其实在github已经有大佬帮我们封装好了&#xff0c;我也是自己刚倒腾好之后才发现的&#xff0c;所以如果只是需要这个功能的朋友可以直接移步这个项目&#xff1a;https://github.com/kenshinji/yddict&#xff0c;自己电脑安装一个…