Kaggle竞赛——手写数字识别(Digit Recognizer)

目录

  • 1. 数据集介绍
  • 2. 数据分析
  • 3. 数据处理与封装
    • 3.1 数据集划分
    • 3.2 将数据转为tensor张量
    • 3.3 数据封装
  • 4. 模型训练
    • 4.1 定义功能函数
    • 4.1 resnet18模型
    • 4.3 CNN模型
    • 4.4 FCNN模型
  • 5. 结果分析
    • 5.1 混淆矩阵
    • 5.2 查看错误分类的样本
  • 6. 加载最佳模型
  • 7. 参考文献

本次手写数字识别使用了resnet18(比resnet50精度更好)、CNN和FCNN三种模型,精度上resnet18 > CNN > FCNN,最终提交到官网的测试集精度为0.983,排名为758(提交时间:2024年9月1日)。数据集、代码、python虚拟环境和训练后的最佳模型已打包上传到Gitee,[点击直达]。
在这里插入图片描述

1. 数据集介绍

竞赛使用的是 MNIST (Modified National Institute of Standards and Technology, 美国国家标准与技术研究院修改版) 手写图像数据集,其中训练集42000条,测试集28000条,每条数据有784 个像素点,即原始图像的像素为 28 * 28。训练集中的Label列表示手写数字的类别(共10个类别,0-10)。

2. 数据分析

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_splittrain = pd.read_csv("D:/Desktop/kaggle数据集/digit-recognizer/train.csv")
test  = pd.read_csv("D:/Desktop/kaggle数据集/digit-recognizer/test.csv")
train.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 42000 entries, 0 to 41999
Columns: 785 entries, label to pixel783
dtypes: int64(785)
memory usage: 251.5 MB
test.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 28000 entries, 0 to 27999
Columns: 784 entries, pixel0 to pixel783
dtypes: int64(784)
memory usage: 167.5 MB

查看空缺值

#--------------------------------------------------------------------------------------------------------------------------------#
# train_data.isnull(): 返回一个与 train_data 相同维度的布尔值数据框,其中 True 表示该位置存在缺失值,False 表示没有缺失值
# any(): 对每一列进行操作,如果某列中存在至少一个 True 那么这一列的结果就是 True;否则就是 False,结果是一个布尔类型的 Series
# describe(): 统计摘要,包括总列数、唯一值个数、最频繁出现的值(top)及其出现频率(freq)
#--------------------------------------------------------------------------------------------------------------------------------#
train.isnull().any().describe()
count       785
unique        1
top       False
freq        785
dtype: object

由结果可知,仅有一个唯一值False,且出现785次,故训练集中无缺失值。

查看类别统计

sns.countplot(x=train['label']);

在这里插入图片描述

3. 数据处理与封装

3.1 数据集划分

将训练集划分为训练集和验证集。

# 分割特征和标签
train_labels = train["label"]
train= train.drop(labels=["label"], axis=1)# 划分训练集和验证集
X_train, X_val, y_train, y_val = train_test_split(train, train_labels, test_size = 0.2, random_state=41)
print("训练集大小:{},验证集大小:{}".format(len(X_train), len(X_val)))
训练集大小:33600,验证集大小:8400

3.2 将数据转为tensor张量

dataFrameSeries类型需要先转为numpy类型,

import torch
from torch.utils.data import DataLoader, TensorDatasetX_train_tensor = torch.tensor(X_train.values, dtype = torch.float32)
y_train_tensor = torch.tensor(y_train.values)X_val_tensor   = torch.tensor(X_val.values, dtype = torch.float32)
y_val_tensor   = torch.tensor(y_val.values)test_tensor = torch.tensor(test.values, dtype = torch.float32)

3.3 数据封装

使用TensorDataset创建创建包含数据特征和数据类别的tensor数据集,再用DataLoader划分封装数据集。封装数据集时,训练集中的shuffle参数设置为True(随机打乱数据),可以防止模型学习到数据的顺序,从而提高模型的泛化能力;验证集和测试集shuffle参数设置为False,能够保证测试集预测结果的一致性和可比性。

