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

day41 python图像识别任务

目录

一、数据预处理:为模型打下坚实基础

二、模型构建:多层感知机的实现

三、训练过程:迭代优化与性能评估

四、测试结果:模型性能的最终检验

五、总结与展望


在深度学习的旅程中,多层感知机(MLP)作为最基础的神经网络结构,是每位初学者的必经之路。最近,我通过实现和训练MLP模型,对图像识别任务有了更深入的理解。本文将从数据预处理、模型构建、训练过程到最终的测试结果,详细记录我的学习过程,并总结MLP在图像识别任务中的优势与局限。

一、数据预处理:为模型打下坚实基础

在任何机器学习任务中,数据预处理都是至关重要的第一步。对于图像数据,我们需要将其转换为适合模型处理的格式。以MNIST手写数字数据集为例,我使用了torchvision.transforms库对图像进行了标准化处理:

transform = transforms.Compose([transforms.ToTensor(),  # 转换为张量并归一化到[0,1]transforms.Normalize((0.1307,), (0.3081,))  # MNIST数据集的均值和标准差
])

通过ToTensor()操作,图像被转换为张量格式,并且像素值被归一化到[0,1]区间。Normalize()操作则进一步对图像进行标准化,使其均值为0,标准差为1。这有助于加速模型的收敛。

对于彩色图像数据集(如CIFAR-10),处理方式类似,只是需要对每个通道分别进行标准化:

transform = transforms.Compose([transforms.ToTensor(),                transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))  # 标准化处理
])

数据加载器DataLoader的使用也非常关键,它能够高效地批量加载数据,并支持多线程加速数据读取:

train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)

通过设置shuffle=True,训练数据会在每个epoch开始时被打乱,这有助于模型更好地泛化。

二、模型构建:多层感知机的实现

多层感知机(MLP)是一种经典的神经网络结构,由多个全连接层组成。在MNIST数据集上,我构建了一个简单的MLP模型:

class MLP(nn.Module):def __init__(self):super(MLP, self).__init__()self.flatten = nn.Flatten()  # 将28x28的图像展平为784维向量self.layer1 = nn.Linear(784, 128)  # 第一层:784个输入,128个神经元self.relu = nn.ReLU()  # 激活函数self.layer2 = nn.Linear(128, 10)  # 第二层:128个输入,10个输出(对应10个数字类别)def forward(self, x):x = self.flatten(x)  # 展平图像x = self.layer1(x)   # 第一层线性变换x = self.relu(x)     # 应用ReLU激活函数x = self.layer2(x)   # 第二层线性变换,输出logitsreturn x

在CIFAR-10数据集上,我将模型进行了扩展,增加了层数和神经元数量,并引入了Dropout来防止过拟合:

class MLP(nn.Module):def __init__(self):super(MLP, self).__init__()self.flatten = nn.Flatten()  # 将3x32x32的图像展平为3072维向量self.layer1 = nn.Linear(3072, 512)  # 第一层:3072个输入,512个神经元self.relu1 = nn.ReLU()self.dropout1 = nn.Dropout(0.2)  # 添加Dropout防止过拟合self.layer2 = nn.Linear(512, 256)  # 第二层:512个输入,256个神经元self.relu2 = nn.ReLU()self.dropout2 = nn.Dropout(0.2)self.layer3 = nn.Linear(256, 10)  # 输出层:10个类别def forward(self, x):x = self.flatten(x)  # 输入尺寸: [batch_size, 3, 32, 32] → [batch_size, 3072]x = self.layer1(x)   # 线性变换: [batch_size, 3072] → [batch_size, 512]x = self.relu1(x)    # 应用ReLU激活函数x = self.dropout1(x) # 训练时随机丢弃部分神经元输出x = self.layer2(x)   # 线性变换: [batch_size, 512] → [batch_size, 256]x = self.relu2(x)    # 应用ReLU激活函数x = self.dropout2(x) # 训练时随机丢弃部分神经元输出x = self.layer3(x)   # 线性变换: [batch_size, 256] → [batch_size, 10]return x  # 返回未经过Softmax的logits

Dropout是一种有效的正则化技术,它在训练阶段随机丢弃部分神经元的输出,从而防止模型对训练数据过度拟合。

三、训练过程:迭代优化与性能评估

训练过程是模型学习数据特征的关键阶段。我使用了Adam优化器和交叉熵损失函数,这是分类任务中常用的组合:

criterion = nn.CrossEntropyLoss()  # 交叉熵损失函数,适用于多分类问题
optimizer = optim.Adam(model.parameters(), lr=0.001)  # Adam优化器

在训练过程中,我记录了每个iteration的损失,并绘制了损失曲线,以便直观地观察模型的收敛情况:

