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

基于MNIST数据集的手写数字识别(CNN)

目录

一,模型训练

1.1 数据集介绍

1.2 CNN模型层结构

1.3 定义CNN模型

1.4 神经网络的前向传播过程

1.5 数据预处理

1.6 加载数据

1.7 初始化

1.8 模型训练过程

1.9 保存模型

二,模型测试

2.1 定义与训练时相同的CNN模型架构

2.2 图像的预处理

2.3 预测

三,测试

3.1 测试方法

3.2 测试结果

四 ,总结

五,完整代码

5.1 模型训练部分代码

5.2 模型测试部分代码


本实验直观地体现了CNN对比全连接对于图像处理的优势

全连接网络实现MNIST数字识别实验如下链接:

基于MNIST数据集的手写数字识别(简单全连接网络)-CSDN博客


一,模型训练

1.1 数据集介绍

        MNIST 数据集由 60,000 张图像构成的训练集和 10,000 张图像组成的测试集构成,其中的图像均为 28×28 像素的灰度图,涵盖 0 - 9 这 10 个阿拉伯数字,且数字书写风格、大小、位置多样。它源于美国国家标准与技术研究所(NIST)的数据集,经过归一化和中心化处理。MNIST 数据集是图像识别研究领域的经典数据集,常用于开发和评估图像识别算法与模型,也是机器学习课程中常用的教学案例,许多高性能卷积神经网络模型在该数据集测试集上准确率可达 99% 以上,充分展现出其在机器学习领域的重要价值和广泛应用。

1.2 CNN模型层结构

1.3 定义CNN模型

def __init__(self):super(CNN, self).__init__()  # 调用父类的初始化方法self.conv1 = nn.Conv2d(1, 32, kernel_size=3)  # 定义第一个卷积层,输入通道1,输出通道32,卷积核大小3x3self.conv2 = nn.Conv2d(32, 64, kernel_size=3)  # 定义第二个卷积层,输入通道32,输出通道64,卷积核大小3x3self.pool = nn.MaxPool2d(2, 2)  # 定义最大池化层,池化核大小2x2self.dropout1 = nn.Dropout2d(0.25)  # 定义第一个Dropout层,随机丢弃25%的神经元self.fc1 = nn.Linear(64 * 12 * 12, 128)  # 定义第一个全连接层,输入维度64*12*12,输出维度128self.dropout2 = nn.Dropout(0.5)  # 定义第二个Dropout层,随机丢弃50%的神经元self.fc2 = nn.Linear(128, 10)  # 定义输出层,输入维度128,输出维度10(对应10个数字类别)

        定义了一个用于手写数字识别的卷积神经网络(CNN)架构,专为 MNIST 等单通道图像分类任务设计。网络包含两个卷积层(Conv1 和 Conv2)进行特征提取,每个卷积层后接 ReLU 激活函数和最大池化层(MaxPool2d)进行下采样,逐步将 28×28 的输入图像转换为更高层次的抽象特征。为防止过拟合,在卷积层后添加了 Dropout2d (0.25),在全连接层前使用 Dropout (0.5) 增强模型泛化能力。特征提取完成后,通过两次全连接层(FC1 和 FC2)将卷积输出的多维特征映射到 10 个类别,最终输出对应 0-9 数字的分类得分。

1.4 神经网络的前向传播过程

    def forward(self, x):# 第一层卷积+ReLU激活x = torch.relu(self.conv1(x))# 第二层卷积+ReLU激活+池化x = self.pool(torch.relu(self.conv2(x)))# 应用Dropoutx = self.dropout1(x)# 将多维张量展平为一维向量(64*12*12)x = x.view(-1, 64 * 12 * 12)# 第一个全连接层+ReLU激活x = torch.relu(self.fc1(x))# 应用Dropoutx = self.dropout2(x)# 输出层,得到未归一化的预测分数x = self.fc2(x)return x

1.5 数据预处理

