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

网站的标题标签一般是写在网站 未备案 支付宝

网站的标题标签一般是写在,网站 未备案 支付宝,wordpress怎样加入代码,电商直播LeNet-5(详解)—— 从原理到 PyTorch 实现(含训练示例) 文章目录LeNet-5(详解)—— 从原理到 PyTorch 实现(含训练示例)标题简介:为什么要学习 MobileNet 系列核心思想&a…

LeNet-5(详解)—— 从原理到 PyTorch 实现(含训练示例)

文章目录

  • LeNet-5(详解)—— 从原理到 PyTorch 实现(含训练示例)
    • 标题
    • 简介:为什么要学习 MobileNet 系列
    • 核心思想(总结)
    • 逐层结构(概要表)
      • MobileNet V1(简化版结构)
      • MobileNet V2(关键层次表,paper Table 2)
    • 逐层计算举例(含卷积输出尺寸与计算量公式)
      • 1) 空间尺寸计算(单层示例)
      • 2) 参数与计算量(FLOPs / Multiply-Adds)对比:标准卷积 vs 深度可分离卷积
        • 数值示例(手算/演示)
    • MobileNet V1:关键设计点细解
    • MobileNet V2:核心创新
    • PyTorch 实现(完整代码块)
      • MobileNet V1(精简实现)
      • MobileNet V2(关键模块 + 简洁实现)
    • 训练与评估(示例流程 + 超参建议)
      • 数据与预处理(以 ImageNet/或 CIFAR-10 为例)
      • 超参(示例)
      • 简单训练循环框架(伪代码)
      • 训练曲线与结果(参考)
    • 实验扩展(可以做的对比实验)
    • 部署注意与工程实践
    • 总结

标题

MobileNet V1 & V2(详解)—— 从原理到 PyTorch 实现(含训练示例与对比实验)


简介:为什么要学习 MobileNet 系列

MobileNet 系列是为移动端/嵌入式场景设计的轻量级卷积神经网络家族。它们通过结构设计(Depthwise Separable Convolution、宽度/分辨率缩放、倒置残差与线性瓶颈等)在“精度 ↔ 计算/内存”之间做出高效平衡,是实际工程中非常实用的模型。本文目标是:讲清核心思想、给出逐层计算举例、并提供可直接运行的 PyTorch 实现与训练/评估流程,便于你上手学习与改进。


核心思想(总结)

  1. Depthwise separable convolution(深度可分离卷积):把标准卷积分解为“depthwise” + “pointwise”,从而大幅降低参数与计算量(论文给出 3×3 的情形通常能节省约 8–9 倍计算)。
  2. 模型缩放超参(MobileNet V1):使用 width multiplier(宽度缩放 α)resolution multiplier(分辨率缩放 ρ) 来在线性权衡精度/速度/内存。
  3. 倒置残差 + 线性瓶颈(MobileNetV2):在瓶颈处使用扩展(先扩张通道再做深度卷积,最后线性投影回小通道),并在窄层做残差连接,从而保持信息流并节约内存,同时使用 ReLU6 来增强低精度场景的鲁棒性。

逐层结构(概要表)

MobileNet V1(简化版结构)

(以标准 224×224×3 输入,最后 FC 输出 1000 类为例)

  • conv3×3, stride=2, 32
  • dw-sep(3×3) → 64 (s=1)
  • dw-sep(3×3) → 128 (s=2)
  • dw-sep(3×3) → 128 (s=1)
  • dw-sep(3×3) → 256 (s=2)
  • dw-sep(3×3) → 256 (s=1)
  • dw-sep(3×3) → 512 (s=2)
  • dw-sep(3×3) → 512 (s=1) ×5(重复5次)
  • dw-sep(3×3) → 1024 (s=2)
  • dw-sep(3×3) → 1024 (s=1)
  • global avg pool → FC(1000)
    (详细表可查论文 Table 1)

MobileNet V2(关键层次表,paper Table 2)