def train(model, train_loader, test_loader, criterion, optimizer, device, epochs):model.train()  # 设置为训练模式all_iter_losses = []  # 存储所有 batch 的损失iter_indices = []     # 存储 iteration 序号for epoch in range(epochs):running_loss = 0.0correct = 0total = 0for batch_idx, (data, target) in enumerate(train_loader):data, target = data.to(device), target.to(device)  # 移至GPUoptimizer.zero_grad()  # 梯度清零output = model(data)  # 前向传播loss = criterion(output, target)  # 计算损失loss.backward()  # 反向传播optimizer.step()  # 更新参数iter_loss = loss.item()all_iter_losses.append(iter_loss)iter_indices.append(epoch * len(train_loader) + batch_idx + 1)running_loss += iter_loss_, predicted = output.max(1)total += target.size(0)correct += predicted.eq(target).sum().item()if (batch_idx + 1) % 100 == 0:print(f'Epoch: {epoch+1}/{epochs} | Batch: {batch_idx+1}/{len(train_loader)} 'f'| 单Batch损失: {iter_loss:.4f} | 累计平均损失: {running_loss/(batch_idx+1):.4f}')epoch_train_loss = running_loss / len(train_loader)epoch_train_acc = 100. * correct / totalepoch_test_loss, epoch_test_acc = test(model, test_loader, criterion, device)print(f'Epoch {epoch+1}/{epochs} 完成 | 训练准确率: {epoch_train_acc:.2f}% | 测试准确率: {epoch_test_acc:.2f}%')plot_iter_losses(all_iter_losses, iter_indices)return epoch_test_acc

通过每100个批次打印一次训练信息,我可以实时监控模型的训练进度。同时,每个epoch结束后,我会对模型进行测试,评估其在测试集上的性能。

四、测试结果:模型性能的最终检验

经过多次实验,我发现在MNIST数据集上,MLP模型能够达到较高的准确率(约96.75%)。然而,在更具挑战性的CIFAR-10数据集上,即使增加了模型的深度和训练轮次,最终测试准确率也仅能达到约52.40%。这表明MLP在处理复杂图像数据时存在明显的局限性。

五、总结与展望

通过这次学习,我深刻认识到MLP在图像识别任务中的优势与不足。MLP结构简单,易于理解和实现,但在处理图像数据时,它无法有效利用图像的空间结构信息,导致在复杂任务上性能受限。此外,深层MLP的参数规模呈指数级增长,容易过拟合,训练成本也较高。未来,我将深入学习卷积神经网络(CNN),它专门针对图像数据设计,能够自动提取图像的空间特征,具有更少的参数和更快的训练速度,是解决图像识别问题的更优选择。

@浙大疏锦行

http://www.lryc.cn/news/2392845.html

相关文章:

  • 无人机报警器探测模块技术解析!
  • Docker 替换宿主与容器的映射端口和文件路径
  • 我的3种AI写作节奏搭配模型,适合不同类型写作者
  • Bonjour
  • 华为云Flexus+DeepSeek征文 | 基于Dify和DeepSeek-R1开发企业级AI Agent全流程指南
  • HarmonyOS-ArkUI固定样式弹窗(1)
  • 痉挛性斜颈相关内容说明
  • C语言| 函数参数传递指针
  • 【25-cv-05917】HSP律所代理Le Petit Prince 小王子商标维权案
  • MyBatis 动态 SQL 详解:灵活构建强大查询
  • 从 “金屋藏娇” 到 自然语言处理(NLP)
  • vue3 ElMessage提示语换行渲染
  • Java 微服务架构设计:服务拆分与服务发现的策略
  • 华为OD机试真题——二叉树中序遍历(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
  • 解决 Go 中 `loadinternal: cannot find runtime/cgo` 错误
  • VSCode + GD32F407 构建烧录
  • Linux研学-入门命令
  • Hive在实际应用中,如何选择合适的JOIN优化策略?
  • 设计模式之结构型:桥接模式
  • 监控 Oracle Cloud 负载均衡器:使用 Applications Manager 释放最佳性能
  • 早发现=早安心!超导心磁图如何捕捉早期病变信号?
  • 使用Vditor将Markdown文档渲染成网页(Vite+JS+Vditor)
  • Python打卡DAY40
  • OPC Client第6讲(wxwidgets):Logger.h日志记录文件(单例模式);登录后的主界面
  • CesiumInstancedMesh 实例
  • 单细胞注释前沿:CASSIA——无参考、可解释、自动化细胞注释的大语言模型
  • 历年武汉大学计算机保研上机真题
  • 日语学习-日语知识点小记-构建基础-JLPT-N4阶段(30):みます
  • AR-HUD 光波导方案优化难题待解?OAS 光学软件来破局
  • 火狐安装自动录制表单教程——仙盟自动化运营大衍灵机——仙盟创梦IDE