数字探秘:用神经网络解密MNIST数据集中的数字!

news2024/9/21 10:45:18

用神经网络解密MNIST数据集中的数字!

    • 一. 介绍
      • 1.1 MNIST数据集简介
      • 1.2 MLP(多层感知器)模型介绍
      • 1.3 目标:使用MLP模型对MNIST数据集中的0-9数字进行分类
    • 二.数据预处理
      • 2.1 数据集的获取与加载
      • 2.2 数据集的探索性分析(EDA)
      • 2.3 数据预处理:归一化、展平图像数据
    • 三. MLP模型构建
      • 3.1 MLP模型结构介绍
      • 3.2 激活函数选择
      • 3.3 损失函数和优化算法选择
      • 3.4 模型训练
    • 四. 模型性能评估
      • 4.1 分类准确度(Accuracy)评估
      • 4.2 混淆矩阵(Confusion Matrix)分析
      • 4.3 精确率(Precision)、召回率(Recall)和F1分数(F1 Score)计算
      • 4.4 可视化误差分析
    • 五. 性能改进
      • 5.1 超参数调优
        • 5.1.1 学习率调整
        • 5.1.2 批量大小优化
      • 5.2 模型结构优化
        • 5.2.1 增加隐藏层和神经元数量
        • 5.2.2 正则化技术的应用
      • 5.3 数据增强(Data Augmentation)应用
        • 5.3.1 图像旋转、平移和缩放
    • 六. 结论
      • 6.1 模型性能总结
      • 6.2 可能的改进方向
      • 6.3 对于实际应用的启示

一. 介绍

1.1 MNIST数据集简介

MNIST(Modified National Institute of Standards and Technology database)是一个经典的手写数字数据集,常被用来测试机器学习算法的性能。它包含了大约70000张标准化的手写数字图像,每张图像是28x28像素,灰度图,标记从0到9的数字。这个数据集被广泛应用于数字识别的研究和实验中,是深度学习入门和基准测试的常用选择。
在这里插入图片描述

1.2 MLP(多层感知器)模型介绍

多层感知器(MLP)是一种经典的前馈人工神经网络模型,由一个或多个隐藏层组成,每个隐藏层由多个神经元(节点)组成。MLP的每个神经元与前一层的所有神经元相连,每条连接都有一个权重。通常,MLP包括一个输入层、若干隐藏层和一个输出层。每一层都通过一个非线性激活函数(如ReLU、sigmoid等)来处理输入数据,以产生非线性的模型输出。

MLP适合处理结构化数据,特别是在特征之间存在复杂关系或需要进行非线性映射时表现良好。在数字分类问题中,MLP通过学习输入数据的特征和模式,能够有效地识别和分类不同的数字。

1.3 目标:使用MLP模型对MNIST数据集中的0-9数字进行分类

本项目的主要目标是设计、实现和评估一个MLP模型,用于对MNIST数据集中的手写数字进行准确的分类。我们将通过以下步骤完成这一任务:

  • 数据预处理:包括加载数据集、标准化图像、划分训练集和测试集等。
  • 模型设计:定义MLP模型的结构,包括选择合适的层数、每层的神经元数量和激活函数。
  • 模型训练:使用训练集对MLP模型进行训练,通过反向传播算法优化模型参数。
  • 模型评估:使用测试集评估模型的性能,包括准确率、混淆矩阵等指标。
  • 性能优化:通过调整超参数、正则化技术和其他优化策略改进模型性能。

接下来,我们将详细展开每个步骤,并介绍如何在实际项目中实现这些内容。

二.数据预处理

2.1 数据集的获取与加载

在实现基于MNIST数据集的MLP模型之前,首先需要获取和加载数据集。MNIST数据集可以通过多种方式获取,包括直接从公共数据集存储库下载或使用机器学习库提供的API进行访问。以下是使用Python和相关库加载MNIST数据集的示例代码:

import tensorflow.keras as keras
from tensorflow.keras.datasets import mnist

# 加载MNIST数据集,分为训练集和测试集
(X_train, y_train), (X_test, y_test) = mnist.load_data()

print("训练集数据量:", X_train.shape[0])
print("测试集数据量:", X_test.shape[0])

2.2 数据集的探索性分析(EDA)

探索性数据分析(EDA)是数据科学中的重要步骤,有助于理解数据的结构、特征分布以及可能存在的问题。对于MNIST数据集,我们可以进行以下分析:

  • 数据形状和类型:检查数据集中图像和标签的维度和类型。
  • 类别分布:统计每个数字类别在数据集中的分布情况,确保类别平衡。
  • 图像可视化:随机可视化几个图像样本,检查图像质量和手写风格的多样性。