transform = transforms.Compose([transforms.ToTensor(),  # 将图像转换为张量transforms.Normalize((0.1307,), (0.3081,))  # 使用MNIST数据集的均值和标准差进行归一化
])

1.6 加载数据

train_dataset = datasets.MNIST('data', train=True, download=True, transform=transform)  # 加载MNIST训练数据集
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)  # 创建数据加载器,批次大小为64,打乱数据

1.7 初始化

model = CNN()  # 创建CNN模型实例
criterion = nn.CrossEntropyLoss()  # 定义交叉熵损失函数
optimizer = optim.Adam(model.parameters(), lr=0.001)  # 定义Adam优化器,学习率为0.001

1.8 模型训练过程

def train(epochs):model.train()  # 设置模型为训练模式for epoch in range(epochs):  # 进行指定轮数的训练running_loss = 0.0  # 初始化本轮的损失累加器for batch_idx, (data, target) in enumerate(train_loader):  # 遍历数据加载器中的每个批次optimizer.zero_grad()  # 梯度清零output = model(data)  # 前向传播,计算模型输出loss = criterion(output, target)  # 计算损失loss.backward()  # 反向传播,计算梯度optimizer.step()  # 更新模型参数running_loss += loss.item()  # 累加当前批次的损失if batch_idx % 100 == 0:  # 每100个批次打印一次损失print(f'Epoch {epoch + 1}, Batch {batch_idx}, Loss: {loss.item():.6f}')print(f'Epoch {epoch + 1} completed, Average Loss: {running_loss / len(train_loader):.6f}')  # 打印本轮平均损失

1.9 保存模型

if __name__ == '__main__':train(epochs=5)  # 调用训练函数,训练5轮torch.save(model.state_dict(),'mnist_cnn_model.pth')  # 保存模型的参数print("模型已保存为: mnist_cnn_model.pth")  # 打印保存模型的信息

二,模型测试

2.1 定义与训练时相同的CNN模型架构

class CNN(nn.Module):def __init__(self):# 调用父类初始化方法super(CNN, self).__init__()# 第一个卷积层:输入1通道(灰度图),输出32通道,卷积核3x3self.conv1 = nn.Conv2d(1, 32, kernel_size=3)# 第二个卷积层:输入32通道,输出64通道,卷积核3x3self.conv2 = nn.Conv2d(32, 64, kernel_size=3)# 最大池化层:核大小2x2,步长2self.pool = nn.MaxPool2d(2, 2)# Dropout层:训练时随机丢弃25%的神经元,防止过拟合self.dropout1 = nn.Dropout2d(0.25)# 第一个全连接层:输入维度64*12*12,输出128self.fc1 = nn.Linear(64 * 12 * 12, 128)# Dropout层:训练时随机丢弃50%的神经元self.dropout2 = nn.Dropout(0.5)# 输出层:输入128,输出10个类别(对应0-9数字)self.fc2 = nn.Linear(128, 10)def forward(self, x):# 第一层卷积+ReLU激活x = torch.relu(self.conv1(x))# 第二层卷积+ReLU激活+池化x = self.pool(torch.relu(self.conv2(x)))# 应用Dropoutx = self.dropout1(x)# 将多维张量展平为一维向量(64*12*12)x = x.view(-1, 64 * 12 * 12)# 第一个全连接层+ReLU激活x = torch.relu(self.fc1(x))# 应用Dropoutx = self.dropout2(x)# 输出层,得到未归一化的预测分数x = self.fc2(x)return x

2.2 图像的预处理

