神经网络推理加速入门——超简单的卷积和加法融合—伪代码版

简介: 用一个伪代码,学习卷积和加法如何融合的。

大家好啊,我是董董灿。

前几天写了一个卷积神经网络(CNN)中,卷积和加法融合的文章。有同学发私信,希望写一个带代码版本的,方便更好的理解。

我的第一反应是,代码版本的咋写,有那么多细节。后来一想,其实那位同学想知道的并不是那些细节,而是一个大致的流程。

于是我说,行,那我写一个伪代码版的吧,把大致的代码思路写一下。

至于具体卷积算法怎么实现的,建议chatGPT一下,或者看下开源深度学习仓库就行。

如果没看之前的文章,可以看上一看:超简单的卷积和加法融合

开始分析

还是以 resnet50 中的图为例,做一个卷积和加法的融合。

image.png

正常情况下,上述网络片段在执行的时候大概是这样的:

BatchNorm -> Relu -> Conv -| Add的左分支
                           |                -> Add
                  -> Conv -| Add的右分支

写出伪代码,实际上就是一种顺序调用逻辑,比如

bn_out = Batch_normal();
relu_out = Relu(bn_out);
conv_out_left = Conv2d(relu_out)
conv_out_right = Conv2d(...)
add_out = Add(conv_out_left, conv_out_right)

而一旦融合完之后,上图红框中的Conv 和 Add 就变成了一个算子,这里暂且称这个融合之后的算子为 ConvAdd 算子。

于是,上述的图,就变成了如下的图:

image.png

此时,整个网络片段的调用逻辑变成了:

bn_out = Batch_normal();
relu_out = Relu(bn_out);
conv_out_right = Conv2d(...)
add_out = ConvAdd(relu_out, conv_out_right)

再把 ConvAdd 当做一个算子之后,便可以进行很多融合、拆图、流水并行操作。

假设现在这个网络运行在一个Asic芯片上,芯片上卷积计算模块和加法计算模块是互相独立的,没有任何依赖。

这里假设卷积输入的 Feature Map 的大小是 [n, hi, wi, ci],卷积核是[co, kh, kw, ci]。

其余参数简化一下,将卷积 pad 简化为0,stride 简化为1,dilation简化为1。

卷积的输出为[n, ho, wo, co]。

那么卷积后面的加法,执行的两个tensor相加,也就变成了 [n, ho, wo, co] + [n, ho, wo, co] = [n, ho, wo, co]。

那么,我们将卷积的输入(假设是下面的一张图),在H方向切成两份。

image.png

那么计算完一整张图,需要调用两次卷积运算,第一次计算上半部分,第二次计算下半部分。

两次计算中,大部分像素之间是没有关系的,仅仅在两部分交界的地方会有可能存在依赖。(存在依赖的条件为 kernel 大于1,或者 stride 大于1,这些情况先不考虑,暂时认为两部分像素没有关系)。

那么第一次卷积计算,计算的输入是 [n, hi/2, wi, ci],计算输出结果是 [n, ho/2, wo, co]。此时计算的是前半部分的 hi。用红色表示。

那么第二次卷积计算,计算的输入是 [n, hi/2, wi, ci],计算输出结果是 [n, ho/2, wo, co]。此时计算的是后半部分的 hi。用蓝色表示。

同理,加法也会被分成两次计算,分别对应计算卷积的两次输出:

  • 第一次加法,计算的是第一次卷积的输出,即 [n, ho/2, wo, co]
  • 第一次加法,计算的是第一次卷积的输出,即 [n, ho/2, wo, co]

那么,在两次计算的情况下,ConvAdd 这一个算子中,内部的实现逻辑大致应该是:

conv_out_part1 = Conv2d(part1)
conv_out_part2 = Conv2d(part2)
add_out_part1 = Add(conv_out_part1)
add_out_part2 = Add(conv_out_part2)

但是这样显然是不行的,因为这样写还是串行执行:执行完第一次卷积执行第二次卷积,执行完第二次卷积执行第一次加法...

那怎么让 Conv 和 Add 并行起来呢?

