当前位置: 首页 > news >正文

二、模型训练与优化(4):模型优化-实操

下面我将以 MNIST 手写数字识别模型为例,从 剪枝 (Pruning)量化 (Quantization) 两个常用方法出发,提供一套可实际动手操作的模型优化流程。此示例基于 TensorFlow/Keras 环境,示范如何先训练一个基础模型,然后对其进行剪枝和量化,最后验证优化后的模型性能。


目录

  1. 整体流程概览
  2. 模型剪枝 (Pruning)
    1. 安装依赖库
    2. 修改训练脚本实现剪枝
    3. 如何运行剪枝脚本
    4. 检查与验证剪枝后模型
  3. 模型量化 (Quantization)
    1. 原理与应用场景
    2. 在脚本中添加量化步骤
    3. 运行量化脚本
    4. 验证量化后模型
  4. 常见问题与建议
  5. 总结

1. 整体流程概览

在之前博客中已经可以训练一个基础 MNIST 模型(train_mnist.py)并成功获得 mnist_model.h5 的前提下,通常会按照以下顺序进行优化:

在模型训练好后,可以在mnist_project文件夹下找到mnist_model.h5,如下:

  1. 剪枝 (Pruning):减小模型大小、去除不重要的权重,生成 pruned_mnist_model.h5
  2. (可选)量化 (Quantization):将浮点模型转化为 INT8 等低比特模型,大幅减小模型体积,并提升推理速度,生成 mnist_model_quant.tflite

在此过程中,我们需要:

  • 修改已有脚本新增脚本来执行剪枝和量化的操作。
  • 确保虚拟环境已安装必要库tensorflow-model-optimizationtensorflow-lite等)。
  • 反复验证模型的大小、推理速度、准确率,找到最适合部署需求的平衡点。

2. 模型剪枝 (Pruning)

2.1 安装依赖库

  • TensorFlow Model Optimization Toolkit:其中包含 tfmot.sparsity.keras 模块,可用于剪枝、量化感知训练等。

在激活的虚拟环境(tf_env 等)下,输入:

pip install tensorflow-model-optimization

如果已经安装过,可以跳过此步骤;若版本较旧,建议 pip install --upgrade tensorflow-model-optimization

2.2 修改训练脚本实现剪枝