def preprocess_image(image_path):"""预处理自定义图像,使其符合模型输入要求"""# 打开图像并转换为灰度图(单通道)image = Image.open(image_path).convert('L')# 调整图像大小为28x28像素(如果不是)if image.size != (28, 28):image = image.resize((28, 28), Image.Resampling.LANCZOS)# 将PIL图像转换为numpy数组以便处理img_array = np.array(image)# 预处理:二值化和颜色反转# MNIST数据集中数字为白色(255),背景为黑色(0)if img_array.mean() > 127:  # 如果平均像素值大于127,说明可能是黑底白字img_array = 255 - img_array  # 颜色反转# 将numpy数组转换为PyTorch张量并添加批次维度img_tensor = transforms.ToTensor()(img_array).unsqueeze(0)# 使用MNIST数据集的均值和标准差进行归一化img_tensor = transforms.Normalize((0.1307,), (0.3081,))(img_tensor)return image, img_tensor  # 返回原始图像和处理后的张量

2.3 预测

def predict_digit(image_path):"""预测自定义图像中的数字"""# 创建模型实例model = CNN()# 加载预训练模型权重model.load_state_dict(torch.load('mnist_cnn_model.pth'))# 设置模型为评估模式(关闭Dropout等训练特有的层)model.eval()# 预处理输入图像original_img, img_tensor = preprocess_image(image_path)# 预测过程,不计算梯度以提高效率with torch.no_grad():# 前向传播,得到模型输出output = model(img_tensor)# 应用softmax将输出转换为概率分布probabilities = torch.softmax(output, dim=1)# 获取最高概率及其对应的数字类别confidence, predicted = torch.max(probabilities, 1)

三,测试

3.1 测试方法

如上文代码所示,我这里用的测试图片是自己定义图片,使用电脑自带的paint绘图软件,设置画布为28*28像素,黑底白字,手动写入一个字进行预测

3.2 测试结果

        预测5的置信度为99.94%

        预测0的置信度为99.99%

        预测7的置信度为92.33%(尽管这个“7”写的很不好但是并不影响预测结果)


四 ,总结

        卷积神经网络(CNN)在图像分类中相比全连接网络(FNN)具有显著优势:通过局部连接权重共享机制,CNN 大幅减少参数量,避免全连接网络因输入维度高导致的参数爆炸问题,计算效率更高且不易过拟合;CNN 通过卷积核逐层提取图像的局部特征(如边缘、纹理),结合池化层的平移不变性,能自动学习从低级到高级的层级化语义特征,而全连接网络将图像展平为向量,完全忽略像素空间关系,需依赖人工特征或大量数据学习;此外,CNN 的卷积结构天然具备正则化效果,对数据量需求更低,训练速度更快,且通过可视化卷积核和特征图可直观解释其对图像模式的捕捉过程,而全连接网络的特征表示缺乏可解释性。


五,完整代码

5.1 模型训练部分代码