MobileNetV2 用 bottleneck(倒置残差块) 做堆叠,每个 block 有扩张系数 t、输出通道 c、重复次数 n、stride s,示例(部分):

  • conv3×3, 32, s=2
  • bottleneck t=1, c=16, n=1, s=1
  • bottleneck t=6, c=24, n=2, s=2
  • bottleneck t=6, c=32, n=3, s=2
  • 最后 1×1 conv → 1280 → avgpool → FC
    详表见论文 Table 2(本文后面给出 PyTorch 实现)。

逐层计算举例(含卷积输出尺寸与计算量公式)

1) 空间尺寸计算(单层示例)

标准二维卷积输出尺寸公式(以 0-based padding 表述):

out_H = floor((in_H + 2*pad - kernel_size) / stride) + 1
out_W = floor((in_W + 2*pad - kernel_size) / stride) + 1

举例:输入 224×224,第一层 conv3×3, stride=2, padding=1

  • out_H = floor((224 + 2*1 - 3)/2) + 1 = floor(224/2) + 1 = 112(等价于常用“保持 same” 的设置)
    所以空间变为 112×112

2) 参数与计算量(FLOPs / Multiply-Adds)对比:标准卷积 vs 深度可分离卷积

标准卷积(kernel K×K, 输入通道 M, 输出通道 N, 特征图 D_F × D_F)的计算量(multiply-adds):

cost_standard = K*K * M * N * D_F * D_F

Depthwise separable = depthwise + pointwise:

  • depthwise cost = K*K * M * D_F * D_F
  • pointwise cost = 1*1 * M * N * D_F * D_F = M * N * D_F * D_F
  • 总和:
cost_ds = K*K * M * D_F * D_F + M * N * D_F * D_F

节省比率(cost_ds / cost_standard)

ratio = (K^2 * M + M*N) / (K^2 * M * N) = 1/N + 1/(K^2)

对于 K=3K^2=9,当 N 很大(常见情况)时,主要项约为 1/9 ≈ 0.111,也就是约 8~9 倍 的减少(与论文结论一致)。

数值示例(手算/演示)

K=3, M=128, N=256, D_F=56(比较常见的一层尺寸):

  • 标准卷积 MAdds = 3*3*128*256*56*56 = 924,844,032(约 9.25e8)
  • Depthwise separable MAdds = 3*3*128*56*56 + 128*256*56*56 = 106,373,120(约 1.06e8)
  • 比例 ≈ 106,373,120 / 924,844,032 ≈ 0.115约 8.7× 更少计算(论文中也得出 8–9 倍的结论)。

(上面数字为逐项展开后的乘法结果,展示了深度可分离卷积带来的实际计算节省。)


MobileNet V1:关键设计点细解

  • Depthwise + Pointwise:把“滤波(spatial)”和“通道融合”分离开。滤波放到 depthwise(每通道一个 filter),channel 则由 1×1 pointwise 完成。
  • 宽度/分辨率超参(α, ρ):通过 α 缩减通道数,通过 ρ 缩减输入分辨率,从而在推断速度/模型大小/精度之间平滑权衡。论文中说明了多组 α/ρ 的实验。
  • BN + ReLU:每个 depthwise 和 pointwise 后接 BatchNorm 与 ReLU(paper 中使用 ReLU)。

MobileNet V2:核心创新

  • 倒置残差(Inverted Residual):残差连接不再连接“宽”通道,而是连接“窄(bottleneck)”通道;基本单元是先用 1×1 扩展通道(ReLU6),再 depthwise 3×3(ReLU6),最后用 1×1 线性投影回窄通道(无激活)。该结构在表达能力与内存效率之间取得平衡。
  • 线性瓶颈(Linear Bottleneck):最后投影回低维时不使用非线性(no ReLU),以避免信息在低维空间被 ReLU 非线性“毁损”。
  • ReLU6:在窄通道使用 ReLU6(对低精度设备更鲁棒)。

MobileNetV2 在效率/准确率曲线上相比 V1 有明显改进(paper 给出在 ImageNet 上 MobileNetV2 (1.0) top-1 ≈ 72.0%,参数 ≈ 3.4M,MAdds ≈ 300M 的典型点)。


PyTorch 实现(完整代码块)

说明:下面给出可直接复制运行的简洁实现(适合教学与小改动)。在工程中也可直接使用 torchvision.models.mobilenet_v2(可加载预训练权重)。([PyTorch][1])