这里给出的示例代码可放在一个新的脚本(如 prune_mnist.py),或者在原 train_mnist.py 中替换。示例如下:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import tensorflow_model_optimization as tfmotdef main():# 1. 加载 MNIST 数据集(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()# 2. 数据预处理x_train = x_train.astype("float32") / 255.0x_test  = x_test.astype("float32") / 255.0x_train = x_train.reshape(-1, 28 * 28)x_test  = x_test.reshape(-1, 28 * 28)# 3. 定义剪枝参数pruning_params = {# PolynomialDecay 让剪枝率从 initial_sparsity 到 final_sparsity 逐渐增加'pruning_schedule': tfmot.sparsity.keras.PolynomialDecay(initial_sparsity=0.0,     # 初始剪枝率 (0%)final_sparsity=0.5,       # 最终剪枝率 (50%)begin_step=0,             # 剪枝开始 stepend_step=np.ceil(len(x_train) / 64).astype(np.int32) * 5# end_step: 这里相当于 epochs * (训练集样本数 / batch_size))}# 4. 构建剪枝后的模型#   - 先定义一个包含1~2层的网络#   - 使用 prune_low_magnitude 对最后一层进行剪枝封装model = tf.keras.models.Sequential([tf.keras.layers.Dense(128, activation='relu', input_shape=(784,)),tfmot.sparsity.keras.prune_low_magnitude(tf.keras.layers.Dense(10, activation='softmax'),**pruning_params)])# 5. 编译模型model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])# 6. 设置剪枝回调#    - UpdatePruningStep:在每个批次/epoch后更新剪枝进度#    - PruningSummaries:可选,将剪枝信息写入到指定 log_dir,配合 TensorBoard 查看callbacks = [tfmot.sparsity.keras.UpdatePruningStep(),tfmot.sparsity.keras.PruningSummaries(log_dir='logs')]# 7. 训练模型#    - epochs=5 可以根据需要加大或减少history = model.fit(x_train, y_train,epochs=5,batch_size=64,validation_split=0.1,callbacks=callbacks)# 8. 模型评估test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)print(f"\n测试集上的准确率: {test_acc:.4f}")# 9. 保存剪枝后的模型#    - 先使用 strip_pruning 去除剪枝包装器,得到最终“瘦身”模型final_model = tfmot.sparsity.keras.strip_pruning(model)final_model.save("pruned_mnist_model.h5")# 10. 可视化训练过程plot_history(history)def plot_history(history):"""可视化训练曲线"""acc = history.history['accuracy']val_acc = history.history['val_accuracy']loss = history.history['loss']val_loss = history.history['val_loss']epochs_range = range(len(acc))plt.figure(figsize=(12, 4))# 绘制准确率曲线plt.subplot(1, 2, 1)plt.plot(epochs_range, acc, label='训练准确率')plt.plot(epochs_range, val_acc, label='验证准确率')plt.legend(loc='lower right')plt.title('训练和验证准确率')# 绘制损失曲线plt.subplot(1, 2, 2)plt.plot(epochs_range, loss, label='训练损失')plt.plot(epochs_range, val_loss, label='验证损失')plt.legend(loc='upper right')plt.title('训练和验证损失')plt.show()if __name__ == "__main__":main()
代码要点
  1. tfmot.sparsity.keras.PolynomialDecay:定义从 0% 到 50% 的剪枝率逐渐增加的策略。
  2. prune_low_magnitude(...):对目标层进行剪枝包装。可以只对某些关键层做剪枝,也可对网络所有层做封装。
  3. strip_pruning(...):剪枝训练完后,需要去掉剪枝相关的“假”节点,才能得到真正稀疏的权重以减小体积。

2.3 如何运行剪枝脚本

  1. 确保已经训练过一个基础模型(可选,如果想微调原模型);或者像示例这样直接在脚本里构建一个新的网络。
  2. 打开 Anaconda Prompt(或终端),激活虚拟环境
    conda activate tf_env
    
  3. 导航到脚本所在目录
    cd C:\Users\FCZ\Desktop\Projects\mnist_project
    
  4. 运行脚本
    python prune_mnist.py
    

训练过程结束后,会打印出测试集准确率,并在目录下生成 pruned_mnist_model.h5

2.4 检查与验证剪枝后模型

  1. 模型体积:相较原始不剪枝模型,pruned_mnist_model.h5 通常会更小,但因 HDF5 格式本身包含稀疏权重的表示方式,实际文件大小并不总是线性减少。关键是剪枝会让权重矩阵变得稀疏,后续可以配合特定框架(如 STM32Cube.AI)进行再处理。
  2. 准确率:可能略有降低,一般会在 0.97~0.98 附近。若下降过多,可调整 final_sparsity (如从 0.5 改为 0.3) 或增加微调 epochs。
  3. 后续可做量化:将剪枝后模型再进行量化,可实现进一步体积和推理速度的提升。

3. 模型量化 (Quantization)

3.1 原理与应用场景

  • 量化:把模型中的权重(和激活)从 float32 转化成 int8、float16 等低位格式,典型方式是使用 TensorFlow Lite 的离线量化。
  • 适用场景:需要在嵌入式或移动端部署,同时希望降低模型大小和加速推理。
  • 代价:可能带来少量精度损失。如果需要减小精度损失,可用量化感知训练(QAT)。

3.2 在脚本中添加量化步骤

当我们在 train_mnist.py 训练完基础模型后,在prune_mnist.py完成剪枝操作后,接下来完成量化操作,编写单独脚本 quantize_mnist.py:将 训练、剪枝、量化 三个步骤整合在一起