import torch  # 导入PyTorch库,用于深度学习
import torch.nn as nn  # 导入PyTorch的神经网络模块
import torch.optim as optim  # 导入PyTorch的优化器模块
from torchvision import datasets, transforms  # 从torchvision导入数据集和数据变换模块
from torch.utils.data import DataLoader  # 导入数据加载器模块# 定义CNN模型
class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()  # 调用父类的初始化方法self.conv1 = nn.Conv2d(1, 32, kernel_size=3)  # 定义第一个卷积层,输入通道1,输出通道32,卷积核大小3x3self.conv2 = nn.Conv2d(32, 64, kernel_size=3)  # 定义第二个卷积层,输入通道32,输出通道64,卷积核大小3x3self.pool = nn.MaxPool2d(2, 2)  # 定义最大池化层,池化核大小2x2self.dropout1 = nn.Dropout2d(0.25)  # 定义第一个Dropout层,随机丢弃25%的神经元self.fc1 = nn.Linear(64 * 12 * 12, 128)  # 定义第一个全连接层,输入维度64*12*12,输出维度128self.dropout2 = nn.Dropout(0.5)  # 定义第二个Dropout层,随机丢弃50%的神经元self.fc2 = nn.Linear(128, 10)  # 定义输出层,输入维度128,输出维度10(对应10个数字类别)def forward(self, x):x = torch.relu(self.conv1(x))  # 对第一个卷积层的输出应用ReLU激活函数x = self.pool(torch.relu(self.conv2(x)))  # 对第二个卷积层的输出应用ReLU激活函数,然后进行最大池化x = self.dropout1(x)  # 应用第一个Dropout层x = x.view(-1, 64 * 12 * 12)  # 将张量展平为一维向量,-1表示自动推断批次维度x = torch.relu(self.fc1(x))  # 对第一个全连接层的输出应用ReLU激活函数x = self.dropout2(x)  # 应用第二个Dropout层x = self.fc2(x)  # 通过输出层return x  # 返回模型的输出# 数据预处理
transform = transforms.Compose([transforms.ToTensor(),  # 将图像转换为张量transforms.Normalize((0.1307,), (0.3081,))  # 使用MNIST数据集的均值和标准差进行归一化
])# 加载数据
train_dataset = datasets.MNIST('data', train=True, download=True, transform=transform)  # 加载MNIST训练数据集
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)  # 创建数据加载器,批次大小为64,打乱数据# 初始化模型、损失函数和优化器
model = CNN()  # 创建CNN模型实例
criterion = nn.CrossEntropyLoss()  # 定义交叉熵损失函数
optimizer = optim.Adam(model.parameters(), lr=0.001)  # 定义Adam优化器,学习率为0.001# 训练模型
def train(epochs):model.train()  # 设置模型为训练模式for epoch in range(epochs):  # 进行指定轮数的训练running_loss = 0.0  # 初始化本轮的损失累加器for batch_idx, (data, target) in enumerate(train_loader):  # 遍历数据加载器中的每个批次optimizer.zero_grad()  # 梯度清零output = model(data)  # 前向传播,计算模型输出loss = criterion(output, target)  # 计算损失loss.backward()  # 反向传播,计算梯度optimizer.step()  # 更新模型参数running_loss += loss.item()  # 累加当前批次的损失if batch_idx % 100 == 0:  # 每100个批次打印一次损失print(f'Epoch {epoch + 1}, Batch {batch_idx}, Loss: {loss.item():.6f}')print(f'Epoch {epoch + 1} completed, Average Loss: {running_loss / len(train_loader):.6f}')  # 打印本轮平均损失# 执行训练并保存模型
if __name__ == '__main__':train(epochs=5)  # 调用训练函数,训练5轮torch.save(model.state_dict(),'mnist_cnn_model.pth')  # 保存模型的参数print("模型已保存为: mnist_cnn_model.pth")  # 打印保存模型的信息

5.2 模型测试部分代码