import matplotlib.pyplot as plt
import numpy as np

# 查看类别分布
unique, counts = np.unique(y_train, return_counts=True)
plt.bar(unique, counts)
plt.title('Class Frequency')
plt.xlabel('Class')
plt.ylabel('Frequency')
plt.xticks(unique)
plt.show()

# 随机可视化几个图像样本
plt.figure(figsize=(10, 10))
for i in range(25):
    plt.subplot(5, 5, i + 1)
    plt.imshow(X_train[i], cmap='gray')
    plt.title(f'Label: {y_train[i]}')
    plt.axis('off')
plt.show()

2.3 数据预处理:归一化、展平图像数据

在训练MLP模型之前,需要对图像数据进行预处理,以便提高模型训练的效果和收敛速度。常见的预处理步骤包括图像归一化和展平操作:

  • 归一化:将图像像素值缩放到0到1之间,有助于加速模型收敛并提高模型的稳定性。
  • 展平:将二维的28x28像素图像转换为一维向量,以作为MLP模型的输入。
# 归一化
X_train = X_train.astype('float32') / 255.0
X_test = X_test.astype('float32') / 255.0

# 展平图像数据
X_train_flat = X_train.reshape((-1, 28*28))
X_test_flat = X_test.reshape((-1, 28*28))

print("训练集展平后的形状:", X_train_flat.shape)
print("测试集展平后的形状:", X_test_flat.shape)

通过上述步骤,我们完成了对MNIST数据集的加载、探索性分析和预处理操作。接下来,可以设计和训练MLP模型,并对其性能进行评估。在后续章节中,我们将详细讨论如何构建和优化MLP模型,以及如何解释和改进其分类性能。

三. MLP模型构建

3.1 MLP模型结构介绍

多层感知器(MLP)是一种经典的前馈神经网络模型,适用于处理结构化数据和分类问题。MLP由输入层、若干隐藏层和输出层组成,每个层之间的神经元完全连接,并通过权重进行信息传递。以下是一个典型的MLP模型结构示例:

  • 输入层:接收展平后的图像数据作为输入,每个样本是一个长度为784的向量(对应28x28像素的展平图像)。
  • 隐藏层:可以包括一个或多个隐藏层,每个隐藏层包含多个神经元。隐藏层的选择通常基于任务的复杂性和数据的特征。
  • 输出层:最后一层通常是一个具有10个神经元的输出层,每个神经元对应一个数字类别(0到9)的概率。
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

# 定义MLP模型
model = Sequential([
    Dense(128, activation='relu', input_shape=(784,)),
    Dense(64, activation='relu'),
    Dense(10, activation='softmax')
])

# 打印模型结构
model.summary()

在上面的示例中,我们创建了一个包含两个隐藏层(128个神经元和64个神经元)的MLP模型,输出层使用softmax激活函数以获得每个类别的概率分布。

3.2 激活函数选择

激活函数在神经网络中起到了非常重要的作用,它们增加了模型的非线性特性,使其能够学习复杂的数据模式和特征。常用的激活函数包括:

  • ReLU(Rectified Linear Unit): ( f(x) = \max(0, x) ),在隐藏层中常用,能够有效地缓解梯度消失问题。
  • sigmoid函数: ( f(x) = \frac{1}{1 + e^{-x}} ),用于二分类问题中的输出层。
  • softmax函数: ( f(x_i) = \frac{e^{x_i}}{\sum_{j} e^{x_j}} ),用于多分类问题中的输出层,将输出转换为概率分布。

在MLP模型中,通常在隐藏层使用ReLU激活函数,在输出层使用softmax激活函数来预测每个类别的概率。

3.3 损失函数和优化算法选择

选择合适的损失函数和优化算法对模型的性能和训练效率至关重要。

  • 损失函数:用于衡量模型预测值与真实标签之间的差异。对于多分类问题,常用的损失函数包括交叉熵损失函数(Categorical Crossentropy),它能够衡量两个概率分布之间的差异。

  • 优化算法:用于更新模型参数以最小化损失函数。常见的优化算法包括随机梯度下降(SGD)、Adam优化器等。Adam优化器结合了动量和自适应学习率调整,通常在训练深度学习模型时表现较好。

# 编译模型,选择损失函数和优化算法
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