MobileNet V1(精简实现)

# mobilenet_v1.py
import torch
import torch.nn as nn
import torch.nn.functional as Fdef _make_divisible(v, divisor=8, min_value=None):if min_value is None:min_value = divisornew_v = max(min_value, int(v + divisor / 2) // divisor * divisor)# make sure that round down does not go down by more than 10%if new_v < 0.9 * v:new_v += divisorreturn new_vclass DepthwiseSeparableConv(nn.Module):def __init__(self, in_ch, out_ch, stride=1):super().__init__()self.depthwise = nn.Conv2d(in_ch, in_ch, kernel_size=3, stride=stride,padding=1, groups=in_ch, bias=False)self.bn1 = nn.BatchNorm2d(in_ch)self.pointwise = nn.Conv2d(in_ch, out_ch, kernel_size=1, bias=False)self.bn2 = nn.BatchNorm2d(out_ch)self.relu = nn.ReLU(inplace=True)def forward(self, x):x = self.depthwise(x)x = self.bn1(x)x = self.relu(x)x = self.pointwise(x)x = self.bn2(x)x = self.relu(x)return xclass MobileNetV1(nn.Module):def __init__(self, num_classes=1000, width_mult=1.0):super().__init__()# base channel settings from paperbase_cfg = [# t: (out_ch, stride)(32, 2),(64, 1),(128, 2),(128, 1),(256, 2),(256, 1),(512, 2),(512, 1), (512, 1), (512, 1), (512, 1), (512, 1),(1024, 2),(1024, 1),]input_channel = _make_divisible(32 * width_mult)self.features = []# first conv (not depthwise)self.features.append(nn.Conv2d(3, input_channel, kernel_size=3, stride=2, padding=1, bias=False))self.features.append(nn.BatchNorm2d(input_channel))self.features.append(nn.ReLU(inplace=True))# add depthwise separable blocksfor out_ch, stride in base_cfg[1:]:out_ch = _make_divisible(out_ch * width_mult)self.features.append(DepthwiseSeparableConv(input_channel, out_ch, stride))input_channel = out_chself.features = nn.Sequential(*self.features)self.avgpool = nn.AdaptiveAvgPool2d(1)self.classifier = nn.Linear(input_channel, num_classes)# weight initfor m in self.modules():if isinstance(m, nn.Conv2d):nn.init.kaiming_normal_(m.weight, mode='fan_out')elif isinstance(m, nn.BatchNorm2d):nn.init.ones_(m.weight)nn.init.zeros_(m.bias)elif isinstance(m, nn.Linear):nn.init.normal_(m.weight, 0, 0.01)nn.init.zeros_(m.bias)def forward(self, x):x = self.features(x)x = self.avgpool(x).view(x.size(0), -1)x = self.classifier(x)return x

MobileNet V2(关键模块 + 简洁实现)

# mobilenet_v2.py
import torch
import torch.nn as nndef _make_divisible(v, divisor=8, min_value=None):if min_value is None:min_value = divisornew_v = max(min_value, int(v + divisor / 2) // divisor * divisor)if new_v < 0.9 * v:new_v += divisorreturn new_vclass InvertedResidual(nn.Module):def __init__(self, inp, oup, stride, expand_ratio):super().__init__()self.stride = strideself.use_res_connect = (self.stride == 1 and inp == oup)hidden_dim = int(round(inp * expand_ratio))layers = []if expand_ratio != 1:# pointwiselayers.append(nn.Conv2d(inp, hidden_dim, 1, 1, 0, bias=False))layers.append(nn.BatchNorm2d(hidden_dim))layers.append(nn.ReLU6(inplace=True))# depthwiselayers.append(nn.Conv2d(hidden_dim, hidden_dim, 3, stride, 1, groups=hidden_dim, bias=False))layers.append(nn.BatchNorm2d(hidden_dim))layers.append(nn.ReLU6(inplace=True))# linear projectionlayers.append(nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False))layers.append(nn.BatchNorm2d(oup))self.conv = nn.Sequential(*layers)def forward(self, x):if self.use_res_connect:return x + self.conv(x)else:return self.conv(x)class MobileNetV2(nn.Module):def __init__(self, num_classes=1000, width_mult=1.0):super().__init__()# setting as paper's tableinverted_residual_setting = [# t, c, n, s(1, 16, 1, 1),(6, 24, 2, 2),(6, 32, 3, 2),(6, 64, 4, 2),(6, 96, 3, 1),(6, 160, 3, 2),(6, 320, 1, 1),]input_channel = _make_divisible(32 * width_mult)last_channel = _make_divisible(1280 * max(1.0, width_mult))features = []# first layerfeatures.append(nn.Conv2d(3, input_channel, kernel_size=3, stride=2, padding=1, bias=False))features.append(nn.BatchNorm2d(input_channel))features.append(nn.ReLU6(inplace=True))# bottlenecksfor t, c, n, s in inverted_residual_setting:output_channel = _make_divisible(c * width_mult)for i in range(n):stride = s if i == 0 else 1features.append(InvertedResidual(input_channel, output_channel, stride, expand_ratio=t))input_channel = output_channel# last layersfeatures.append(nn.Conv2d(input_channel, last_channel, kernel_size=1, bias=False))features.append(nn.BatchNorm2d(last_channel))features.append(nn.ReLU6(inplace=True))self.features = nn.Sequential(*features)self.avgpool = nn.AdaptiveAvgPool2d(1)self.classifier = nn.Linear(last_channel, num_classes)# weight initfor m in self.modules():if isinstance(m, nn.Conv2d):nn.init.kaiming_normal_(m.weight, mode='fan_out')elif isinstance(m, nn.BatchNorm2d):nn.init.ones_(m.weight)nn.init.zeros_(m.bias)elif isinstance(m, nn.Linear):nn.init.normal_(m.weight, 0, 0.01)nn.init.zeros_(m.bias)def forward(self, x):x = self.features(x)x = self.avgpool(x).view(x.size(0), -1)x = self.classifier(x)return x

实现注释

  • groups=in_channels 的 Conv2d 即为 depthwise 卷积(PyTorch 标准实现)。关于如何用 groups 做 depthwise,请参见 PyTorch 讨论与示例。([PyTorch Forums][2])
  • MobileNetV2 的实现与 torchvision 的实现思想一致;在工程中可以直接用 torchvision.models.mobilenet_v2(pretrained=True) 加载预训练模型并微调。([PyTorch][1])

训练与评估(示例流程 + 超参建议)

数据与预处理(以 ImageNet/或 CIFAR-10 为例)

  • ImageNet 推荐 Resize(256) -> CenterCrop(224)(或训练时 RandomResizedCrop(224)),标准 ImageNet 归一化。
  • CIFAR-10 推荐 RandomCrop(32, padding=4), RandomHorizontalFlip()、Normalize。

超参(示例)

  • Optimizer:SGD(momentum=0.9, weight_decay=1e-4)
  • LR schedule:初始 LR=0.1(ImageNet)或 0.01(小数据集),使用 StepLR 或 CosineAnnealing,训练 90 epoch(ImageNet)或 200 epoch(CIFAR-10)
  • Batch size:根据显存设定(常见 128/256 for ImageNet)
  • loss:CrossEntropyLoss
  • 预训练:对小数据集用 ImageNet 预训练权重做 fine-tune 可以大幅加速与提高最终精度(若可用)。

简单训练循环框架(伪代码)

# 假设 model, train_loader, val_loader 已准备
optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9, weight_decay=1e-4)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1)
criterion = nn.CrossEntropyLoss()for epoch in range(epochs):model.train()for x,y in train_loader:x,y = x.to(device), y.to(device)pred = model(x)loss = criterion(pred, y)optimizer.zero_grad()loss.backward()optimizer.step()scheduler.step()# 验证model.eval()correct = 0total = 0with torch.no_grad():for x,y in val_loader:x,y = x.to(device), y.to(device)pred = model(x)correct += (pred.argmax(1) == y).sum().item()total += y.size(0)print(f"Epoch {epoch}: val_acc = {correct/total:.4f}")