# 导入PyTorch深度学习框架及其神经网络模块
import torch
import torch.nn as nn
# 导入torchvision的图像变换工具
from torchvision import transforms
# 导入PIL库用于图像处理
from PIL import Image
# 导入matplotlib用于可视化
import matplotlib.pyplot as plt
# 导入numpy用于数值计算
import numpy as np
# 导入os模块用于文件和路径操作
import os# 设置matplotlib的字体,确保中文正常显示
plt.rcParams['font.sans-serif'] = ['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC']
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题# 定义与训练时相同的CNN模型架构
class CNN(nn.Module):def __init__(self):# 调用父类初始化方法super(CNN, self).__init__()# 第一个卷积层:输入1通道(灰度图),输出32通道,卷积核3x3self.conv1 = nn.Conv2d(1, 32, kernel_size=3)# 第二个卷积层:输入32通道,输出64通道,卷积核3x3self.conv2 = nn.Conv2d(32, 64, kernel_size=3)# 最大池化层:核大小2x2,步长2self.pool = nn.MaxPool2d(2, 2)# Dropout层:训练时随机丢弃25%的神经元,防止过拟合self.dropout1 = nn.Dropout2d(0.25)# 第一个全连接层:输入维度64*12*12,输出128self.fc1 = nn.Linear(64 * 12 * 12, 128)# Dropout层:训练时随机丢弃50%的神经元self.dropout2 = nn.Dropout(0.5)# 输出层:输入128,输出10个类别(对应0-9数字)self.fc2 = nn.Linear(128, 10)def forward(self, x):# 第一层卷积+ReLU激活x = torch.relu(self.conv1(x))# 第二层卷积+ReLU激活+池化x = self.pool(torch.relu(self.conv2(x)))# 应用Dropoutx = self.dropout1(x)# 将多维张量展平为一维向量(64*12*12)x = x.view(-1, 64 * 12 * 12)# 第一个全连接层+ReLU激活x = torch.relu(self.fc1(x))# 应用Dropoutx = self.dropout2(x)# 输出层,得到未归一化的预测分数x = self.fc2(x)return xdef preprocess_image(image_path):"""预处理自定义图像,使其符合模型输入要求"""# 打开图像并转换为灰度图(单通道)image = Image.open(image_path).convert('L')# 调整图像大小为28x28像素(如果不是)if image.size != (28, 28):image = image.resize((28, 28), Image.Resampling.LANCZOS)# 将PIL图像转换为numpy数组以便处理img_array = np.array(image)# 预处理:二值化和颜色反转# MNIST数据集中数字为白色(255),背景为黑色(0)if img_array.mean() > 127:  # 如果平均像素值大于127,说明可能是黑底白字img_array = 255 - img_array  # 颜色反转# 将numpy数组转换为PyTorch张量并添加批次维度img_tensor = transforms.ToTensor()(img_array).unsqueeze(0)# 使用MNIST数据集的均值和标准差进行归一化img_tensor = transforms.Normalize((0.1307,), (0.3081,))(img_tensor)return image, img_tensor  # 返回原始图像和处理后的张量def predict_digit(image_path):"""预测自定义图像中的数字"""# 创建模型实例model = CNN()# 加载预训练模型权重model.load_state_dict(torch.load('mnist_cnn_model.pth'))# 设置模型为评估模式(关闭Dropout等训练特有的层)model.eval()# 预处理输入图像original_img, img_tensor = preprocess_image(image_path)# 预测过程,不计算梯度以提高效率with torch.no_grad():# 前向传播,得到模型输出output = model(img_tensor)# 应用softmax将输出转换为概率分布probabilities = torch.softmax(output, dim=1)# 获取最高概率及其对应的数字类别confidence, predicted = torch.max(probabilities, 1)# 创建可视化窗口plt.figure(figsize=(12, 4))# 子图1:显示原始输入图像plt.subplot(1, 3, 1)plt.imshow(original_img, cmap='gray')plt.title('原始图像')plt.axis('off')  # 关闭坐标轴显示# 子图2:显示模型实际输入(归一化后的图像)plt.subplot(1, 3, 2)plt.imshow(img_tensor[0][0], cmap='gray')plt.title('模型输入')plt.axis('off')# 子图3:显示预测结果和置信度条形图plt.subplot(1, 3, 3)plt.bar(range(10), probabilities[0].numpy())plt.xticks(range(10))  # 设置x轴刻度为0-9plt.title(f'预测结果: {predicted.item()} (置信度: {confidence.item() * 100:.2f}%)')plt.xlabel('数字')plt.ylabel('概率')# 自动调整子图布局plt.tight_layout()# 显示图像plt.show()# 返回预测结果和置信度return predicted.item(), confidence.item() * 100if __name__ == '__main__':# 指定要测试的图像路径,请替换为实际路径image_path = r"C:\Users\10532\Desktop\Study\test\Untitled.png"# 检查文件是否存在if not os.path.exists(image_path):print(f"错误:文件 '{image_path}' 不存在")else:# 执行预测digit, confidence = predict_digit(image_path)print(f"预测结果: {digit},置信度: {confidence:.2f}%")

相关文章:

基于MNIST数据集的手写数字识别(CNN)

