主动学习简单教程及代码示例

article/2025/8/29 13:16:19

本文是这篇文章的(翻译)简化版。

本文代码地址

已经不止一次有人说代码地址打不开,但是每次我都打得开。。这里放个阿里云的地址吧Active_Learning_Tutorial.ipynb。需要的去阿里云下载文件就行了。

建议直接看代码地址(代码地址包含了本文全部内容)

文章目录

  • 主动学习教程(与代码框架)
    • 主动学习简介
    • 主动学习分类
    • 主动学习代码框架
      • 导入使用的库
      • 数据集
      • 模型
      • 训练
      • 样本挑选
      • 正则化
      • 用于第一次训练的K个随机样本
      • 整个流程
      • 运行代码
      • 不同模型结果对比
      • 不同样本挑选方式结果对比

主动学习教程(与代码框架)

主动学习简介

  众所周知这是个大数据时代,我们可以从许多来源(如学术和贸易机构)获取到大量的未标记数据。未标记数据相对来说是可以廉价获取的,然而标记数据却是昂贵的,许多公司雇佣相关专家或志愿者来为数据打标签[1](如医学图像)。对于众多的小型AI机构而言,标记数据的代价往往是难以忍受的,此时主动学习就能派上用场了。
需要注意下面几点:

  1. AL实际上是一种策略而非算法(是逐渐增加数据量来训练模型的过程)
  2. AL建立的基础在于“数据量和信息量不成正比”这一基本现象
  3. 可以认为AL的优势在于得到更好的学习曲线(learning curves"
  4. 数据标签难以获取(且难度不同),打标签代价较大且消耗时间

主动学习分类

  按照标签查询方式的不同,可将AL分为三类

  1. Membership query synthesis
  2. Stream-Based selective sampling
  3. Pool-Based sampling[2]

  许多主动学习工作都是基于池的(Pool-Based sampling),下面简单介绍基于池的主动学习流程

  1. Divide the data to a ‘pool’ and a test-set
  2. Select ‘k’ samples from the pool for the initial train-set and label them, the remaining data will be the validation-set
  3. Normalize all the sets
  4. Train the Model using the train-set, with balanced weights.
  5. Use the trained model with the validation-set, get probabilities per sample.
  6. Use the trained model with the test-set, get performance measures.
  7. Select ‘k’ most-informative samples based on per-sample-probabilities, i.e., those that the model was most uncertain about regarding their labelling.
  8. Move these ‘k’ samples from the validation set to the train-set and query their labels.
  9. Inverse normalization for all the data-sets
  10. Stop according to the stop criterion, otherwise go to 3.

主动学习代码框架

导入使用的库

import os
import time
import json
import pickle
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
from scipy import stats
from pylab import rcParams
from sklearn.utils import check_random_state
from sklearn.datasets import load_digits
from sklearn.datasets import fetch_openml
from sklearn.decomposition import PCA
from sklearn.preprocessing import scale
from sklearn.preprocessing import MinMaxScaler
from sklearn.cluster import KMeans
from sklearn.mixture import GaussianMixture
from sklearn.svm import LinearSVC, SVC
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import LogisticRegression
from sklearn import metrics
from sklearn.metrics import pairwise_distances_argmin_min
from sklearn.metrics import confusion_matrix
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import average_precision_score
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier, \GradientBoostingClassifiermax_queried = 500

数据集

  使用著名的基本数据集MNIST,采取60k/10k的划分方法。

trainset_size = 60000  # ie., testset_size = 10000def download():mnist = fetch_openml('mnist_784')X = mnist.data.astype('float64')y = mnist.targetprint ('MNIST:', X.shape, y.shape)return (X, y)def split(train_size):X_train_full = X[:train_size]y_train_full = y[:train_size]X_test = X[train_size:]y_test = y[train_size:]return (X_train_full, y_train_full, X_test, y_test)

模型

  先构造一个基本类,所用模型包括SVM, logistic regression, random forest and gradient boosting.

class BaseModel(object):def __init__(self):passdef fit_predict(self):passclass SvmModel(BaseModel):model_type = 'Support Vector Machine with linear Kernel'def fit_predict(self, X_train, y_train, X_val, X_test, c_weight):print ('training svm...')self.classifier = SVC(C=1, kernel='linear', probability=True,class_weight=c_weight)self.classifier.fit(X_train, y_train)self.test_y_predicted = self.classifier.predict(X_test)self.val_y_predicted = self.classifier.predict(X_val)return (X_train, X_val, X_test, self.val_y_predicted,self.test_y_predicted)class LogModel(BaseModel):model_type = 'Multinominal Logistic Regression' def fit_predict(self, X_train, y_train, X_val, X_test, c_weight):print ('training multinomial logistic regression')train_samples = X_train.shape[0]self.classifier = LogisticRegression(C=50. / train_samples,multi_class='multinomial',penalty='l1',solver='saga',tol=0.1,class_weight=c_weight,)self.classifier.fit(X_train, y_train)self.test_y_predicted = self.classifier.predict(X_test)self.val_y_predicted = self.classifier.predict(X_val)return (X_train, X_val, X_test, self.val_y_predicted,self.test_y_predicted)class RfModel(BaseModel):model_type = 'Random Forest'def fit_predict(self, X_train, y_train, X_val, X_test, c_weight):print ('training random forest...')self.classifier = RandomForestClassifier(n_estimators=500, class_weight=c_weight)self.classifier.fit(X_train, y_train)self.test_y_predicted = self.classifier.predict(X_test)self.val_y_predicted = self.classifier.predict(X_val)return (X_train, X_val, X_test, self.val_y_predicted, self.test_y_predicted)

训练

class TrainModel:def __init__(self, model_object):        self.accuracies = []self.model_object = model_object()        def print_model_type(self):print (self.model_object.model_type)# we train normally and get probabilities for the validation set. i.e., we use the probabilities to select the most uncertain samplesdef train(self, X_train, y_train, X_val, X_test, c_weight):print ('Train set:', X_train.shape, 'y:', y_train.shape)print ('Val   set:', X_val.shape)print ('Test  set:', X_test.shape)t0 = time.time()(X_train, X_val, X_test, self.val_y_predicted,self.test_y_predicted) = \self.model_object.fit_predict(X_train, y_train, X_val, X_test, c_weight)self.run_time = time.time() - t0return (X_train, X_val, X_test)  # we return them in case we use PCA, with all the other algorithms, this is not needed.# we want accuracy only for the test setdef get_test_accuracy(self, i, y_test):classif_rate = np.mean(self.test_y_predicted.ravel() == y_test.ravel()) * 100self.accuracies.append(classif_rate)               print('--------------------------------')print('Iteration:',i)print('--------------------------------')print('y-test set:',y_test.shape)print('Example run in %.3f s' % self.run_time,'\n')print("Accuracy rate for %f " % (classif_rate))    print("Classification report for classifier %s:\n%s\n" % (self.model_object.classifier, metrics.classification_report(y_test, self.test_y_predicted)))print("Confusion matrix:\n%s" % metrics.confusion_matrix(y_test, self.test_y_predicted))print('--------------------------------')

样本挑选

class BaseSelectionFunction(object):def __init__(self):passdef select(self):passclass RandomSelection(BaseSelectionFunction):@staticmethoddef select(probas_val, initial_labeled_samples):random_state = check_random_state(0)selection = np.random.choice(probas_val.shape[0], initial_labeled_samples, replace=False)#     print('uniques chosen:',np.unique(selection).shape[0],'<= should be equal to:',initial_labeled_samples)return selectionclass EntropySelection(BaseSelectionFunction):@staticmethoddef select(probas_val, initial_labeled_samples):e = (-probas_val * np.log2(probas_val)).sum(axis=1)selection = (np.argsort(e)[::-1])[:initial_labeled_samples]return selectionclass MarginSamplingSelection(BaseSelectionFunction):@staticmethoddef select(probas_val, initial_labeled_samples):rev = np.sort(probas_val, axis=1)[:, ::-1]values = rev[:, 0] - rev[:, 1]selection = np.argsort(values)[:initial_labeled_samples]return selection

正则化

class Normalize(object):def normalize(self, X_train, X_val, X_test):self.scaler = MinMaxScaler()X_train = self.scaler.fit_transform(X_train)X_val   = self.scaler.transform(X_val)X_test  = self.scaler.transform(X_test)return (X_train, X_val, X_test) def inverse(self, X_train, X_val, X_test):X_train = self.scaler.inverse_transform(X_train)X_val   = self.scaler.inverse_transform(X_val)X_test  = self.scaler.inverse_transform(X_test)return (X_train, X_val, X_test) 

用于第一次训练的K个随机样本

def get_k_random_samples(initial_labeled_samples, X_train_full,y_train_full):random_state = check_random_state(0)permutation = np.random.choice(trainset_size,initial_labeled_samples,replace=False)print ()print ('initial random chosen samples', permutation.shape),
#            permutation)X_train = X_train_full[permutation]y_train = y_train_full[permutation]X_train = X_train.reshape((X_train.shape[0], -1))bin_count = np.bincount(y_train.astype('int64'))unique = np.unique(y_train.astype('int64'))print ('initial train set:',X_train.shape,y_train.shape,'unique(labels):',bin_count,unique,)return (permutation, X_train, y_train)

整个流程

实现主动学习流程

class TheAlgorithm(object):accuracies = []def __init__(self, initial_labeled_samples, model_object, selection_function):self.initial_labeled_samples = initial_labeled_samplesself.model_object = model_objectself.sample_selection_function = selection_functiondef run(self, X_train_full, y_train_full, X_test, y_test):# initialize process by applying base learner to labeled training data set to obtain Classifier(permutation, X_train, y_train) = \get_k_random_samples(self.initial_labeled_samples,X_train_full, y_train_full)self.queried = self.initial_labeled_samplesself.samplecount = [self.initial_labeled_samples]# permutation, X_train, y_train = get_equally_k_random_samples(self.initial_labeled_samples,classes)# assign the val set the rest of the 'unlabelled' training dataX_val = np.array([])y_val = np.array([])X_val = np.copy(X_train_full)X_val = np.delete(X_val, permutation, axis=0)y_val = np.copy(y_train_full)y_val = np.delete(y_val, permutation, axis=0)print ('val set:', X_val.shape, y_val.shape, permutation.shape)print ()# normalize datanormalizer = Normalize()X_train, X_val, X_test = normalizer.normalize(X_train, X_val, X_test)   self.clf_model = TrainModel(self.model_object)(X_train, X_val, X_test) = self.clf_model.train(X_train, y_train, X_val, X_test, 'balanced')active_iteration = 1self.clf_model.get_test_accuracy(1, y_test)# fpfn = self.clf_model.test_y_predicted.ravel() != y_val.ravel()# print(fpfn)# self.fpfncount = []# self.fpfncount.append(fpfn.sum() / y_test.shape[0] * 100)while self.queried < max_queried:active_iteration += 1# get validation probabilitiesprobas_val = \self.clf_model.model_object.classifier.predict_proba(X_val)print ('val predicted:',self.clf_model.val_y_predicted.shape,self.clf_model.val_y_predicted)print ('probabilities:', probas_val.shape, '\n',np.argmax(probas_val, axis=1))# select samples using a selection functionuncertain_samples = \self.sample_selection_function.select(probas_val, self.initial_labeled_samples)# normalization needs to be inversed and recalculated based on the new train and test set.X_train, X_val, X_test = normalizer.inverse(X_train, X_val, X_test)   # get the uncertain samples from the validation setprint ('trainset before', X_train.shape, y_train.shape)X_train = np.concatenate((X_train, X_val[uncertain_samples]))y_train = np.concatenate((y_train, y_val[uncertain_samples]))print ('trainset after', X_train.shape, y_train.shape)self.samplecount.append(X_train.shape[0])bin_count = np.bincount(y_train.astype('int64'))unique = np.unique(y_train.astype('int64'))print ('updated train set:',X_train.shape,y_train.shape,'unique(labels):',bin_count,unique,)X_val = np.delete(X_val, uncertain_samples, axis=0)y_val = np.delete(y_val, uncertain_samples, axis=0)print ('val set:', X_val.shape, y_val.shape)print ()# normalize again after creating the 'new' train/test setsnormalizer = Normalize()X_train, X_val, X_test = normalizer.normalize(X_train, X_val, X_test)               self.queried += self.initial_labeled_samples(X_train, X_val, X_test) = self.clf_model.train(X_train, y_train, X_val, X_test, 'balanced')self.clf_model.get_test_accuracy(active_iteration, y_test)print ('final active learning accuracies',self.clf_model.accuracies)

运行代码

(X, y) = download()
(X_train_full, y_train_full, X_test, y_test) = split(trainset_size)
print ('train:', X_train_full.shape, y_train_full.shape)
print ('test :', X_test.shape, y_test.shape)
classes = len(np.unique(y))
print ('unique classes', classes)def pickle_save(fname, data):filehandler = open(fname,"wb")pickle.dump(data,filehandler)filehandler.close() print('saved', fname, os.getcwd(), os.listdir())def pickle_load(fname):print(os.getcwd(), os.listdir())file = open(fname,'rb')data = pickle.load(file)file.close()print(data)return datadef experiment(d, models, selection_functions, Ks, repeats, contfrom):algos_temp = []print ('stopping at:', max_queried)count = 0for model_object in models:if model_object.__name__ not in d:d[model_object.__name__] = {}for selection_function in selection_functions:if selection_function.__name__ not in d[model_object.__name__]:d[model_object.__name__][selection_function.__name__] = {}for k in Ks:d[model_object.__name__][selection_function.__name__][str(k)] = []           for i in range(0, repeats):count+=1if count >= contfrom:print ('Count = %s, using model = %s, selection_function = %s, k = %s, iteration = %s.' % (count, model_object.__name__, selection_function.__name__, k, i))alg = TheAlgorithm(k, model_object, selection_function)alg.run(X_train_full, y_train_full, X_test, y_test)d[model_object.__name__][selection_function.__name__][str(k)].append(alg.clf_model.accuracies)fname = 'Active-learning-experiment-' + str(count) + '.pkl'pickle_save(fname, d)if count % 5 == 0:print(json.dumps(d, indent=2, sort_keys=True))print ()print ('---------------------------- FINISHED ---------------------------')print ()return dmax_queried = 500 repeats = 1models = [SvmModel, RfModel, LogModel] selection_functions = [RandomSelection, MarginSamplingSelection, EntropySelection] Ks = [250,125,50,25,10] d = {}
stopped_at = -1 # print('directory dump including pickle files:', os.getcwd(), np.sort(os.listdir()))  
# d = pickle_load('Active-learning-experiment-' + str(stopped_at) + '.pkl')  
# print(json.dumps(d, indent=2, sort_keys=True))d = experiment(d, models, selection_functions, Ks, repeats, stopped_at+1)
print (d)
results = json.loads(json.dumps(d, indent=2, sort_keys=True))
print(results)

不同模型结果对比

通过对比发现随机森林是几种模型中最好的

def performance_plot(fully_supervised_accuracy, dic, models, selection_functions, Ks, repeats):  fig, ax = plt.subplots()ax.plot([0,500],[fully_supervised_accuracy, fully_supervised_accuracy],label = 'algorithm-upper-bound')for model_object in models:for selection_function in selection_functions:for idx, k in enumerate(Ks):x = np.arange(float(Ks[idx]), 500 + float(Ks[idx]), float(Ks[idx]))            Sum = np.array(dic[model_object][selection_function][k][0])for i in range(1, repeats):Sum = Sum + np.array(dic[model_object][selection_function][k][i])mean = Sum / repeatsax.plot(x, mean ,label = model_object + '-' + selection_function + '-' + str(k))ax.legend()ax.set_xlim([50,500])ax.set_ylim([40,100])ax.grid(True)plt.show()models_str = ['SvmModel', 'RfModel', 'LogModel']
selection_functions_str = ['RandomSelection', 'MarginSamplingSelection', 'EntropySelection']
Ks_str = ['250','125','50','25','10'] 
repeats = 1
random_forest_upper_bound = 97.
svm_upper_bound = 94.
log_upper_bound = 92.47
total_experiments = len(models_str) * len(selection_functions_str) * len(Ks_str) * repeatsprint('So which is the better model? under the stopping condition and hyper parameters - random forest is the winner!')
performance_plot(random_forest_upper_bound, d, ['RfModel'] , selection_functions_str    , Ks_str, 1)
performance_plot(svm_upper_bound, d, ['SvmModel'] , selection_functions_str    , Ks_str, 1)
performance_plot(log_upper_bound, d, ['LogModel'] , selection_functions_str    , Ks_str, 1)

在这里插入图片描述

不同样本挑选方式结果对比

通过对比,margin sampling是最好的样本挑选方式

print('So which is the best sample selection function? margin sampling is the winner!')
performance_plot(random_forest_upper_bound, d, ['RfModel'], selection_functions_str    , Ks_str, 1)
print()
print('So which is the best k? k=10 is the winner')
performance_plot(random_forest_upper_bound, d, ['RfModel'] , ['MarginSamplingSelection'], Ks_str, 1)

在这里插入图片描述

[1] Shay Yehezkel, High Dimensional Statistical Pr
ocess Control and Application, M.Sc Thesis.
[2] Stefan Hosein Active Learning: Curious AI Algorithms


http://chatgpt.dhexx.cn/article/eL1hnODm.shtml

相关文章

主动学习研究现状

主动学习研究现状 一. 传统查询策略&#xff08;Query Strategy&#xff09;二. 在图像分类的应用三. 在目标检测的研究3.1.《Localization-Aware Active Learning for Object Detection 》(ACCV, 2018)3.2. 《Active Learning for Deep Object Detection via Probabilistic Mo…

什么是主动学习?

机器学习算法特别需要数据&#xff0c;需要成千上万的例子才能做出明智的决定。为我们的算法提供高质量的训练数据是一项昂贵的任务。主动学习是一种优化构建有效机器学习系统所需人力的策略。 主动学习定义 主动学习是一种机器学习训练策略&#xff0c;它使算法能够主动识别…

Deep Active Learning(深度主动学习)

在深度学习时代&#xff0c;以监督学习为首的各项模型都取得了非常好的效果&#xff0c;但是这往往需要非常多的数据量来支撑。所以主动学习这一领域主要的目的就是为了让目标模型达到性能的前提下&#xff0c;尽可能的减少标准成本。 Active Learning&#xff08;主动学习&a…

主动学习入门

文章目录 1.介绍1.1 监督学习、半监督学习、非监督学习1.2 主动学习1.2.1 主动学习介绍1.2.2 主动学习与半监督学习异同1.2.3 主动学习流程 2. 基本思想2.1 图示2.2 策略 3. 算法3.1 基于流、基于池3.2 类别3.3 算法(这里只介绍基本的)3.3.1 基于不确定性3.3.2 多样性(一般与不…

主动学习(active learning)

背景 在现实应用场景中&#xff0c;训练一个有效的深度模型依赖大量已标注样本&#xff0c;而准确标注大规模数据往往耗时耗力且代价高昂。为降低模型对数据的依赖&#xff0c;相继提出无监督学习&#xff0c;半监督学习以及弱监督学习等领域的学习方法。在这些方法中&#xf…

主动学习(Active Learning,AL)综述

目录 1. 基本概念2. 基于不确定性的主动学习方法3.基于最近邻和支持向量的分类器的方法3.1 NNClassifier3.2 RBF network Gradient Penalty 4 基于特征空间覆盖的方法5 基于对抗学习的方法5.1 VAAL5.1.1 核心思想5.1.2 网络结构5.1.3 主动学习策略5.1.4 模型特点 5.2 SRAAL5.3…

主动学习(Active Learning) 概述、策略和不确定性度量

主动学习是指对需要标记的数据进行优先排序的过程&#xff0c;这样可以确定哪些数据对训练监督模型产生最大的影响。 主动学习是一种学习算法可以交互式查询用户(teacher 或 oracle)&#xff0c;用真实标签标注新数据点的策略。主动学习的过程也被称为优化实验设计。主动学习的…

主动学习(Active Learning,AL)的理解以及代码流程讲解

为什么要使用主动学习(Active Learning&#xff0c;AL) 针对有监督的学习任务&#xff0c;存在标记成本较为昂贵且标记难以大量获取的问题。 在此问题背景下&#xff0c;主动学习&#xff08;Active Learning, AL&#xff09;尝试通过选择性的标记较少数据而训练出表现较好的模…

主动学习(Active learning)简介

文章目录 Labeling faster vs. labeling smarter1. 什么是主动学习&#xff1f;2. 主动学习如何运行&#xff1f;2.1 Stream-based Active Learning2.2 Pool-based Active Learning2.3 Membership Query Synthesis 3. 主动学习与强化学习的不同&#xff1f;4. 不确定性度量1&am…

哪本书适合推荐给 Java 初学者?

之前写过一篇文章叫《假如时光倒流&#xff0c; 我会这么学习Java》&#xff0c; 希望对你有帮助&#xff1a; ----------------------------------------------------------------------- 回头看看&#xff0c; 我进入Java 领域已经快15个年头了&#xff0c; 虽然学的也一般…

Java程序员必看的20本书,从入门到精通!收藏

推荐的20本学习 Java 必看书&#xff0c;记得点收藏哈~ 基础核心 1、《Java核心技术卷2&#xff1a;高级特性&#xff08;原书第9版&#xff09;》 豆瓣评分: 8.7 推荐指数&#xff1a;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d; 2、《图解 HTTP》 讲漫画一样的…

Java入门到进阶推荐书籍

Java学习中推荐的书籍 第一本&#xff0c;《Head First JAVA》 小白学习JAVA的入门书籍&#xff0c;这本书和其他专业书籍相比多了一些趣味性&#xff0c;让人能够读下去&#xff0c;知识点比较全面&#xff0c;但是也没有讲的很深。 第二本&#xff0c;《JAVA核心技术卷1》 …

【书籍学习】史上最全的Java进阶书籍推荐

学习Java&#xff0c;书籍是必不可少的学习工具之一&#xff0c;尤其是对于自学者而言。废话不多说&#xff0c;下边就给大家推荐一些Java进阶的好书。 第一部分&#xff1a;Java语言篇 1.《Java编程规范》 适合对象&#xff1a;初级、中级 介绍&#xff1a;这本书的作者是被…

java 入门书籍(java7)

一、Java从入门到精通 《Java从入门到精通(第3版)》从初学者角度出发&#xff0c;通过通俗易懂的语言、丰富多彩的实例&#xff0c;详细介绍了使用Java语言进行程序开发需要掌握的知识。 《Java从入门到精通(第3版)》编辑推荐&#xff1a;“软件开发视频大讲堂”丛书系清华社…

Java从入门到进阶书单推荐|必收藏

关于Java从入门到进阶的书单推荐 一、入门基础类 如果是0基础学习&#xff0c;入门阶段千万不要选择太难的书&#xff0c;首先太难的你也看不懂&#xff0c;而且会打击信心&#xff0c;所以建议选择通俗易懂的就行&#xff0c;先领进门&#xff08;注意&#xff1a;基础一定要…

零基础学Java有哪些必看书?推荐这5本

零基础学Java初学者&#xff0c;想要入门&#xff0c;应该多看一些关于Java的书&#xff0c;先充实理论基础。然而Java的技术知识是海量的&#xff0c;市面上关于Java的书令人眼花缭乱&#xff0c;零基础的小白完全不知道该看哪本书。那么&#xff0c;零基础学Java有哪些必看书…

MySQL启动1053错误之解决方法

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。https://blog.csdn.net/qq_42680327 创建mysql服务时&#xff0c;系统已提示创建服务成功&#xff0c;但是net start mysql命令提示启动失败&#xff0c;并在services.msc中提示1053错误 解决办法1…

解决phpstudy mysql启动不了

之前的电脑上下了mysql&#xff0c;phpstudy自带一个mysql&#xff0c;目测是本来的mysql进程占用端口。 1、按winR键&#xff0c;输入 services.msc 找到mysql服务,关闭 2、再以管理员身份运行 一定要用管理员身份运行&#xff0c;我的问题这种方法解决了&#xff0c;其他的…

phpstudy mysql启动不了,问题已解决

首先讲一下我遇到的问题&#xff0c;安装好phpStudy v8.1之后&#xff0c;MySQL无法无法启动&#xff0c;出现错误的原因大概是phpStudy与原先下载的MySQL冲突了&#xff0c;随后在网上找了一些教程&#xff0c;进行了一系列操作&#xff1a;&#xff08;有些朋友成功了&#x…

MySQL启动与关闭的3种方式

MySQL启动与关闭的3种方式 在这里大概记述一下MySQL最常用的3种启动与关闭的方式 文章目录 MySQL启动与关闭的3种方式一、第一种方式二、第二种方式三、第三种方式总结 一、第一种方式 直接搜索“服务”或者搜索“service”&#xff0c;再点击服务 找到MySQL57&#xff0c;…