3.4 模型训练

模型构建完成后,我们需要对其进行训练。训练过程包括将模型参数调整到最佳状态,以便能够对新数据做出准确的预测。

四. 模型性能评估

4.1 分类准确度(Accuracy)评估

分类准确度是最常用的性能指标之一,它表示模型正确分类的样本比例。在MNIST数据集上,我们可以通过以下方式计算模型的分类准确度:

# 在测试集上评估模型
test_loss, test_acc = model.evaluate(X_test_flat, y_test, verbose=2)
print(f'测试集上的准确率:{test_acc:.4f}')

4.2 混淆矩阵(Confusion Matrix)分析

混淆矩阵是一种用于可视化模型预测结果的表格,显示了模型在每个类别上的真实预测情况。我们可以使用混淆矩阵来进一步分析模型在各个类别上的表现:

from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay

# 预测测试集的类别
y_pred = model.predict_classes(X_test_flat)

# 计算混淆矩阵
cm = confusion_matrix(y_test, y_pred)

# 可视化混淆矩阵
plt.figure(figsize=(10, 8))
ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=np.arange(10)).plot(cmap='Blues')
plt.title('Confusion Matrix')
plt.show()

4.3 精确率(Precision)、召回率(Recall)和F1分数(F1 Score)计算

精确率、召回率和F1分数是衡量分类器性能的重要指标,特别是在不平衡类别分布的情况下更为有用。它们的计算公式如下:

  • 精确率(Precision): ( \text{Precision} = \frac{TP}{TP + FP} ),其中TP是真阳性(正确预测为正例的样本数),FP是假阳性(错误预测为正例的样本数)。
  • 召回率(Recall): ( \text{Recall} = \frac{TP}{TP + FN} ),其中FN是假阴性(错误预测为负例的样本数)。
  • F1分数(F1 Score): ( F1 = 2 \cdot \frac{\text{Precision} \cdot \text{Recall}}{\text{Precision} + \text{Recall}} ),综合考虑了精确率和召回率。
from sklearn.metrics import classification_report

# 打印精确率、召回率和F1分数
print(classification_report(y_test, y_pred, target_names=[str(i) for i in range(10)]))

4.4 可视化误差分析

最后,我们可以通过可视化来分析模型在测试集上的误差,帮助我们理解模型预测错误的原因和模式:

# 找出预测错误的样本
incorrect_indices = np.where(y_pred != y_test)[0]

# 随机选择一些错误样本进行展示
plt.figure(figsize=(12, 8))
for i, incorrect in enumerate(np.random.choice(incorrect_indices, size=25, replace=False)):
    plt.subplot(5, 5, i + 1)
    plt.imshow(X_test[incorrect], cmap='gray')
    plt.title(f'True: {y_test[incorrect]} Predicted: {y_pred[incorrect]}')
    plt.axis('off')
plt.tight_layout()
plt.show()

通过以上步骤,我们可以全面评估和理解MLP模型在MNIST数据集上的分类性能。下一步将是根据评估结果对模型进行优化和改进,以提高其在数字分类任务上的表现。

五. 性能改进

5.1 超参数调优

超参数是影响模型性能和训练速度的重要因素,包括学习率、批量大小、隐藏层神经元数量等。通过系统地调整这些超参数,我们可以找到最佳组合以改善模型性能。

5.1.1 学习率调整

学习率控制着模型参数更新的速度,过高的学习率可能导致模型在训练过程中震荡,而过低的学习率则会导致收敛速度缓慢。可以通过尝试不同的学习率来找到最优值。

from tensorflow.keras.optimizers import Adam

# 定义不同的学习率
learning_rates = [1e-3, 1e-4, 1e-5]

for lr in learning_rates:
    model = Sequential([
        Dense(128, activation='relu', input_shape=(784,)),
        Dense(64, activation='relu'),
        Dense(10, activation='softmax')
    ])
    
    # 编译模型,选择优化器和学习率
    optimizer = Adam(learning_rate=lr)
    model.compile(optimizer=optimizer,
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])
    
    # 训练模型
    history = model.fit(X_train_flat, y_train, epochs=10, batch_size=128, validation_data=(X_test_flat, y_test), verbose=0)
    
    # 打印最终的验证集准确率
    _, test_acc = model.evaluate(X_test_flat, y_test, verbose=0)
    print(f'学习率 {lr} 下的测试集准确率:{test_acc:.4f}')
5.1.2 批量大小优化