目录 一,模型训练 1.1 数据集介绍 1.2 CNN模型层结构 1.3 定义CNN模型 1.4 神经网络的前向传播过程 1.5 数据预处理 1.6 加载数据 1.7 初始化 1.8 模型训练过程 1.9 保存模型 二,模型测试 2.1 定义与训练时相同的CNN模型架构 2.2 图像的预处…...

MYSQL创建索引的原则

创建索引的原则包括: 表中的数据量超过10万以上时考虑创建索引。 选择查询频繁的字段作为索引,如查询条件、排序字段或分组字段。 尽量使用复合索引,覆盖SQL的返回值。 如果字段区分度不高,可以将其放在组合索引的后面。 对于…...

运行Spark程序-在shell中运行

Spark Shell运行程序步骤 启动Spark Shell 根据语言选择启动命令: Scala版本(默认):执行spark-shellPython版本:执行pyspark 数据加载示例 读取本地文本文件: // Scala版本 val textData sc.textFile(…...

idea Maven 打包SpringBoot可执行的jar包

背景&#xff1a;当我们需要坐联调测试的时候&#xff0c;需要对接前端同事&#xff0c;则需要打包成jar包直接运行启动服务 需要将项目中的pom文件增加如下代码配置&#xff1a; <build><plugins><plugin><groupId>org.springframework.boot</gr…...

HarmonyOs开发之——— ArkWeb 实战指南

HarmonyOs开发之——— ArkWeb 实战指南 谢谢关注!! 前言:上一篇文章主要介绍HarmonyOs开发之———合理使用动画与转场:CSDN 博客链接 一、ArkWeb 组件基础与生命周期管理 1.1 Web 组件核心能力概述 ArkWeb 的Web组件支持加载本地或在线网页,提供完整的生命周期回调体…...

国标GB/T 12536-90滑行试验全解析:纯电动轻卡行驶阻力模型参数精准标定

摘要 本文以国标GB/T 12536-90为核心框架&#xff0c;深度解析纯电动轻卡滑行试验的完整流程与数据建模方法&#xff0c;提供&#xff1a; 法规级试验规范&#xff1a;从环境要求到数据采集全流程详解行驶阻力模型精准标定&#xff1a;最小二乘法求解 ( FAv^2BvC ) 的MATLAB实…...

初识——QT

QT安装方法 一、项目创建流程 创建项目 入口&#xff1a;通过Qt Creator的欢迎页面或菜单栏&#xff08;文件→新建项目&#xff09;创建新项目。 项目类型&#xff1a;选择「Qt Widgets Application」。 路径要求&#xff1a;项目路径需为纯英文且不含特殊字符。 构建系统…...

几何_平面方程表示_点+向量形式

三维平面方程可以写成&#xff1a; π : n ⊤ X d 0 \boxed{\pi: \mathbf{n}^\top \mathbf{X} d 0} π:n⊤Xd0​ &#x1f4d0; 一、几何直观解释 ✅ 平面是“法向量 平面上一点”定义的集合 一个平面可以由&#xff1a; 一个单位法向量 n ∈ R 3 \mathbf{n} \in \mat…...

学习alpha

(sign(ts_delta(volume, 1)) * (-1 * ts_delta(close, 1))) 这个先用sign操作符 sign.如果输入NaN则返回NaN 在金融领域&#xff0c;符号函数 sign(x) 与 “基础”&#xff08;Base&#xff09;的组合概念可结合具体场景解读&#xff0c;以下从不同金融场景分析其潜在意义&…...

Java - Junit框架

单元测试&#xff1a;针对最小的功能单元(方法)&#xff0c;编写测试代码对该功能进行正确性测试。 Junit&#xff1a;Java语言实现的单元测试框架&#xff0c;很多开发工具已经集成了Junit框架&#xff0c;如IDEA。 优点 编写的测试代码很灵活&#xff0c;可以指某个测试方法…...

秒删node_modules[无废话版]