通过观察可以发现,第一次的Add并不依赖第二次的Conv,并且我们已经假设了Asic芯片上Conv运算模块和Add模块完全独立。

那么让第二次Conv和第一次Add并行起来的方法就是:第一次Conv计算完之后,直接计算第一次Add,然后同时并行第二次Conv,这个时候,代码的实现大致是这样:

conv1 = Conv2d(part1)
-----------------------
add1 = Add(conv1)      
conv2 = Conv2d(part2) 
-----------------------
add2 = Add(conv2)

这个时候,Add 和 conv 在中间的一个流水级中并行起来了。

所谓的一个流水级,指的是上面代码段中两个“ ------ ” 之间的代码,称之为在一个流水级中。

那如果将图片拆成更多份,那可以并行的流水级就会更多。

比如拆成4份,那可以有3个流水级中的Conv和Add并行起来。

conv1 = Conv2d(part1)
-----------------------
add1 = Add(conv1)      
conv2 = Conv2d(part2) 
-----------------------
add2 = Add(conv2)
conv3 = Conv2d(part3) 
-----------------------
add3 = Add(conv3)      
conv4 = Conv2d(part4) 
-----------------------
add4 = Add(conv4)      
-----------------------

需要说明一点的是,上面伪代码中,每一个 “-----” 其实都代表了一个同步点。

在实际部署到硬件上运行时,需要在这些同步点上设置同步操作,用来使上一个流水级中的所有计算操作全部完成即可。

常用的同步操作有一些同步指令或者barrier指令。假设我们使用barrier指令来进行同步,那么上述完整的伪代码便是:

conv1 = Conv2d(part1)
barrier()

add1 = Add(conv1)      
conv2 = Conv2d(part2) 
barrier()

add2 = Add(conv2)
conv3 = Conv2d(part3) 
barrier()

add3 = Add(conv3)      
conv4 = Conv2d(part4) 
barrier()

add4 = Add(conv4)      
barrier()

当然上述代码看起来太长了,可以写成循环的形式,还是以将H方向拆分 4 份为例:

conv1 = Conv2d(part1);
barrier();

for i in range(1, 4):
    add_i = Add(convi)
    Conv_i+1 = Conv2d(part_i+1)
    barrier()

add4 = Add(conv4)      
barrier()

伪代码的逻辑还是很简单的,关键是需要理解Conv和Add并行流水的思想。

这种方法可以用到的融合场景很多,并不仅仅局限于Conv和Add这两个算子,也不局限于某一个神经网络。

只要是在硬件上计算单元可以并行执行,并且在神经网络结构图上前后有依赖的层,几乎都可以这么进行融合来提升整体性能。

欢迎关注@董董灿是个攻城狮 和同名微信公众号
本文作者原创,转载请联系作者,请勿随意转载

