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

ema_mnist_blog

使用ModelEmaV2优化MNIST分类模型

在深度学习模型的训练过程中,参数波动可能会导致模型在测试集上的性能不稳定。为了解决这个问题,可以使用指数移动平均(EMA)技术来平滑参数的更新,从而获得更稳定的模型。本文将介绍如何在MNIST数据集上使用ModelEmaV2来优化分类模型,并分析其效果。

实验背景

MNIST数据集是一个经典的手写数字识别数据集,包含60,000张训练图像和10,000张测试图像。我们的目标是训练一个简单的神经网络模型来分类这些手写数字,并使用EMA技术来优化模型参数。

模型定义与EMA实现

首先,我们定义一个简单的全连接神经网络模型,并实现ModelEmaV2来进行EMA参数更新。

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
import copy# 定义简单的模型
class SimpleModel(nn.Module):def __init__(self):super(SimpleModel, self).__init__()self.fc = nn.Linear(28*28, 10)def forward(self, x):x = x.view(-1, 28*28)x = self.fc(x)return x# 初始化模型、损失函数和优化器
model = SimpleModel()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)# 定义 EMA 模型
class ModelEmaV2(nn.Module):def __init__(self, model, decay=0.99, device='cpu'):super(ModelEmaV2, self).__init__()self.ema_model = copy.deepcopy(model).to(device)self.ema_model.eval()self.decay = decayself.device = devicedef update(self, model):with torch.no_grad():model_params = dict(model.named_parameters())ema_params = dict(self.ema_model.named_parameters())for k in model_params.keys():ema_params[k].mul_(self.decay).add_(model_params[k], alpha=1 - self.decay)def forward(self, x):return self.ema_model(x)

数据加载与预处理

我们使用torchvision库来加载和预处理MNIST数据集。

# 加载MNIST数据集
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])
train_dataset = datasets.MNIST('../data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST('../data', train=False, transform=transform)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=1000, shuffle=False)

训练与评估

我们进行4个epoch的训练,并在每个epoch结束后评估模型和EMA模型的准确率。

# 训练和评估
num_epochs = 4
results = []for epoch in range(num_epochs):model.train()for inputs, targets in train_loader:optimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs, targets)loss.backward()optimizer.step()# 更新 EMA 模型ema_model.update(model)# 计算每个epoch的准确率model.eval()ema_model.eval()correct = 0total = 0ema_correct = 0ema_total = 0with torch.no_grad():for inputs, targets in test_loader:outputs = model(inputs)_, predicted = torch.max(outputs.data, 1)total += targets.size(0)correct += (predicted == targets).sum().item()# 测试 EMA 模型ema_outputs = ema_model(inputs)_, ema_predicted = torch.max(ema_outputs.data, 1)ema_total += targets.size(0)ema_correct += (ema_predicted == targets).sum().item()normal_accuracy = 100 * correct / totalema_accuracy = 100 * ema_correct / ema_totallag = normal_accuracy - ema_accuracyresults.append({'epoch': epoch + 1,'normal_accuracy': normal_accuracy,'ema_accuracy': ema_accuracy,'lag': lag})results

实验结果分析

实验结果如下表所示:

EpochNormal Model AccuracyEMA Model AccuracyLag
191.0990.970.12
292.5492.460.08
393.5393.500.03
494.0394.13-0.10

从结果可以看出,在训练的前几轮,EMA模型的准确率稍微滞后于正常模型,但随着训练的进行,两者的准确率逐渐接近,甚至在第四轮时,EMA模型的准确率略高于正常模型。

结论

通过实验可以看出,EMA技术在一定程度上平滑了模型参数的波动,使得模型在测试集上的表现更加稳定。尽管在训练的初期EMA模型的准确率稍有滞后,但随着训练的进行,EMA模型的表现逐渐赶上并超过了正常模型。这表明EMA技术对于提高模型的稳定性和性能具有重要作用。

相关文章:

  • SpringBoot项目中如何使用Redisson队列详解
  • 机器字长与操作系统的关系
  • 每天一个数据分析题(三百四十三)
  • 先导微型数控桌面式加工中心
  • 如何 使用Cubemax配置串口1.5得停止位
  • Vue2中的计算属性(computed)和监听属性(watch)
  • 【因果推断python】6_图因果模型
  • 释放视频潜力:Topaz Video AI for mac/win 一款全新的视频增强与修复利器
  • ROS2在RVIZ2中加载机器人urdf模型
  • 计算属性与监听属性
  • 恒创科技:无法与服务器建立安全连接怎么解决?
  • 国内常用的编程博客网址:技术资源与学习平台
  • Stable Diffusion|插件安装基础教程
  • 前端角色负责人岗
  • 5、css3 自动动画渐变背景
  • 【mysql】环境安装、服务启动、密码设置
  • 【刷算法】从上往下打印二叉树
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • Angular4 模板式表单用法以及验证
  • AngularJS指令开发(1)——参数详解
  • Apache Zeppelin在Apache Trafodion上的可视化
  • CAP 一致性协议及应用解析
  • ECMAScript入门(七)--Module语法
  • go语言学习初探(一)
  • Javascript弹出层-初探
  • MobX
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • PHP 7 修改了什么呢 -- 2
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • Redis在Web项目中的应用与实践
  • TypeScript实现数据结构(一)栈,队列,链表
  • 第十八天-企业应用架构模式-基本模式
  • 关于List、List?、ListObject的区别
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 如何使用 JavaScript 解析 URL
  • 使用parted解决大于2T的磁盘分区
  • 异步
  • 找一份好的前端工作,起点很重要
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • AI算硅基生命吗,为什么?
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (26)4.7 字符函数和字符串函数
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (MATLAB)第五章-矩阵运算
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (二)springcloud实战之config配置中心
  • (附源码)ssm码农论坛 毕业设计 231126
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (四)React组件、useState、组件样式
  • (转)母版页和相对路径