“npm install”命令带来的便利和高效让人感到畅快&#xff0c;但删除依赖包时却可能带来诸多困扰。特别是在项目依赖关系较为复杂的情况下&#xff0c;node_modules文件夹的体积往往会膨胀至数百MB甚至几个GB&#xff0c;手动删除时进度条长时间转圈&#xff0c;令人感到焦虑和…...

kkFileView文件文档在线预览镜像分享

kkFileView为文件文档在线预览解决方案&#xff0c;该项目使用流行的spring boot搭建&#xff0c;易上手和部署&#xff0c;基本支持主流办公文档的在线预览&#xff0c;如doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,rar,图片,视频,音频等等 开源项目地址 https://gitee.com/kek…...

实例分割AI数据标注 ISAT自动标注工具使用方法

文章目录 🌕ISAT安装和启动方法🌕下载和使用AI分割模型🌙SAM模型性能排行🌙手动下载sam模型 & sam模型下载路径🌕使用方法🌙从file中导入图片🌙点击左上角的图标进入分割模式🌙鼠标左键点击画面中的人则自动标注🌙点击右键该区域不标注🌙一个人一个人的…...

Qt图表绘制(QtCharts)- 性能优化(13)

文章目录 1 批量替换代替追加1.1 测试11.2 测试21.3 测试3 2 开启OpenGL2.1 测试12.2 测试22.3 测试32.4 测试4 更多精彩内容&#x1f449;内容导航 &#x1f448;&#x1f449;Qt开发 &#x1f448;&#x1f449;QtCharts绘图 &#x1f448;&#x1f449;python开发 &#x1f…...

Spring Cloud动态配置刷新:@RefreshScope与@Component的协同机制解析

在微服务架构中&#xff0c;动态配置管理是实现服务灵活部署、快速响应业务变化的关键能力之一。Spring Cloud 提供了基于 RefreshScope 和 Component 的动态配置刷新机制&#xff0c;使得开发者可以在不重启服务的情况下更新配置。 本文将深入解析 RefreshScope 与 Component…...

部署docker上的redis,idea一直显示Failed to connect to any host resolved for DNS name

参考了https://blog.csdn.net/m0_74216612/article/details/144145127 这篇文章&#xff0c;关闭了centos的防火墙&#xff0c;也修改了redis.conf文件&#xff0c;还是一直显示Failed to connect to any host resolved for DNS name。最终发现是腾讯云服务器那一层防火墙没…...

如何在 Windows 10 或 11 上使用命令提示符安装 PHP

我们可以在 Windows 上从其官方网站下载并安装 PHP 的可执行文件,但使用命令提示符或 PowerShell 更方便。 PHP 并不是一种新的或不为人知的脚本语言,它已经存在并被全球数千名网络开发人员使用。它以开源许可并分发,广泛用于 LAMP 堆栈中。然而,与 Linux 相比,它在 Wind…...

RK3588 ADB使用

安卓adb操作介绍 adb&#xff08;Android Debug Bridge&#xff09;是一个用于与安卓设备进行通信和控制的工具。adb可以通过USB或无线网络连接安卓设备&#xff0c;执行各种命令&#xff0c;如安装和卸载应用&#xff0c;传输文件&#xff0c;查看日志&#xff0c;运行shell命…...

Vue 3.0双向数据绑定实现原理

Vue3 的数据双向绑定是通过响应式系统来实现的。相比于 Vue2&#xff0c;Vue3 在响应式系统上做了很多改进&#xff0c;主要使用了 Proxy 对象来替代原来的 Object.defineProperty。本文将介绍 Vue3 数据双向绑定的主要特点和实现方式。 1. 响应式系统 1.1. Proxy对象 Vue3 …...

Please install it with pip install onnxruntime

无论怎么安装都是 Please install it with pip install onnxruntime 我python 版本是3.11 &#xff0c;我换成3.10 解决了...

java -jar命令运行 jar包时如何运行外部依赖jar包