批量大小决定了在每次参数更新时用于计算梯度的样本数。通常情况下,较大的批量大小可以加快训练速度,但可能会影响模型的泛化能力。

# 尝试不同的批量大小
batch_sizes = [32, 64, 128]

for bs in batch_sizes:
    model = Sequential([
        Dense(128, activation='relu', input_shape=(784,)),
        Dense(64, activation='relu'),
        Dense(10, activation='softmax')
    ])
    
    # 编译模型,选择优化器和批量大小
    model.compile(optimizer='adam',
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])
    
    # 训练模型
    history = model.fit(X_train_flat, y_train, epochs=10, batch_size=bs, validation_data=(X_test_flat, y_test), verbose=0)
    
    # 打印最终的验证集准确率
    _, test_acc = model.evaluate(X_test_flat, y_test, verbose=0)
    print(f'批量大小 {bs} 下的测试集准确率:{test_acc:.4f}')

5.2 模型结构优化

优化模型结构是提升模型性能的关键步骤之一,可以通过增加/减少隐藏层、调整神经元数量等方式来改进模型的表现。

5.2.1 增加隐藏层和神经元数量

在某些情况下,增加隐藏层或增加每层神经元数量可以增加模型的表达能力,从而提升性能。但需要注意避免过拟合问题。

# 增加隐藏层和神经元数量的示例
model = Sequential([
    Dense(256, activation='relu', input_shape=(784,)),
    Dense(128, activation='relu'),
    Dense(64, activation='relu'),
    Dense(10, activation='softmax')
])
5.2.2 正则化技术的应用

正则化技术(如L2正则化、dropout等)可以有效控制模型的复杂度,提升泛化能力,从而减少过拟合现象。

from tensorflow.keras.layers import Dropout
from tensorflow.keras import regularizers

# 添加Dropout层进行正则化
model = Sequential([
    Dense(128, activation='relu', kernel_regularizer=regularizers.l2(0.01), input_shape=(784,)),
    Dropout(0.3),
    Dense(64, activation='relu', kernel_regularizer=regularizers.l2(0.01)),
    Dropout(0.3),
    Dense(10, activation='softmax')
])

5.3 数据增强(Data Augmentation)应用

对于图像数据,数据增强是一种有效的方法,通过对原始图像进行随机变换来生成新的训练样本,以增加数据的多样性和数量,从而提升模型的泛化能力。

5.3.1 图像旋转、平移和缩放
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# 创建图像增强生成器
datagen = ImageDataGenerator(rotation_range=10, width_shift_range=0.1, height_shift_range=0.1, zoom_range=0.1)

# 在训练集上应用图像增强
datagen.fit(X_train.reshape(-1, 28, 28, 1))

# 使用增强后的数据训练模型
model.fit(datagen.flow(X_train_flat, y_train, batch_size=32), epochs=10, validation_data=(X_test_flat, y_test))

通过以上方法,我们可以有效地优化和改进基于MNIST数据集的MLP模型的性能,提升其在数字分类任务上的表现。在实际应用中,建议结合交叉验证等技术,综合考虑模型在不同超参数组合下的表现,以获取最佳的性能结果。

六. 结论

6.1 模型性能总结

通过本文中的实验和分析,我们成功地实现了基于MNIST数据集的MLP(多层感知器)模型,用于识别手写数字图像。以下是我们对模型性能的总结:

  • 准确度评估:我们通过测试集对模型进行了准确度评估,通常能够达到90%以上的准确率,这表明MLP模型在处理MNIST数据集上具有良好的分类能力。
  • 混淆矩阵分析:混淆矩阵展示了模型在各个数字类别上的预测效果,能够清晰地看出模型在每个类别上的精确度和召回率。
  • 精确率、召回率和F1分数:通过计算精确率、召回率和F1分数,我们进一步评估了模型在不同类别上的分类表现,确保模型在各个类别上均有良好的性能。

总体而言,我们的MLP模型在MNIST数据集上展现出了较高的分类精度和稳定性,能够有效地区分手写数字。

6.2 可能的改进方向

尽管我们的模型已经取得了良好的结果,但仍然存在一些改进的空间,以进一步提升其性能和泛化能力:

  • 超参数调优:可以进一步探索不同的学习率、批量大小、隐藏层结构等超参数的组合,以找到最佳的模型配置。
  • 模型结构优化:考虑尝试更复杂的模型结构,如增加更深的隐藏层或者应用正则化技术来提升模型的表达能力和泛化能力。
  • 集成学习:可以尝试集成多个MLP模型,如投票集成或堆叠集成,以进一步提升模型的整体性能。
  • 数据增强:对于MNIST数据集这种小规模数据集,可以应用数据增强技术,如图像旋转、平移、缩放等,增加训练样本的多样性,从而提升模型的鲁棒性。