相关文章
|
4月前
|
机器学习/深度学习 PyTorch TensorFlow
卷积神经网络深度解析:从基础原理到实战应用的完整指南
蒋星熠Jaxonic,深度学习探索者。深耕TensorFlow与PyTorch,分享框架对比、性能优化与实战经验,助力技术进阶。
|
9月前
|
机器学习/深度学习 自然语言处理 数据可视化
基于图神经网络的自然语言处理:融合LangGraph与大型概念模型的情感分析实践
本文探讨了在企业数字化转型中,大型概念模型(LCMs)与图神经网络结合处理非结构化文本数据的技术方案。LCMs突破传统词汇级处理局限,以概念级语义理解为核心,增强情感分析、实体识别和主题建模能力。通过构建基于LangGraph的混合符号-语义处理管道,整合符号方法的结构化优势与语义方法的理解深度,实现精准的文本分析。具体应用中,该架构通过预处理、图构建、嵌入生成及GNN推理等模块,完成客户反馈的情感分类与主题聚类。最终,LangGraph工作流编排确保各模块高效协作,为企业提供可解释性强、业务价值高的分析结果。此技术融合为挖掘非结构化数据价值、支持数据驱动决策提供了创新路径。
578 6
基于图神经网络的自然语言处理:融合LangGraph与大型概念模型的情感分析实践
|
5月前
|
机器学习/深度学习 人工智能 算法
卷积神经网络深度解析:从基础原理到实战应用的完整指南
蒋星熠Jaxonic带你深入卷积神经网络(CNN)核心技术,从生物启发到数学原理,详解ResNet、注意力机制与模型优化,探索视觉智能的演进之路。
554 11
|
7月前
|
机器学习/深度学习 数据采集 算法
贝叶斯状态空间神经网络:融合概率推理和状态空间实现高精度预测和可解释性
本文将BSSNN扩展至反向推理任务,即预测X∣y,这种设计使得模型不仅能够预测结果,还能够探索特定结果对应的输入特征组合。在二元分类任务中,这种反向推理能力有助于识别导致正负类结果的关键因素,从而显著提升模型的可解释性和决策支持能力。
582 42
贝叶斯状态空间神经网络:融合概率推理和状态空间实现高精度预测和可解释性
|
5月前
|
人工智能 监控 数据可视化
如何破解AI推理延迟难题:构建敏捷多云算力网络
本文探讨了AI企业在突破算力瓶颈后,如何构建高效、稳定的网络架构以支撑AI产品化落地。文章分析了典型AI IT架构的四个层次——流量接入层、调度决策层、推理服务层和训练算力层,并深入解析了AI架构对网络提出的三大核心挑战:跨云互联、逻辑隔离与业务识别、网络可视化与QoS控制。最终提出了一站式网络解决方案,助力AI企业实现多云调度、业务融合承载与精细化流量管理,推动AI服务高效、稳定交付。
|
8月前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于PSO粒子群优化TCN-LSTM时间卷积神经网络时间序列预测算法matlab仿真
本内容展示了一种基于粒子群优化(PSO)与时间卷积神经网络(TCN)的时间序列预测方法。通过 MATLAB2022a 实现,完整程序运行无水印,核心代码附详细中文注释及操作视频。算法利用 PSO 优化 TCN 的超参数(如卷积核大小、层数等),提升非线性时间序列预测性能。TCN 结构包含因果卷积层与残差连接,结合 LSTM 构建混合模型,经多次迭代选择最优超参数,最终实现更准确可靠的预测效果,适用于金融、气象等领域。
|
5月前
|
机器学习/深度学习 传感器 数据采集
【故障识别】基于CNN-SVM卷积神经网络结合支持向量机的数据分类预测研究(Matlab代码实现)
【故障识别】基于CNN-SVM卷积神经网络结合支持向量机的数据分类预测研究(Matlab代码实现)
405 0
|
9月前
|
机器学习/深度学习 人工智能 算法
深度解析:基于卷积神经网络的宠物识别
宠物识别技术随着饲养规模扩大而兴起,传统手段存在局限性,基于卷积神经网络的宠物识别技术应运而生。快瞳AI通过优化MobileNet-SSD架构、多尺度特征融合及动态网络剪枝等技术,实现高效精准识别。其在智能家居、宠物医疗和防走失领域展现广泛应用前景,为宠物管理带来智能化解决方案,推动行业迈向新高度。
|
7月前
|
机器学习/深度学习 人工智能 PyTorch
零基础入门CNN:聚AI卷积神经网络核心原理与工业级实战指南
卷积神经网络(CNN)通过局部感知和权值共享两大特性,成为计算机视觉的核心技术。本文详解CNN的卷积操作、架构设计、超参数调优及感受野计算,结合代码示例展示其在图像分类、目标检测等领域的应用价值。
451 7
|
9月前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于PSO粒子群优化TCN时间卷积神经网络时间序列预测算法matlab仿真
本内容介绍了一种基于PSO(粒子群优化)改进TCN(时间卷积神经网络)的时间序列预测方法。使用Matlab2022a运行,完整程序无水印,附带核心代码中文注释及操作视频。TCN通过因果卷积层与残差连接处理序列数据,PSO优化其卷积核权重等参数以降低预测误差。算法中,粒子根据个体与全局最优位置更新速度和位置,逐步逼近最佳参数组合,提升预测性能。

热门文章

最新文章