训练曲线与结果(参考)

  • 论文给出的 ImageNet 对比(paper 中的表格)显示:

    • MobileNetV1 (1.0): Top-1 ≈ 70.6%, params ≈ 4.2M, MAdds ≈ 575M
    • MobileNetV2 (1.0): Top-1 ≈ 72.0%, params ≈ 3.4M, MAdds ≈ 300M(更高效)。
  • 你的实际训练结果会根据数据增强、优化器与训练时长而变化;上面是论文在 ImageNet 上的基准值,可作为对照。


实验扩展(可以做的对比实验)

  1. Width multiplier α 的影响:α ∈ {1.4, 1.0, 0.75, 0.5, 0.35},对比参数量 / MAdds / Top-1 精度的 trade-off(论文有完整曲线)。
  2. 输入分辨率 ρ 的影响:224 vs 192 vs 160 的效果对比(影响计算量与精度)。
  3. V1 vs V2 基于相同 MAdds 的精度对比:论文显示 V2 在相同预算下通常更优。
  4. 激活函数对比:ReLU6(V2) vs ReLU(V1),在低精度量化(8-bit)场景下通常 ReLU6 更稳健。
  5. 数据增强 / AutoAugment / MixUp / CutMix:尝试这些增广能在给定模型上提升 1~3% 精度。
  6. 替换 Depthwise 的实现或优化:不同后端(e.g., cuDNN, TensorRT, TF-Lite)对 depthwise 卷积支持差异会导致实际运行时间差异,注意工程部署时的算子支持。