6.3 对于实际应用的启示

基于我们在MNIST数据集上的探索,我们可以得出以下对于实际应用的启示:

  • 模型迁移:虽然MNIST是一个简单的手写数字数据集,但是MLP模型的训练和优化方法可以迁移到更复杂的图像分类任务中,如物体识别、人脸识别等。
  • 自动化和优化:在实际应用中,可以结合自动化超参数搜索、模型选择和部署技术,以便更快速地优化和部署深度学习模型。
  • 持续学习:随着数据和任务的变化,模型需要不断更新和优化。因此,建立持续学习和监控的机制是确保模型长期性能的关键。

综上所述,通过本文对基于MNIST数据集的MLP模型的实现与性能评估,我们不仅提升了对深度学习模型的理解和应用能力,还为更复杂问题的解决提供了有益的经验和指导。在未来的工作中,可以进一步探索和应用新的技术,以不断提升模型的性能和应用效果。

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

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

相关文章

编写商品列表和商品编辑和商品新增页面

addvue <template><!-- 传过来的id --> <!-- {{ $route.query.id }} --> <el-formref"FormRef"style"max-width: 600px":model"FormData":rule"rules"status-iconlabel-width"auto"class"demo-r…

【中台】数字中台建设方案(PPT)

数字中台建设要点&#xff1a; 数据采集与整合&#xff1a; 打破企业内部各个业务系统的数据隔阂&#xff0c;通过数据采集和数据交换实现数据的集中管理&#xff0c;形成统一的数据中心&#xff0c;为后续数据价值的挖掘提供基础。 利用自研或第三方ETL&#xff08;Extract, T…

最长下降序列

如何理解这个题目呢,我们可以每个人的分数放到排名上&#xff0c;然后求解最长下降序列即可 #include<bits/stdc.h> using namespace std;int n; const int N (int)1e5 5; int a[N]; int b[N]; int d[N]; int dp[N]; int t;int main() {cin >> t;while (t--) {…

排序——归并排序及排序章节总结

前面的文章中 我们详细介绍了排序的概念&#xff0c;插入排序&#xff0c;交换排序与选择排序&#xff0c;大家可以通过下面的链接再去学习&#xff1a; ​​​​​​排序的概念及插入排序 交换排序 选择排序 这篇文章就详细介绍一下另一种排序算法&#xff1a;归并排序以及…

PE文件(十)重定位表

重定位表的引入 程序加载过程 在win32下&#xff0c;每一个PE文件&#xff08;其可能由多个子PE文件组成&#xff09;在运行时&#xff0c;操作系统会给分配一个独立的4GB虚拟内存&#xff0c;内存地址从0x00000000到0xFFFFFFFF。其中低2G为用户程序空间&#xff0c;高2G为操…

【Linux】进程间通信——消息队列和信号量

目录 消息队列&#xff08;message queue&#xff09; 信号量&#xff08;Semaphore&#xff09; system V版本的进程间通信方式有三种&#xff1a;共享内存&#xff0c;消息队列和信号量。之前我们已经说了共享内存&#xff0c;那么我们来看一下消息队列和信号量以及它们之间…

【鸿蒙学习笔记】位置设置・position・绝对定位

官方文档&#xff1a;位置设置 目录标题 position&#xff1a;绝对定位&#xff0c;确定子组件相对父组件的位置。 position&#xff1a;绝对定位&#xff0c;确定子组件相对父组件的位置。 正→ ↓ Entry Component struct Loc_position {State message: string Hello Wor…

汇编语言程序设计-8-汇编语言快速查阅

8. 汇编语言快速查阅 文章目录 8. 汇编语言快速查阅常用资料寄存器含义标志寄存器的含义Debug的使用汇编语法 本章列出一些需要经常查阅的知识点。 常用资料 参考视频&#xff1a;烟台大学贺利坚老师的网课《汇编语言程序设计系列专题》&#xff0c;或者是B站《汇编语言程序设计…

vue学习day08-v-model详解、sync修饰符、ref和$refs获取dom组件、Vue异步更新和$nextTick