train_tensor = TensorDataset(X_train_tensor, y_train_tensor)
train_loader = DataLoader(train_tensor, batch_size=100, shuffle=True)val_tensor   = TensorDataset(X_val_tensor, y_val_tensor)
val_loader   = DataLoader(val_tensor, batch_size=100, shuffle=False)test_loader  = DataLoader(test_tensor, batch_size = 100, shuffle=False)

可视化训练集中的一张图像

plt.imshow(train.values[10].reshape(28,28), cmap='gray')
plt.axis("off")
plt.title(str(train_labels.values[10]));

在这里插入图片描述

4. 模型训练

4.1 定义功能函数

定义模型的训练和验证函数:

"""
模型训练函数
Params:epoch:        训练轮次model:        预定义模型dataloader:   批处理数据criterion:    损失函数(交叉熵)optimizer:    优化器
Returnsrunning_loss/len(train_loader):本轮次(遍历一遍训练集)的平均损失sum_correct/train_num:本轮次(遍历一遍训练集)准确率
"""
def model_train(epoch, model, model_name, dataloader, criterion, optimizer):
#     print("-------------------------Training-------------------------")# 设置模型为训练模式model.train()running_loss = 0.0# 训练集大小train_num = len(X_train)#记录遍历一轮数据集后分类正确的样本数sum_correct = 0for step, data in enumerate(dataloader):images, labels = dataif model_name == 'resnet18':#-------------------------------------------------------------------------------------------------## ResNet18 期望输入的形状为 [batch_size, channels, height, width],其中 channels 为 3(RGB 图像)# expand(): 沿指定维度扩展张量(但不复制数据,只改变视图)#-------------------------------------------------------------------------------------------------#images = images.view(-1, 1, 28, 28).expand(-1, 3, -1, -1)if model_name == 'cnn':# 自定义CNN的输入维度为 1images = images.view(-1, 1, 28, 28)# 模型为FCNN时无需转换images = images.to(device)labels = labels.to(device)# 清除上一次迭代的梯度信息,防止梯度累积optimizer.zero_grad()#-------------------------------------------------------------------------------------------------## outputs的尺寸[每次输入的样本数(batch_size), 类别数]# 表示的含义:对应样本被分为某一类别的概率#-------------------------------------------------------------------------------------------------#outputs = model(images)# 计算损失值loss = criterion(outputs, labels)#-------------------------------------------------------------------------------------------------## 计算损失函数相对于模型参数的梯度,并将这些梯度存储在每个参数的 .grad 属性中。# 随后,优化器会使用这些梯度来更新模型参数,从而逐步最小化损失函数,实现模型的训练#-------------------------------------------------------------------------------------------------#loss.backward()# 使用优化器 optimizer 更新模型参数optimizer.step()running_loss += loss.item()#-------------------------------------------------------------------------------------------------## torch.max()函数返回两个值:每行的最大值和最大值的索引# _:表示忽略了第一个返回值(每行的最大值)# 1:寻找每行的最大值和索引#-------------------------------------------------------------------------------------------------#_, predicted = torch.max(outputs, 1)#-------------------------------------------------------------------------------------------------## sum(): 将布尔张量转换为整数张量并对其进行求和,得到正确预测的总数。# 布尔值 True 计算为 1,False 计算为 0。# item(): 将单元素张量转换为 Python 标量值,便于计算#-------------------------------------------------------------------------------------------------#correct = (predicted == labels).sum().item()sum_correct += correcttrain_acc = correct / len(labels)    
#         print("[Epoch {}, step: {}] Train Loss: {:.4f}, Train Acc: {:.2f}%".format(epoch + 1, step+1, loss, train_acc*100))#     print("-------------------------Training-------------------------")return running_loss/len(train_loader), sum_correct/train_num"""
模型评估函数
Params:epoch:        训练轮次model:        预定义模型dataloader:   批处理数据criterion:    损失函数(交叉熵)
Returnsrunning_loss/len(train_loader):本轮次(遍历一遍验证集)的平均损失sum_correct/train_num:本轮次(遍历一遍验证集)准确率
"""
def model_validate(epoch, model, model_name, dataloader, criterion):
#     print("------------------------Validating------------------------")# 设置模型为测试模式model.eval()val_loss = 0.0# 训练集大小val_num = len(X_val)sum_correct  = 0# 禁止梯度反传with torch.no_grad():for step, data in enumerate(dataloader):images, labels = dataif model_name == 'resnet18':#-------------------------------------------------------------------------------------------------## ResNet18 期望输入的形状为 [batch_size, channels, height, width],其中 channels 为 3(RGB 图像)# expand(): 沿指定维度扩展张量(但不复制数据,只改变视图)#-------------------------------------------------------------------------------------------------#images = images.view(-1, 1, 28, 28).expand(-1, 3, -1, -1)if model_name == 'cnn':# 自定义CNN的输入维度为 1images = images.view(-1, 1, 28, 28)# 模型为FCNN时无需转换images = images.to(device)labels = labels.to(device)outputs = model(images)# 计算损失值loss = criterion(outputs, labels)val_loss += loss.item()#-------------------------------------------------------------------------------------------------## torch.max()函数返回两个值:每行的最大值和最大值的索引# _:表示忽略了第一个返回值(每行的最大值)# 1:寻找每行的最大值和索引#-------------------------------------------------------------------------------------------------#_, predicted = torch.max(outputs, 1)correct = (predicted == labels).sum().item()sum_correct += correcttotal = len(labels)val_acc = correct / total
#             print("[Epoch {}, step: {}] Val Loss: {:.4f}, Val Acc: {:.2f}%".format(epoch + 1, step+1, loss, val_acc*100))#     print("------------------------Validating------------------------")return val_loss/len(train_loader), sum_correct/val_num

定义模型训练与验证的综合函数:

import torch.nn as nn
import torch.optim as optim
"""
模型整体训练与验证函数
Params:model:        预定义模型
"""
def train_val(model, model_name):# 定义损失函数(交叉熵)和优化器criterion = nn.CrossEntropyLoss()optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)# 验证集上的最佳准确率和最佳轮次best_val_acc = 0.0best_epoch = 0  for epoch in range(10): # 模型训练train_loss, train_acc = model_train(epoch, model, model_name, train_loader, criterion, optimizer)train_losses.append(train_loss)train_accuracies.append(train_acc)# 模型验证val_loss, val_acc = model_validate(epoch, model, model_name, val_loader, criterion)val_losses.append(val_loss)val_accuracies.append(val_acc)if val_acc > best_val_acc:best_val_acc = val_accbest_epoch = epoch + 1torch.save(model.state_dict(), model_name+'_best_model.pth')  print("[第{}轮训练完成,训练集中 Loss:{},Accuracy:{}]".format(epoch+1, train_loss, train_acc))print("训练完成!最佳训练轮次:{},该轮次验证集上的准确率:{}".format(best_epoch, best_val_acc))

定义损失值和准确率的可视化函数:


"""
可视化损失值和准确率
"""
def loss_acc_plot(train_losses, val_losses, train_accuracies, val_accuracies):plt.figure(figsize=(12, 4))plt.subplot(1, 2, 1)# 默认情况下,plt.plot 会将 train_losses 的索引作为 X 轴的值plt.plot(train_losses, label='Train Loss')plt.plot(val_losses, label='Validation Loss')plt.xlabel('Epoch')plt.ylabel('Loss')plt.legend()plt.subplot(1, 2, 2)plt.plot(train_accuracies, label='Train Accuracy')plt.plot(val_accuracies, label='Validation Accuracy')plt.xlabel('Epoch')plt.ylabel('Accuracy')plt.legend()plt.tight_layout()

4.1 resnet18模型

from torchvision import models
# 使用GPU训练模型(如果GPU可用的话)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 调用resnet18
resnet_model = models.resnet18()
resnet_model = resnet_model.to(device)# 记录训练集和验证集的损失值和准确率
train_losses = []
val_losses = []
train_accuracies = []
val_accuracies = []train_val(resnet_model, "resnet18")
[1轮训练完成,训练集中 Loss:0.48536758923104834,Accuracy:0.9060714285714285]
[2轮训练完成,训练集中 Loss:0.05270050720095502,Accuracy:0.985]
[3轮训练完成,训练集中 Loss:0.02555189496238849,Accuracy:0.9938392857142857]
[4轮训练完成,训练集中 Loss:0.015233770400560129,Accuracy:0.9965773809523809]
[5轮训练完成,训练集中 Loss:0.007979269749263213,Accuracy:0.9988690476190476]
[6轮训练完成,训练集中 Loss:0.005160370017706771,Accuracy:0.9996428571428572]
[7轮训练完成,训练集中 Loss:0.0035936778385803336,Accuracy:0.9998511904761904]
[8轮训练完成,训练集中 Loss:0.0028507261213235324,Accuracy:0.9999107142857143]
[9轮训练完成,训练集中 Loss:0.002293311161511589,Accuracy:0.9998809523809524]
[10轮训练完成,训练集中 Loss:0.0019566422187857653,Accuracy:0.9998511904761904]
训练完成!最佳训练轮次:6,该轮次验证集上的准确率:0.9858333333333333

可视化损失值和准确率:

loss_acc_plot(train_losses, val_losses, train_accuracies, val_accuracies)

在这里插入图片描述

4.3 CNN模型

定义CNN模型结构:

class CNNModel(nn.Module):def __init__(self):super(CNNModel, self).__init__()# 卷积层 1self.cnn1 = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=5, stride=1, padding=0)self.relu1 = nn.ReLU()# 最大池化层 1self.maxpool1 = nn.MaxPool2d(kernel_size=2)# 卷积层 2self.cnn2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=5, stride=1, padding=0)self.relu2 = nn.ReLU() # 最大池化层 2self.maxpool2 = nn.MaxPool2d(kernel_size=2)# 全连接层self.fc1 = nn.Linear(32 * 4 * 4, 10) def forward(self, x):# 卷积层 1out = self.cnn1(x)out = self.relu1(out)#最大池化层 1out = self.maxpool1(out)# 卷积层 2 out = self.cnn2(out)out = self.relu2(out)# 最大池化层 2 out = self.maxpool2(out)# flatten层out = out.view(out.size(0), -1)# 全连接层out = self.fc1(out)return out

网络结构可视化:
在这里插入图片描述

上述结构图中,双层黄色块的第一层表示卷积操作,第二层表示ReLU()激活操作,红色块表示最大池化操作。16表示卷积操作后输出的的通道数,784表示卷积操作后输出的图像大小(宽度*高度)。


训练模型:

cnn_model = CNNModel()
cnn_model = cnn_model.to(device)# 记录训练集和验证集的损失值和准确率
train_losses = []
val_losses = []
train_accuracies = []
val_accuracies = []train_val(cnn_model, "cnn")
[1轮训练完成,训练集中 Loss:1.004740373009727,Accuracy:0.8109226190476191]
[2轮训练完成,训练集中 Loss:0.17581947764293068,Accuracy:0.945625]
[3轮训练完成,训练集中 Loss:0.13953285299551985,Accuracy:0.9569345238095238]
[4轮训练完成,训练集中 Loss:0.12599757561526662,Accuracy:0.9607738095238095]
[5轮训练完成,训练集中 Loss:0.11612535938842311,Accuracy:0.9638095238095238]
[6轮训练完成,训练集中 Loss:0.10294126443720113,Accuracy:0.9671726190476191]
[7轮训练完成,训练集中 Loss:0.09651396153051228,Accuracy:0.9698214285714286]
[8轮训练完成,训练集中 Loss:0.09004475945229864,Accuracy:0.9717857142857143]
[9轮训练完成,训练集中 Loss:0.08583687311537298,Accuracy:0.9727083333333333]
[10轮训练完成,训练集中 Loss:0.08039018868779142,Accuracy:0.9748214285714286]
训练完成!最佳训练轮次:9,该轮次验证集上的准确率:0.9721428571428572

可视化损失值和准确率:

loss_acc_plot(train_losses, val_losses, train_accuracies, val_accuracies)

在这里插入图片描述

4.4 FCNN模型

定义FCNN模型结构:

class FCNNModel(nn.Module):  def __init__(self, input_dim, hidden_dim, output_dim):super(FCNNModel, self).__init__()# 784 --> 150self.fc1 = nn.Linear(input_dim, hidden_dim) # 激活函数self.relu1 = nn.ReLU()# 150 --> 150self.fc2 = nn.Linear(hidden_dim, hidden_dim)# 激活函数self.tanh2 = nn.Tanh()# 150 --> 150self.fc3 = nn.Linear(hidden_dim, hidden_dim)# 激活函数self.elu3 = nn.ELU()# 150 --> 10self.fc4 = nn.Linear(hidden_dim, output_dim)  def forward(self, x):# 784 --> 150out = self.fc1(x)out = self.relu1(out)# 150 --> 150out = self.fc2(out)out = self.tanh2(out)# 150 --> 150out = self.fc3(out)out = self.elu3(out)# 150 --> 10out = self.fc4(out)return out

模型训练:

# 记录训练集和验证集的损失值和准确率
train_losses = []
val_losses = []
train_accuracies = []
val_accuracies = []input_dim = 28*28
# 可微调
hidden_dim = 150 
output_dim = 10fcnn_model = FCNNModel(input_dim, hidden_dim, output_dim)
fcnn_model = fcnn_model.to(device)
train_val(fcnn_model, "fcnn")
[1轮训练完成,训练集中 Loss:0.8977700323753414,Accuracy:0.7811904761904762]
[2轮训练完成,训练集中 Loss:0.3077347204089165,Accuracy:0.9172916666666666]
[3轮训练完成,训练集中 Loss:0.2244828560034789,Accuracy:0.9372619047619047]
[4轮训练完成,训练集中 Loss:0.18338089338725522,Accuracy:0.9476488095238095]
[5轮训练完成,训练集中 Loss:0.15651956990006424,Accuracy:0.9541071428571428]
[6轮训练完成,训练集中 Loss:0.1355396158483234,Accuracy:0.9603869047619048]
[7轮训练完成,训练集中 Loss:0.11753073033122789,Accuracy:0.965625]
[8轮训练完成,训练集中 Loss:0.10319345946135443,Accuracy:0.9705059523809524]
[9轮训练完成,训练集中 Loss:0.09024346410296857,Accuracy:0.974047619047619]
[10轮训练完成,训练集中 Loss:0.07875394061695606,Accuracy:0.9776785714285714]
训练完成!最佳训练轮次:10,该轮次验证集上的准确率:0.963452380952381

可视化损失值和准确率:

loss_acc_plot(train_losses, val_losses, train_accuracies, val_accuracies)

在这里插入图片描述

5. 结果分析

5.1 混淆矩阵

计算混淆矩阵,

from sklearn.metrics import confusion_matrix
cm = confusion_matrix(all_labels, all_predictions)
plt.figure(figsize=(5, 5))
sns.heatmap(cm, annot=True, fmt="d", cmap="Blues", cbar=False, xticklabels=range(10), yticklabels=range(10))
plt.xlabel("Predicted Label")
plt.ylabel("True Label")
plt.title("Confusion Matrix");

在这里插入图片描述
横轴为预测类别,纵轴为实际类别。对标线上的值表示模型正确预测的样本数量,非对角线上的值表示模型错误预测的样本数量。对角线(1, 1)中的值900表示实际类别为1的样本中有900条被正确预测为1;(1, 4)中的值为1表示实际类别为1的样本中有1个样本被错误预测为4。

5.2 查看错误分类的样本

incorrect_images = []
incorrect_labels = []
predicted_labels = []with torch.no_grad():for step, data in enumerate(val_loader):images, labels = dataimages = images.view(-1, 1, 28, 28)outputs = best_resnet_model(images.expand(-1, 3, -1, -1))_, predicted = torch.max(outputs, 1)for i in range(len(predicted)):if predicted[i] != labels[i]:incorrect_images.append(images[i])incorrect_labels.append(labels[i])predicted_labels.append(predicted[i])# 展示部分预测错误的样本
num_samples = 6
fig, axes = plt.subplots(nrows=2, ncols=num_samples // 2, figsize=(10, 6))
axes = axes.flatten()for i in range(num_samples):ax = axes[i]img = incorrect_images[i].reshape(28,28)ax.imshow(img, cmap='gray')ax.set_title(f"True: {incorrect_labels[i]}, Pred: {predicted_labels[i]}")ax.axis('off')

在这里插入图片描述

6. 加载最佳模型

保存的最佳模型中,resnet18CNNFCNN在验证集中的准确率分别为98.58%97.21%96.35%,因此选择resnet18模型来预测测试集。

best_model = models.resnet18()
best_model.load_state_dict(torch.load("./resnet18_best_model.pth"))
predictions = []
with torch.no_grad():for data in test_loader:images = data.view(-1, 1, 28, 28).expand(-1, 3, -1, -1)outputs = best_model(images)_, predicted = torch.max(outputs, 1)predictions.extend(predicted.numpy())
# 保存预测结果
submission = pd.DataFrame({'ImageId': range(1, len(test) + 1), 'Label': predictions})
# submission.to_csv('/kaggle/working/submission.csv', index=False)
print('Submission file created!')

7. 参考文献

[1] kaggle:Digit Recognizer《手写数字识别》你的第一个图像识别竞赛项目
[2] Pytorch Tutorial for Deep Learning Lovers

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

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

相关文章

Lenze伦茨E82ZBC, E82ZBB E82ZMBRB安装说明手测

Lenze伦茨E82ZBC, E82ZBB E82ZMBRB安装说明手测

景联文科技:提供高质量多模态数据标注,推动智能化转型

随着人工智能技术的快速发展&#xff0c;多模态数据标注成为推动智能系统更深层次理解和应用的关键技术之一。 作为行业领先的多模态数据标注服务商&#xff0c;景联文科技凭借其在技术、流程和人才方面的综合优势&#xff0c;推出了全面的多模态标注解决方案&#xff0c;助力…

828华为云征文|部署电影收藏管理器 Radarr

828华为云征文&#xff5c;部署电影收藏管理器 Radarr 一、Flexus云服务器X实例介绍1.1 云服务器介绍1.2 应用场景1.3 性能模式 二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 Radarr3.1 Radarr 介绍3.2 Docker 环境搭建3.3 Radarr 部署3.4 R…

枚举: C++和Python实现鸡兔同笼问题

作者制作不易&#xff0c;关注、点赞、收藏一下吧&#xff01; 目录 1.Python实现 2.C实现 1.Python实现 首先&#xff0c;我们需要输入头和脚的数量: head int(input("请输入头的数量: ")) feet int(input("请输入脚的数量: ")) input() 实现输入…

ChauffeurNet:通过模仿最佳驾驶和合成最坏情况进行学习驾驶

ChauffeurNet: Learning to Drive by Imitating the Best and Synthesizing the Worst ChauffeurNet&#xff1a;通过模仿最佳驾驶和合成最坏情况进行学习驾驶 https://arxiv.org/abs/1812.03079 Abstract Our goal is to train a policy for autonomous driving via imit…

基于卷积神经网络的磨削平板类零件擦伤检测

基于卷积神经网络的磨削平板类零件擦伤检测 前言正文 前言 还记得读研那会儿刚学习完了卷积神经网络&#xff0c;初步学会了最基础的分类问题&#xff0c;当时也有点python基础&#xff0c;同时对TensorFlow也有点入门了。正好我的课题中有一类缺陷比较难以用传统方法识别判断&…

【LeetCode】01.两数之和

题目要求 做题链接&#xff1a;1.两数之和 解题思路 我们这道题是在nums数组中找到两个两个数使得他们的和为target&#xff0c;最简单的方法就是暴力枚举一遍即可&#xff0c;时间复杂度为O&#xff08;N&#xff09;&#xff0c;空间复杂度为O&#xff08;1&#xff09;。…

【JAVA入门】Day34 - Stream流

【JAVA入门】Day34 - Stream流 文章目录 【JAVA入门】Day34 - Stream流一、Stream 流的作用和使用步骤1.Stream流的创建&#xff0c;数据的添加2. Stream流的中间方法3. Stream流的终结方法 Stream 流有什么作用&#xff1f;我们看一个例子&#xff1a; 【练习】需求&#xff…

C++入门(01)VisualStudio2022社区版HelloWorld

文章目录 1. 下载社区版2. 安装3. 启动4. 创建新项目5. C空项目6. 项目名称和位置7. 创建后&#xff0c;出现“新增功能”&#xff0c;关闭即可8. 解决方案和项目9. 新建源文件10. 编辑第一个C程序11. 运行该程序12. Debug文件夹13. 用好Microsoft Learn 1. 下载社区版 访问&a…

JavaScript 循环分支语句-dowhile循环

do/while 循环是 while 循环的变体。该循环会在检查条件是否为真之前执行一次代码块&#xff0c;然后如果条件为真的话&#xff0c;就会重复这个循环。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta htt…

网页时装购物系统:Spring Boot框架的创新设计

第1章 绪论 1.1背景及意义 随着社会的快速发展&#xff0c;计算机的影响是全面且深入的。人们生活水平的不断提高&#xff0c;日常生活中人们对时装购物系统方面的要求也在不断提高&#xff0c;喜欢购物的人数更是不断增加&#xff0c;使得时装购物系统的开发成为必需而且紧迫的…

一种非接触式智能垃圾桶设计(论文+源码+实物)

1系统方案设计 通过对需求展开分析&#xff0c;本设计非接触式智能垃圾桶采用STM32F103单片机作为控制器&#xff0c;通过红外传感器实现垃圾桶的满溢检测&#xff0c;通过三个SG90舵机分别控制可回收、不可回收、其他垃圾桶盖的开关&#xff0c;并通过WiFi通信模块将数据信息…

EmguCV学习笔记 VB.Net 9.2 VideoWriter类

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。 教程VB.net版本请访问…

c++一个数因子和(快速求解)

void 一个数因子和(int 整数) {//缘由https://ask.csdn.net/questions/1054457#answer_1251715int he 0, j 0; string a "";while (j < 整数)if (!(整数%j))he j, a to_string(j) "";cout << a << "的因子和&#xff1a;" …

Opencv中的直方图(1)计算反向投影直方图函数calcBackProject()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算直方图的反向投影。 cv::calcBackProject 函数计算直方图的反向投影。也就是说&#xff0c;类似于 calcHist&#xff0c;在每个位置 (x, y)…

ITK-高斯滤波

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 高斯滤波原理 高斯滤波&#xff08;Gaussian Blur&#xff09;是数字图像处理中常见的一种平滑滤波器&#xff0c;旨在通过模糊处…

OpenCV结构分析与形状描述符(10)检测并提取轮廓函数findContours()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在二值图像中查找轮廓。 该函数使用算法 253从二值图像中检索轮廓。轮廓是有用的工具&#xff0c;可用于形状分析和对象检测与识别。参见 OpenC…

Linux下安装MySQL8.0

一、安装 1.下载安装包 先创建一个mysql目录&#xff0c;在将压缩包下载到此 # 下载tar包 wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz等待下载成功 2.解压mysql8.0安装包 tar xvJf mysql-8.0.20-linux-glibc2.12-x86…

visual studio 2022更新以后,之前的有些工程编译出错,升级到Visual studio Enterprise 2022 Preview解决

系列文章目录 文章目录 系列文章目录前言一、解决方法 前言 今天遇到一个问题&#xff1a;visual studio 2022升级成预览版以后&#xff0c;之前的有些工程编译出错。首先代码、项目设置都没有改变&#xff0c;只是更新了visual studio 2022。 在编译工程时&#xff0c;编译器…

Mybatis概述

目录 MyBatis环境搭建 1.创建一张表和表对应的实体类 2.导入MyBatis jar包&#xff0c;mysql 数据库驱动包 3.创建MyBatis全局配置文件 4.定义接口 5.创建sql映射文件 6.测试MyBatis 读取配置文件 创建SqlSeessionFactory 创建SqlSession 获得接口代理对象 MyBatis-D…