部署注意与工程实践

  • 虽然 depthwise separable 在理论 FLOPs 大幅减少,但实际 延迟/吞吐 受后端对 groups 支持、内存访问与并发实现影响。不同设备上需要做针对性 benchmark(TF-Lite / ONNX / TensorRT / CoreML)。
  • 若目标是极致压缩,可结合量化(8-bit)、剪枝、知识蒸馏等手段进一步减小模型与延迟。

总结

  • MobileNet 系列通过结构设计(深度可分离卷积、宽度/分辨率缩放、倒置残差与线性瓶颈)实现了在资源受限场景下优异的“精度 ↔ 计算/内存”折中。MobileNetV2 在 V1 的基础上引入了倒置残差和线性瓶颈,进一步提高了性能与效率。论文中给出的基准(ImageNet 上)可作为工程选择模型规模的参考。
http://www.dtcms.com/a/453824.html

相关文章:

  • 募投绘蓝图-昂瑞微的成长密码与未来布局
  • 公司网络营销的方案思路seo整站优化外包服务
  • 工程建设公司网站怎么查询网站的域名备案
  • TypeScript 对比 JavaScript
  • 焦作网站设计公司自己怎么做外贸网站
  • ros2 消息订阅与发布示例 c++
  • 廊坊网站建设廊坊企业文化建设网站
  • 纸做的花朵成品网站个人简介html代码模板
  • 【精品资料鉴赏】证券数据治理项目投标技术方案
  • AI大模型核心概念
  • 企业网站模板seo公益建设网站的作用
  • 阿里巴巴1688怎么做网站自建网站阿里云备案通过后怎么做
  • 成都规划网站佛山网上办事大厅官网
  • AI-RAN Sionna 5G NR 开发者套件
  • 百度商桥怎么添加到网站山东网站
  • iis 里没有网站柯桥网站建设
  • 外汇返佣网站建设有了域名之后怎么做自己的网站
  • 模板网站配置文件域名注册 网站建设 好做吗
  • 网站开发工具安卓版泉州网站建设方案服务
  • 长沙网站建设长沙网站制作淘宝优惠券网站建设总代
  • 河北云网站建设福建联泰建设集团网站
  • 基于单片机的蓝牙可调PWM波形发生器设计
  • 网站如何生成静态页面英国网站建设
  • 网站建设人员分工wordpress菜单导航代码
  • 怎么查网站外链企业小程序注册
  • OpenCV(一):创建显示窗口
  • 国际设计网站有哪些吉林省吉林市天气预报
  • 全响应网站制作北京中燕建设公司网站
  • TensorFlow2 Python深度学习 - TensorFlow2框架入门 - 张量(Tensor)的定义与操作
  • 网站授权合同网站服务器查询