25、v-model详解 &#xff08;1&#xff09;v-model原理 1&#xff09;原理: v-model本质上是一个语法糖&#xff0c;比如&#xff1a;在应用于输入框时&#xff0c;就是value属性与input事件的合写。 2&#xff09;作用 ①数据变&#xff0c;视图变 ②视图变&#xff0c…

【 C++ 】详解 (类和对象) 继承

继承的概念及定义 继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对象 程序设计的层次结构…

【Linux】Linux的账号和用户组

管理员的工作中&#xff0c;相当重要的一环就是【管理账号】。 因为整个系统都是你在管理&#xff0c;并且所有一般用户的账号申请&#xff0c;都必须要通过你的协助才行&#xff0c;所以你就必须要了解一下如何管理好一个服务器主机的账号。 在管理Linux主机的账号时&#xff…

Python应用开发——30天学习Streamlit Python包进行APP的构建(15):优化性能并为应用程序添加状态

Caching and state 优化性能并为应用程序添加状态! Caching 缓存 Streamlit 为数据和全局资源提供了强大的缓存原语。即使从网络加载数据、处理大型数据集或执行昂贵的计算,它们也能让您的应用程序保持高性能。 本页仅包含有关 st.cache_data API 的信息。如需深入了解缓…

AG32 的MCU与FPGA的主频可以达到568MHz吗

Customers: AG32/ AGRV2K 这个芯片主频和定时器最高速度是多少&#xff1f;用户期望 CPLD计时器功能0.1ns以下。 AGM RE: CPLD做不到 0.1ns的速率&#xff0c;这个需要10G以上的时钟。 那AGRV2K最高多少MHz呢&#xff1f; 一般200MHZ比较容易实现。 进一步说明&#xff1…

智慧校园服务监控功能

智慧校园系统中的服务监控功能&#xff0c;扮演着维护整个校园数字化生态系统稳定与高效运作的重要角色。它如同一位全天候的守护者&#xff0c;通过实时跟踪、分析并响应系统各层面的运行状况&#xff0c;确保教学、管理等核心业务流程的顺畅进行。 服务监控功能覆盖了智慧校园…

自动控制——变速积分的PID控制

变速积分的PID控制 PID控制&#xff08;Proportional-Integral-Derivative Control&#xff09;是工业控制中最常用的控制算法之一。标准的PID控制器由比例&#xff08;P&#xff09;、积分&#xff08;I&#xff09;和微分&#xff08;D&#xff09;三个部分组成&#xff0c;…

连锁直营店小程序赋能多店如何管理

如商超便利店卖货线下场景&#xff0c;也有不少品牌以同城多店和多地开店经营为主&#xff0c;获取店铺周围客户和散流&#xff0c;如今线上重要性凸显&#xff0c;品牌电商发展是经营的重要方式之一&#xff0c;也是完善同城和外地客户随时便捷消费的方式之一。 多个门店管理…

Js 前置,后置补零的原生方法与补字符串 padStart及padEnd

在工作中&#xff0c;遇到了需要将不满八位的一个字符串进行后补0的操作&#xff0c;所以就在网上学习了关于js原生补充字符串的方法&#xff0c;然后用这篇博客记录下来。 目录 前置补充字符串 String.prototype.padStart() 后置补充字符串String.prototype.padEnd() 前置补…

OpenGL笔记十之Shader类的封装

OpenGL笔记十之Shader类的封装 —— 2024-07-10 晚上 bilibili赵新政老师的教程看后笔记 code review! 文章目录 OpenGL笔记十之Shader类的封装1.运行2.目录结构3.main.cpp4.application4.1.CMakeLists.txt4.2.Application.h4.3.Application.cpp 5.assets5.1.shaders&#xf…

虚拟机:VMware功能,安装与使用

目录 一、虚拟机介绍 二、VMware 1.介绍 2.安装 &#xff08;1&#xff09;根据提示按步骤安装​编辑 &#xff08;2&#xff09;更改软件的安装地址​编辑 &#xff08;3&#xff09;根据自己的需求选择是否需要软件更新​编辑 &#xff08;4&#xff09;根据需求选择…

20240715 每日AI必读资讯

&#x1f310; 代号“ 草莓 ”&#xff0c;OpenAI 被曝研发新项目&#xff1a;将 AI 推理能力提至新高度 - OpenAI 公司被曝正在研发代号为“ 草莓 ”的全新项目&#xff0c;进一步延伸去年 11 月宣布的 Q* 项目&#xff0c;不断提高 AI 推理能力&#xff0c;让其更接近人类的…