"""
quantize_mnist.py
-----------------
在同一个脚本中完成:
1. MNIST 基础模型训练
2. 剪枝 (Pruning)
3. 量化 (Quantization)依赖:- tensorflow>=2.5- tensorflow-model-optimization- numpy, matplotlib (可选, 用于可视化)
"""import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import tensorflow_model_optimization as tfmotdef load_mnist_data():"""加载 MNIST 数据,并做基本预处理。"""(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()x_train = x_train.astype("float32") / 255.0x_test  = x_test.astype("float32") / 255.0# 展开 28x28 -> 784x_train = x_train.reshape(-1, 28 * 28)x_test  = x_test.reshape(-1, 28 * 28)return (x_train, y_train), (x_test, y_test)def create_base_model():"""构建一个简单的全连接 MNIST 模型。"""model = tf.keras.models.Sequential([tf.keras.layers.Dense(128, activation='relu', input_shape=(784,)),tf.keras.layers.Dense(10, activation='softmax')])return modeldef plot_history(history, title_prefix=""):"""可视化训练曲线"""acc = history.history['accuracy']val_acc = history.history['val_accuracy']loss = history.history['loss']val_loss = history.history['val_loss']epochs_range = range(len(acc))plt.figure(figsize=(12, 4))# 准确率曲线plt.subplot(1, 2, 1)plt.plot(epochs_range, acc, label='训练准确率')plt.plot(epochs_range, val_acc, label='验证准确率')plt.legend(loc='lower right')plt.title(f'{title_prefix} 训练和验证准确率')# 损失曲线plt.subplot(1, 2, 2)plt.plot(epochs_range, loss, label='训练损失')plt.plot(epochs_range, val_loss, label='验证损失')plt.legend(loc='upper right')plt.title(f'{title_prefix} 训练和验证损失')plt.show()def main():# =======================================# 1. 数据准备# =======================================(x_train, y_train), (x_test, y_test) = load_mnist_data()# =======================================# 2. 训练基线模型# =======================================print("\n--- 步骤1: 训练基线模型 ---")base_model = create_base_model()base_model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])history_base = base_model.fit(x_train, y_train,epochs=5,batch_size=64,validation_split=0.1)test_loss_base, test_acc_base = base_model.evaluate(x_test, y_test, verbose=0)print(f"基线模型测试集准确率: {test_acc_base:.4f}")# 可视化基线模型训练过程plot_history(history_base, title_prefix="基线模型")# 保存基线模型base_model.save("mnist_model.h5")# =======================================# 3. 剪枝 (Pruning)# =======================================print("\n--- 步骤2: 剪枝模型 ---")# 定义剪枝参数:从0%渐增到50%的剪枝率pruning_params = {'pruning_schedule': tfmot.sparsity.keras.PolynomialDecay(initial_sparsity=0.0,final_sparsity=0.5,begin_step=0,end_step=np.ceil(len(x_train) / 64).astype(np.int32) * 5)}# 用之前的 base_model 权重来构造可剪枝模型# 也可直接对 base_model 做 prune_low_magnitude,但这里分开写更清晰pruned_model = tf.keras.models.Sequential([tf.keras.layers.Dense(128, activation='relu', input_shape=(784,)),tfmot.sparsity.keras.prune_low_magnitude(tf.keras.layers.Dense(10, activation='softmax'),**pruning_params)])# 把 base_model 的第一层权重复制到 pruned_model 第1层pruned_model.layers[0].set_weights(base_model.layers[0].get_weights())# 编译可剪枝模型pruned_model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])# 设置回调:更新剪枝步数 + 记录日志callbacks = [tfmot.sparsity.keras.UpdatePruningStep(),tfmot.sparsity.keras.PruningSummaries(log_dir='logs')]history_pruned = pruned_model.fit(x_train, y_train,epochs=3,          # 可以适当增加训练轮数batch_size=64,validation_split=0.1,callbacks=callbacks)test_loss_pruned, test_acc_pruned = pruned_model.evaluate(x_test, y_test, verbose=0)print(f"剪枝后模型测试集准确率: {test_acc_pruned:.4f}")plot_history(history_pruned, title_prefix="剪枝模型")# strip_pruning: 得到真正稀疏的权重final_pruned_model = tfmot.sparsity.keras.strip_pruning(pruned_model)final_pruned_model.save("pruned_mnist_model.h5")# =======================================# 4. 量化 (Quantization)# =======================================print("\n--- 步骤3: 量化剪枝后模型 (PTQ) ---")# 您也可以对 base_model 做量化,这里演示对 剪枝后的模型 做量化converter = tf.lite.TFLiteConverter.from_keras_model(final_pruned_model)converter.optimizations = [tf.lite.Optimize.DEFAULT]# 如需要 representative_dataset 来校准,可添加:# converter.representative_dataset = ...# 转换为 TFLitetflite_quant_model = converter.convert()# 保存量化后的 TFLite 文件with open('pruned_mnist_model_quant.tflite', 'wb') as f:f.write(tflite_quant_model)print("量化后的剪枝模型已保存: pruned_mnist_model_quant.tflite")# 如有需要,可使用 tflite interpreter 测试推理# 这里仅演示到生成 TFLite 文件即可if __name__ == "__main__":main()
注意
  • 量化完成后,记得在 PC 或嵌入式设备上进行推理测试,查看最终精度。

3.3 运行量化脚本

  1. 依旧在 Anaconda Prompt 中激活环境conda activate tf_env
  2. 导航到脚本所在目录
  3. 执行: python quantize_mnist.py
  4. 观察输出:若无异常,脚本会提示 "量化后的模型已保存为 mnist_model_quant.tflite"
  • 训练基线模型:训练 5 轮得到 mnist_model.h5
  • 剪枝模型:基于基线模型的权重进行剪枝,训练 3 轮得到 pruned_mnist_model.h5
  • 量化模型:将剪枝后的模型转换为 .tflite 格式,并保存为 pruned_mnist_model_quant.tflite
  • 结果文件

  •          mnist_model.h5:基线模型(未剪枝、未量化)。

       pruned_mnist_model.h5:剪枝后且 strip_pruning 的 Keras 模型。

       pruned_mnist_model_quant.tflite:剪枝后再量化的 TFLite 模型,通常体积最小,速度也更快(具体依赖硬件支持)。

总结

接下来对优化后的模型进行验证,验证方法:

  • 在脚本运行过程中会输出基线模型剪枝模型的测试集准确率。
  • .tflite 文件可以用 TFLite InterpreterSTM32Cube.AI 进行推理测试,查看最终精度和性能。

相关文章:

二、模型训练与优化(4):模型优化-实操

下面我将以 MNIST 手写数字识别模型为例,从 剪枝 (Pruning) 和 量化 (Quantization) 两个常用方法出发,提供一套可实际动手操作的模型优化流程。此示例基于 TensorFlow/Keras 环境,示范如何先训练一个基础模型,然后对其进行剪枝和…...

3D可视化产品定制,应用于哪些行业领域?

3D可视化定制服务已广泛渗透至众多行业领域,包括汽车、家居、时尚鞋服、珠宝配饰以及数码电器等: 汽车行业: 借助Web全景技术与3D模型,我们高保真地再现了汽车外观,为用户带来沉浸式的车型浏览体验。用户可在展示界面自…...

Avalonia 入门笔记(零):概述

Avalonia 是一个基于 .NET 和 Skia 的开源、跨平台 UI 框架,支持 Windows、Linux、macOS、iOS、Android 和 WebAssembly。Skia 是一个基于 C 的开源 2D 渲染引擎,Avalonia 通过 Skia 自绘 UI 控件,保证在全平台具有一致的观感 基于 .NET 的跨…...

Unity TextMesh Pro入门

概述 TextMesh Pro是Unity提供的一组工具,用于创建2D和3D文本。与Unity的UI文本和Text Mesh系统相比,TextMesh Pro提供了更好的文本格式控制和布局管理功能。 本文介绍了TMP_Text组件和Tmp字体资产(如何创建字体资产和如何解决缺字问题),还有一些高级功…...

[论文阅读] (35)TIFS24 MEGR-APT:基于攻击表示学习的高效内存APT猎杀系统

《娜璋带你读论文》系列主要是督促自己阅读优秀论文及听取学术讲座,并分享给大家,希望您喜欢。由于作者的英文水平和学术能力不高,需要不断提升,所以还请大家批评指正,非常欢迎大家给我留言评论,学术路上期…...

12 USART串口通讯

1 串口物理层 两个设备的“DB9接口”之间通过串口信号建立连接,串口信号线中使用“RS232标准”传输数据信号。由于RS232电平标准的信号不能直接被控制器直接识别,所以这些信号会经过“电平转换芯片”转换成控制器能识别的“TTL校准”的电平信号&#xff…...

CF 368A.Sereja and Coat Rack(Java实现)

问题分析 简而言之,小明要邀请m个绅士到家,家里有n个挂衣钩,一个挂衣钩要支付i元,如果挂衣钩不够了就要给每个绅士赔d元 思路分析 所以思路就很清楚了,获取n,d,m的值,并用数组存放每…...

清华大学、字节跳动等单位联合发布最新视觉语言动作模型RoboVLMs

近年来,视觉语言基础模型(Vision Language Models, VLMs)大放异彩,在多模态理解和推理上展现出了超强能力。现在,更加酷炫的视觉语言动作模型(Vision-Language-Action Models, VLAs)来了&#x…...

网络安全、Web安全、渗透测试之笔经面经总结

本篇文章涉及的知识点有如下几方面: 1.什么是WebShell? 2.什么是网络钓鱼? 3.你获取网络安全知识途径有哪些? 4.什么是CC攻击? 5.Web服务器被入侵后,怎样进行排查? 6.dll文件是什么意思,有什么…...

.NET Core NPOI 导出图片到Excel指定单元格并自适应宽度

NPOI:支持xlsx,.xls,版本>2.5.3 XLS:HSSFWorkbook,主要前缀HSS, XLSX:XSSFWorkbook,主要前缀XSS,using NPOI.XSSF.UserModel; 1、导出Excel添加图片效果&#xff0…...

python bs4 selenium 查找a href=javascript:();的实际点击事件和url

在使用 BeautifulSoup 和 Selenium 时,处理 href"javascript:;" 的链接需要一些额外的步骤,因为这些链接不直接指向一个 URL,而是通过 JavaScript 代码来执行某些操作。这可能包括导航到另一个页面、触发模态窗口、显示/隐藏内容等…...

三 BH1750 光感驱动调试1

一 扫描设备 查看手册 BH1750 光感模块 寄存器地址为 0x23 官方手册 : http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1750fvi-e.pdf su 然后用 i2cdetect 扫描设备: 拨,插 对比, 探测设备挂载在 /dev/i2c-5 上, 从设备地址为 0x23 二 …...

UE材质节点Fresnel

Fresnel节点 ExponentIn 控制边缘透明度 BaseReflectFractionIn 控制中心透明度...

linux的大内核锁与顺序锁

大内核锁 Linux大内核锁(Big Kernel Lock,BKL)是Linux内核中的一种锁机制,用于保护内核资源,以下是关于它的详细介绍: 概念与作用 大内核锁是一种全局的互斥锁,在同一时刻只允许一个进程访问…...

用户注册模块用户校验(头条项目-05)

1 用户注册后端逻辑 1.1 接收参数 username request.POST.get(username) password request.POST.get(password) phone request.POST.get(phone) 1.2 校验参数 前端校验过的后端也要校验,后端的校验和前端的校验是⼀致的 # 判断参数是否⻬全 # 判断⽤户名是否…...

面向对象的基本概念

本篇,来介绍面向对象的基本概念。 1 面向过程与面向对象 面向过程与面向对象,是两种不同的编程思想。 1.1 面向过程 面向过程的思路,是按照问题的解决步骤,将程序分解为一个个具体的函数或过程,然后依次调用这些函数来实现程序的功能。 面向对象的程序设计,程序的执行…...

深度学习每周学习总结R4(LSTM-实现糖尿病探索与预测)

🍨 本文为🔗365天深度学习训练营 中的学习记录博客R6中的内容,为了便于自己整理总结起名为R4🍖 原作者:K同学啊 | 接辅导、项目定制 目录 0. 总结1. LSTM介绍LSTM的基本组成部分如何理解与应用LSTM 2. 数据预处理3. 数…...

如何使用 PHP 操作亚马逊 S3 对象云存储

以下是使用PHP与亚马逊S3对象云存储(也有其他支持S3协议的云存储服务,原理类似)进行交互的常见文档接口使用示例,涵盖了基本的操作如上传文件、下载文件、删除文件、列举文件等内容。 ### 前提条件 1. 首先,你需要获取…...

26_Redis RDB持久化

从这个模块开始带领大家来学习Redis分布式缓存的相关内容,主要学习目标见下: 数据丢失问题:实现Redis数据持久化(RDB和AOF)并发能力问题:搭建Redis主从集群,实现读写分离故障恢复问题:利用Redis哨兵模式,实现健康检测和自动恢复存储能力问题:搭建Redis分片集群,利用…...

标准Android开发jdk和gradle和gradle AGP和AndroidStudio对应版本

还在为用什么gradle版本烦恼吗?编译不过IDE不开始下载第三方库吗?是时候匹配下你的gradle编译版本了: 1.Gradle 各版本支持的 JDK 版本范围如下: Gradle 版本最低支持 JDK最高支持 JDK7.0 - 7.6JDK 8JDK 178.0 - 8.2JDK 11JDK 1…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

湖北理元理律师事务所:债务清偿方案中的法律技术革新

文/金融法律研究组 当前债务服务市场存在结构性矛盾:债权人追求快速回款,债务人需要喘息空间。湖北理元理律师事务所通过创新法律技术,在《企业破产法》《民法典》框架下构建梯度清偿模型,实现多方利益平衡。 一、个人债务优化的…...

Qt Quick Dialogs模块功能及架构

Qt Quick Dialogs 是 Qt Quick 的一个附加模块,提供了一套用于创建和使用系统对话框的 QML 类型。在 Qt 6.0 中,这个模块经过了重构和增强。 一、主要功能和特点 1. 对话框类型 Qt Quick Dialogs 在 Qt 6.0 中提供了以下标准对话框类型: …...

Pycharm的终端无法使用Anaconda命令行问题详细解决教程

很多初学者在Windows系统上安装了Anaconda后,在PyCharm终端中运行Conda命令时,会遇到以下错误: conda : 无法将“conda”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。 请检查名称的拼写,如果包括路径,请确保…...

2. Web网络基础 - 协议端口

深入解析协议端口与netstat命令:网络工程师的实战指南 在网络通信中,协议端口是服务访问的门户。本文将全面解析端口概念,并通过netstat命令实战演示如何监控网络连接状态。 一、协议端口核心知识解析 1. 端口号的本质与分类 端口范围类型说…...

Linux系统的CentOS7发行版安装MySQL80

文章目录 前言Linux命令行内的”应用商店”安装CentOS的安装软件的yum命令安装MySQL1. 配置yum仓库2. 使用yum安装MySQL3. 安装完成后,启动MySQL并配置开机自启动4. 检查MySQL的运行状态 MySQL的配置1. 获取MySQL的初始密码2. 登录MySQL数据库系统3. 修改root密码4.…...