为什么做动漫短视频网站,wordpress数据下载插件,wordpress 块,做电容元器件的网站有哪些文章目录 简介背景为什么理解神经网络中的MAC和FLOPs很重要#xff1f;资源效率内存效率能耗功耗效率 模型优化性能基准研究与发展 FLOPs 和 MACs 定义1. 全连接层 FLOPs 计算步骤 1#xff1a;识别层参数步骤 2#xff1a;计算 FLOPs 和 MACs步骤 3#xff1a;总结结果使用… 文章目录 简介背景为什么理解神经网络中的MAC和FLOPs很重要资源效率内存效率能耗功耗效率 模型优化性能基准研究与发展 FLOPs 和 MACs 定义1. 全连接层 FLOPs 计算步骤 1识别层参数步骤 2计算 FLOPs 和 MACs步骤 3总结结果使用 torchprofile 库验证 2. 卷积神经网络CNNs计算卷积操作时的重要考虑因素第一步确定层参数第二步计算FLOPs和MACs第三步汇总结果使用torchprofile库验证操作 3. 自注意力模块 (self-attention) FLOPs 计算第一步确定层参数第二步汇总结果使用torchprofile库验证操作 总结按不同批次大小缩放MACs和FLOPs 简介
理解神经网络中的 MAC乘累加操作和 FLOPs浮点运算对于优化网络性能和效率至关重要。通过手动计算这些指标可以更深入地了解网络结构的计算复杂性和资源需求。这不仅能帮助设计高效的模型还能在训练和推理阶段节省时间和资源。本文将通过实例演示如何计算全连接层(fc)、卷积层(conv) 以及 自注意力模块(self-attention) 的 FLOPs 和 MACs并探讨其对资源效率、内存效率、能耗和模型优化的影响。 背景
为什么理解神经网络中的MAC和FLOPs很重要
在本节中我们将深入探讨神经网络中 MAC乘累加操作和 FLOPs浮点运算的概念。通过学习如何使用笔和纸手动计算这些指标将获得对各种网络结构的计算复杂性和效率的基本理解。
理解 MAC 和 FLOPs 不仅仅是学术练习它是优化神经网络性能和效率的关键组成部分。它有助于设计既计算高效又有效的模型从而在训练和推理阶段节省时间和资源。
这是一个在 Colab 笔记本中完全运行的示例
资源效率
理解 FLOPs 有助于估算神经网络的计算成本。通过优化 FLOPs 的数量可以潜在地减少训练或运行神经网络所需的时间。
内存效率
MAC 操作通常决定了网络的内存使用情况因为它们直接与网络中的参数和激活数量相关。减少 MACs 有助于使网络的内存使用更高效。
能耗
功耗效率
FLOPs 和 MAC 操作都对运行神经网络的硬件的功耗有贡献。通过优化这些指标可以潜在地减少运行网络所需的能量这对于移动设备和嵌入式设备尤为重要。
模型优化
剪枝和量化 理解 FLOPs 和 MACs 可以帮助通过剪枝去除不必要的连接和量化降低权重和激活的精度等技术优化神经网络这些技术旨在减少计算和内存成本。
性能基准 模型间比较 FLOPs 和 MACs 提供了一种比较不同模型计算复杂性的方法这可以作为为特定应用选择模型的标准。 硬件基准 这些指标还可以用于对比不同硬件平台运行神经网络的性能。 边缘设备上的部署 实时应用 对于实时应用特别是在计算资源有限的边缘设备上理解和优化这些指标对于确保网络能够在应用的时间限制内运行至关重要。电池寿命 在电池供电的设备中减少神经网络的计算成本从而减少能耗可以帮助延长电池寿命。
研究与发展
设计新算法 在开发新算法或神经网络结构时研究人员可以使用这些指标作为指导目的是在不牺牲精度的情况下提高计算效率。 FLOPs 和 MACs 定义 FLOP浮点运算被认为是加法、减法、乘法或除法运算。 MAC乘加运算基本上是一次乘法加上一次加法即 MAC a * b c。它算作两个FLOP一次乘法和一次加法。 1. 全连接层 FLOPs 计算
现在我们将创建一个包含三层的简单神经网络并开始计算所涉及的操作。以下是计算第一层线性层全连接层操作数的公式
对于具有 I 个输入和 O 个输出的全连接层操作数如下 MACs: I × OFLOPs: 2 × (I × O)因为每个 MAC 算作两个 FLOP
import torch
import torch.nn as nn
import torch.nn.functional as F
from torchprofile import profile_macsclass SimpleLinearModel(nn.Module):def __init__(self):super(SimpleLinearModel,self).__init__()self.fc1 nn.Linear(in_features10, out_features20, biasFalse)self.fc2 nn.Linear(in_features20, out_features15, biasFalse)self.fc3 nn.Linear(in_features15, out_features1, biasFalse)def forward(self, x):x self.fc1(x)x F.relu(x)x self.fc2(x)F.relu(x)x self.fc3(x)return xlinear_model SimpleLinearModel().cuda()
sample_data torch.randn(1, 10).cuda()步骤 1识别层参数
对于给定的模型我们定义了三层线性层 fc110 个输入特征20 个输出特征 fc220 个输入特征15 个输出特征 fc315 个输入特征1 个输出特征
步骤 2计算 FLOPs 和 MACs
现在计算每层的 MACs 和 FLOPs 层 fc1 MACs 10 × 20 200 FLOPs 2 × MACs 2 × 200 400 层 fc2 MACs 20 × 15 300 FLOPs 2 × MACs 2 × 300 600 层 fc3 MACs 15 × 1 15 FLOPs 2 × MACs 2 × 15 30
步骤 3总结结果
最后为了找到单个输入通过整个网络的总 MACs 和 FLOPs我们将所有层的结果相加总 MACs MACs(fc1) MACs(fc2) MACs(fc3) 200 300 15 515总 FLOPs FLOPs(fc1) FLOPs(fc2) FLOPs(fc3) 400 600 30 1030
使用 torchprofile 库验证
可以使用 torchprofile 库来验证给定神经网络模型的 FLOPs 和 MACs 计算。以下是具体操作步骤
macs profile_macs(linear_model, sample_data)
print(macs)
# - 5152. 卷积神经网络CNNs
现在让我们确定一个简单卷积模型的 MACs乘加运算和 FLOPs浮点运算。由于诸如步幅、填充和核大小等因素这种计算比我们之前用密集层的例子更复杂一些。然而我将逐步讲解以便于学习。
class SimpleConv(nn.Module):def __init__(self):super(SimpleConv, self).__init__()self.conv1 nn.Conv2d(in_channels1, out_channels16, kernel_size3, stride1, padding1)self.conv2 nn.Conv2d(in_channels16, out_channels32, kernel_size3, stride1, padding1)self.fc nn.Linear(in_features32*28*28, out_features10)def forward(self, x):x self.conv1(x)x F.relu(x)x self.conv2(x)x F.relu(x)x x.view(x.shape[0], -1)x self.fc(x)return xx torch.rand(1, 1, 28, 28).cuda()
conv_model SimpleConv().cuda()计算卷积操作时的重要考虑因素
在计算卷积核的操作时必须记住核的通道数量应与输入的通道数量相匹配。例如如果我们的输入是一个有三个颜色通道的 RGB 图像则核的维度将是 3x3x3 以匹配输入的三个通道。
为了演示的目的我们将保持图像大小在整个卷积层中一致。为此我们将填充和步幅值都设置为1。
第一步确定层参数
对于给定的模型我们定义了两个卷积层和一个线性层
conv1: 1 个输入通道16 个输出通道核大小为 3conv2: 16 个输入通道32 个输出通道fc: 32x28x28 个输入特征10 个输出特征。因为我们的图像在卷积层中没有改变
第二步计算FLOPs和MACs
现在计算每层的 MACs 和 FLOPs
公式是output_image_size * kernel_shape * output_channels
层conv1:
MACs 28 * 28 * 3 * 3 * 1 * 16 1,12,896FLOPs 2 × MACs 2 × 1,12,896 2,25,792
层conv2:
MACs 28 × 28 * 3 * 3 * 16 * 32 3,612,672FLOPs 2 × MACs 2 × 3,612,672 7,225,344
层fc:
MACs 32 * 28 * 28 * 10 250,880FLOPs 2 × MACs 2 × 250,880 501,760
第三步汇总结果
最后为了找到单个输入通过整个网络的总MACs和FLOPs我们汇总所有层的结果
总MACs MACs(conv1) MACs(conv2) MACs(fc) 1,12,896 3,612,672 250,880 3,976,448总FLOPs FLOPs(conv1) FLOPs(conv2) FLOPs(fc) 2,25,792 7,225,344 501,760 7,952,896
使用torchprofile库验证操作
macs profile_macs(conv_model, (x,))
print(macs)
# 输出: 39764483. 自注意力模块 (self-attention) FLOPs 计算
在涵盖了线性和卷积层的 MACs 之后我们的下一步是确定自注意力模块的FLOPs浮点运算这是大型语言模型中的一个关键组件。这个计算对于理解这些模型的计算复杂度至关重要。让我们深入探讨。
class SimpleAttentionBlock(nn.Module):def __init__(self, embed_size, heads):super(SimpleAttentionBlock, self).__init__()self.embed_size embed_sizeself.heads headsself.head_dim embed_size // headsassert (self.head_dim * heads embed_size), Embedding size needs to be divisible by headsself.values nn.Linear(self.embed_size, self.embed_size, biasFalse)self.keys nn.Linear(self.embed_size, self.embed_size, biasFalse)self.queries nn.Linear(self.embed_size, self.embed_size, biasFalse)self.fc_out nn.Linear(heads * self.head_dim, embed_size)def forward(self, values, keys, queries, mask):N queries.shape[0]value_len, key_len, query_len values.shape[1], keys.shape[1], queries.shape[1]print(values.shape)values self.values(values).reshape(N, self.heads, value_len, self.head_dim)keys self.keys(keys).reshape(N, self.heads, key_len, self.head_dim)queries self.queries(queries).reshape(N, self.heads, query_len, self.head_dim)energy torch.matmul(queries, keys.transpose(-2, -1)) if mask is not None:energy energy.masked_fill(mask 0, float(-1e20))attention torch.nn.functional.softmax(energy, dim3)out torch.matmul(attention, values).reshape(N, query_len, self.heads * self.head_dim)return self.fc_out(out)第一步确定层参数
线性变换
让我们定义一些超参数
batch_size 1
seq_len 10
embed_size 256在注意力块中我们有三个线性变换用于查询、键和值以及一个在末尾的线性变换fc_out。
输入大小: [batch_size, seq_len, embed_size]
线性变换矩阵: [embed_size, embed_size]
MACs: batch_size × seq_len × embed_size × embed_size
查询、键、值线性变换
查询变换的MACs 1 × 10 × 256 × 256 655,360键变换的MACs 1 × 10 × 256 × 256 655,360值变换的MACs 1 × 10 × 256 × 256 655,360
能量计算: 查询重塑后和键重塑后点积——一个点积操作。
MACs: batch_size × seq_len × seq_len × heads × head_dim
查询和键的点积
MACs 1 × 10 × 10 × 8 × 32 [32 因为256/8] 25,600
从注意力权重和值的计算输出: 注意力权重和值重塑后点积——另一个点积操作。
MACs : batch_size × seq_len × seq_len × heads × head_dim
注意力和值的点积
MACs 1 × 10 × 10 × 8 × 32 25,600
全连接输出fc_out
MACs: batch_size × seq_len × heads × head_dim × embed_size
MACs 1 × 10 × 8 × 32 × 256 655,360
第二步汇总结果
总 MACs MACsconv1 MACsconv2 MACsfc 655,360 655,360 655,360 25,600 25,600 655,360 2,672,640
总 FLOPs 2 × 总MACs 5,345,280
使用torchprofile库验证操作
# 创建模型实例
model SimpleAttentionBlock(embed_size256, heads8).cuda()# 生成一些样本数据5个序列的批次每个长度为10嵌入大小为256
values torch.randn(1, 10, 256).cuda()
keys torch.randn(1, 10, 256).cuda()
queries torch.randn(1, 10, 256).cuda()# 简化起见没有掩码
mask None# 使用样本数据进行前向传递
macs profile_macs(model, (values, keys, queries, mask))
print(macs)
# - 2672640总结按不同批次大小缩放MACs和FLOPs
在我们的计算中我们主要考虑了批次大小为 1。然而按更大的批次大小缩放 MACs 和 FLOPs 是很简单的。
要计算批次大小大于 1 的 MACs 或 FLOPs您可以简单地将批次大小 1 得到的总 MACs 或 FLOPs 乘以所需的批次大小值。此缩放允许您估计神经网络模型的各种批次大小的计算需求。
请记住结果将直接线性缩放批次大小。例如如果您的批次大小为 32您可以通过将批次大小为 1 的值乘以 32 来获得 MACs 或 FLOPs。 原文链接 https://medium.com/pashashaik/a-guide-to-hand-calculating-flops-and-macs-fa5221ce5ccc