java -jar命令运行 jar包时如何运行外部依赖jar包 场景&#xff1a; 打包发不完,运行时。发现一个问题&#xff0c; java java.lang.NoClassDefFoundError: org/apache/commons/lang3/ArrayUtils 显示此&#xff0c;基本表明&#xff0c;没有这个依赖&#xff0c;如果在开发…...

低损耗高效能100G O Band DWDM 10km光模块 | 支持密集波分复用

目录 前言 一、产品概述 100G QSFP28 O Band DWDM 10km光模块核心特点包括&#xff1a; 二、为何选择O Band DWDM方案&#xff1f; 1.低色散损耗&#xff0c;传输更稳定 2.兼容性强 三、典型应用场景 1.数据中心互联&#xff08;DCI&#xff09; 2.企业园区/智慧城市组网 3.电信…...

【解决分辨数字】2021-12-16

缘由用C语言解决分辨数字-编程语言-CSDN问答 int a 0, w 0, aa[6]{};cin >> a;while (a)aa[w] a % 10, a / 10, w;cout << w << endl;while (a<w)cout << aa[a] << ends, aa[5] * 10, aa[5] aa[a];cout << endl << aa[5] <…...

el-tree结合checkbox实现数据回显

组件代码 <el-tree:data"vertiList"show-checkboxnode-key"id":props"defaultProps"ref"treeRefx"class"custom-tree"check-change"handleCheckChange"> </el-tree>获取选择的节点 handleCheckChan…...

第二十六天打卡

全局变量 global_var 全局变量是定义在函数、类或者代码块外部的变量&#xff0c;它在整个程序文件内都能被访问。在代码里&#xff0c; global_var 就是一个全局变量&#xff0c;下面是相关代码片段&#xff1a; print("\n--- 变量作用域示例 ---") global_var …...

阿里云ECS部署Dify

一&#xff1a;在ECS上面安装Docker 关防火墙 sudo systemctl stop firewalld 检查防火墙状态 systemctl status firewalld sudo yum install -y yum-utils device-mapper-persistent-data lvm2 设置阿里镜像源&#xff0c;安装并启动docker [base] nameCentOS-$releas…...

【线段树】P4588 [TJOI2018] 数学计算|普及+

本文涉及知识点 C线段树 [TJOI2018] 数学计算 题目描述 小豆现在有一个数 x x x&#xff0c;初始值为 1 1 1。小豆有 Q Q Q 次操作&#xff0c;操作有两种类型&#xff1a; 1 m&#xff1a;将 x x x 变为 x m x \times m xm&#xff0c;并输出 x m o d M x \bmod M…...

日志与策略模式

什么是设计模式 IT⾏业 ,为了让 菜鸡们不太拖⼤佬的后腿, 于是⼤佬们针对⼀些经典的常⻅的场景, 给定了⼀些对应的解决⽅案, 这个就是 设计模式 日志认识 计算机中的⽇志是记录系统和软件运⾏中发⽣事件的⽂件&#xff0c;主要作⽤是监控运⾏状态、记录异常信 息&#xff…...

Jenkins 最佳实践

1. 在Jenkins中避免调度过载 过载Jenkins以同时运行多个作业可能导致资源竞争、构建速度变慢和系统性能问题。分配作业启动时间可以防止瓶颈&#xff0c;并确保更顺畅的执行。如何实现&#xff1f; 在Cron表达式中使用H&#xff1a;引入抖动&#xff08;jitter&#xff09;&a…...

天能股份SAP系统整合实战:如何用8个月实现零业务中断的集团化管理升级

目录 天能股份SAP系统整合案例&#xff1a;技术驱动集团化管理的破局之路 一、企业背景&#xff1a;新能源巨头的数字化挑战 二、项目难点&#xff1a;制造业的特殊攻坚战 1. 生产连续性刚性需求 2. 数据整合三重障碍 3. 资源限制下的技术突围 三、解决方案&#xff1a;S…...