1.Python语言学习(三):Tensorflow_gpu搭建及convlstm核心源码解读
2.3d稀疏卷积——spconv源码剖析(三)
3.必知必会的卷积积核VGG网络(含代码)
4.OpenCV中几种卷积的实现方式
5.更灵活、有个性的核源卷积——可变形卷积(Deformable Conv)
6.3d稀疏卷积——spconv源码剖析(一)
Python语言学习(三):Tensorflow_gpu搭建及convlstm核心源码解读
在探索深度学习领域,使用Python语言进行编程无疑是码卷一条高效且灵活的途径。尤其在科研工作或项目实施中,代码Python以其丰富的卷积积核库资源和简单易用的特性,成为了许多专业人士的核源源码与源程序首选。本文旨在分享在Windows系统下使用Anaconda搭建TensorFlow_gpu环境及解读ConvLSTM核心源码的码卷过程。在提供具体步骤的代码同时,也期待读者的卷积积核反馈,以持续改进内容。核源
为了在Windows系统下搭建适合研究或项目的码卷TensorFlow_gpu环境,首先需要确认TensorFlow_gpu版本及其对应的代码cuDNN和CUDA版本。访问相关网站,卷积积核以获取适合自身硬件配置的核源版本信息。以TensorFlow_gpu2.为例,码卷进行环境搭建。
在Anaconda环境下,通过命令行操作来创建并激活特定环境,如`tensorflow-gpu`环境,选择Python3.版本。接着,安装cuDNN8.1和CUDA.2。推荐使用特定命令确保安装过程顺利,亲测有效。随后,使用清华镜像源安装TensorFlow_gpu=2..0。激活虚拟环境后,使用Python环境验证安装成功,通常通过特定命令检查GPU版本是否正确。
为了在Jupyter Notebook中利用该环境,需要安装ipykernel,并将环境写入notebook的kernel中。激活虚拟环境并打开Jupyter Notebook,通过命令确保内核安装成功。
对于ConvLSTM核心源码的解读,重点在于理解模型的构建与参数设置。模型核心代码通常包括输入数据维度、模型结构、超参数配置等。以官方样例为例,构建模型时需关注样本整理、标签设置、卷积核数量等关键参数。源码cp例如,输入数据维度为(None,,,1),输出数据维度为(None,None,,,)。通过返回序列设置,可以控制模型输出的形态,是返回单个时间步的输出还是整个输出序列。
在模型改造中,将彩色图像预测作为目标,需要调整模型的最后层参数,如将`return_sequence`参数更改为`False`,同时将`Conv3D`层修改为`Conv2D`层以适应预测彩色图像的需求。此外,选择合适的损失函数(如MAE)、优化器(如Adam)以及设置Metrics(如MAE)以便在训练过程中监控模型性能。
通过上述步骤,不仅能够搭建出适合特定研究或项目需求的TensorFlow_gpu环境,还能够深入理解并灵活应用ConvLSTM模型。希望本文内容能够为读者提供有价值的指导,并期待在后续过程中持续改进和完善。
3d稀疏卷积——spconv源码剖析(三)
构建Rulebook
下面看ops.get_indice_pairs,位于:spconv/ops.py
构建Rulebook由ops.get_indice_pairs接口完成
get_indice_pairs函数具体实现:
主要就是完成了一些参数的校验和预处理。首先,对于3d普通稀疏卷积,根据输入shape大小,kernel size,stride等参数计算出输出输出shape,子流行稀疏卷积就不必计算了,输出shape和输入shape一样大小
准备好参数之后就进入最核心的get_indice_pairs函数。因为spconv通过torch.ops.load_library加载.so文件注册,所以这里通torch.ops.spconv.get_indice_pairs这种方式来调用该函数。
算子注册:在src/spconv/all.cc文件中通过Pytorch提供的OP Register(算子注册的方式)对底层c++ api进行了注册,可以python接口形式调用c++算子
同C++ extension方式一样,OP Register也是Pytorch提供的一种底层扩展算子注册的方式。注册的算子可以通过 torch.xxx或者 tensor.xxx的方式进行调用,该方式同样与pytorch源码解耦,增加和修改算子不需要重新编译pytorch源码。轰炸+源码用该方式注册一个新的算子,流程非常简单:先编写C++相关的算子实现,然后通过pytorch底层的注册接口(torch::RegisterOperators),将该算子注册即可。
构建Rulebook实际通过python接口get_indice_pairs调用src/spconv/spconv_ops.cc文件种的getIndicePairs函数
代码位于:src/spconv/spconv_ops.cc
分析getIndicePairs直接将重心锁定在GPU逻辑部分,并且子流行3d稀疏卷积和正常3d稀疏卷积分开讨论,优先子流行3d稀疏卷积。
代码中最重要的3个变量分别为:indicePairs,indiceNum和gridOut,其建立过程如下:
indicePairs代表了稀疏卷积输入输出的映射规则,即Input Hash Table 和 Output Hash Table。这里分配理论最大的内存,它的shape为{ 2,kernelVolume,numAct},2表示输入和输出两个方向,kernelVolume为卷积核的volume size。例如一个3x3x3的卷积核,其volume size就是(3*3*3)。numAct表示输入有效(active)特征的数量。indiceNum用于保存卷积核每一个位置上的总的计算的次数,indiceNum对应中的count
代码中关于gpu建立rulebook调用create_submconv_indice_pair_cuda函数来完成,下面具体分析下create_submconv_indice_pair_cuda函数
子流线稀疏卷积
子流线稀疏卷积是调用create_submconv_indice_pair_cuda函数来构建rulebook
在create_submconv_indice_pair_cuda大可不必深究以下动态分发机制的运行原理。
直接将重心锁定在核函数:
prepareSubMGridKernel核函数中grid_size和block_size实则都是用的整形变量。其中block_size为tv::cuda::CUDA_NUM_THREADS,在include/tensorview/cuda_utils.h文件中定义,大小为。而grid_size大小通过tv::cuda::getBlocks(numActIn)计算得到,其中numActIn表示有效(active)输入数据的数量。
prepareSubMGridKernel作用:建立输出张量坐标(通过index表示)到输出序号之间的一张哈希表
见:include/spconv/indice.cu.h
这里计算index换了一种模板加递归的写法,看起来比较复杂而已。令:new_indicesIn = indicesIn.data(),可以推导得出index为:
ArrayIndexRowMajor位于include/tensorview/tensorview.h,其递归调用写法如下:
接着看核函数getSubMIndicePairsKernel3:
位于:include/spconv/indice.cu.h
看:
上述写法类似我们函数中常见的循环的写法,具体可以查看include/tensorview/kernel_utils.h
NumILP按默认值等于1的话,其stride也是gridDim.x*blockDim.x。索引最大值要小于该线程块的线程上限索引blockDim.x * gridDim.x,功能与下面代码类似:
参考: blog.csdn.net/ChuiGeDaQ...
必知必会的VGG网络(含代码)
牛津大学的视觉几何组设计的VGGNet,一种经典卷积神经网络架构,曾在年ILSVRC分类任务中获得第二名。现今,VGG依然广泛应用于图像识别、语音识别、机器翻译、机器人等领域。VGG包含层(VGG-)和层(VGG-),miniftp源码结构相似,由个卷积层和3个全连接层组成。与之前网络相比,VGG采用3*3卷积核替代7x7卷积核,2*3卷积核替代5*5卷积核,以减少参数,提升深度。
VGG-的结构图显示,包含conv(卷积层)、pool(池化层)和最后三个fc(全连接层)。VGG通过减少参数量,使得网络结构更加紧凑,从而提升模型的性能。
VGG-采用五组卷积与三个全连接层,最后使用Softmax进行分类。每个卷积层的参数量通过公式计算得出。特征图计算公式为输出图像大小(O)等于(输入图像大小(I)+2*填充(P)-卷积核大小(K))/步长(S)+1。
VGG-的代码实现可以通过构建一个Layer类,通过循环添加每个层的顺序执行来实现。具体代码可在关注公众号CV算法恩仇录后,回复VGG源码获取。
了解更多关于VGG的细节,请参阅相关链接:《VGG网络细节》 shimo.im/docs/dPkpKKErv...、《VGG网络》 blog.csdn.net/weixin_...
深入理解VGG,可参考《一文读懂VGG》/s/vWuGW4iMD1MjVDZVCqH_FA。
OpenCV中几种卷积的实现方式
自从opencv引入dnn模块后,卷积实现方式不断扩展,以适应PC、手机、边缘计算设备的部署需求。目前,可调用CUDA、OpenCL、Tengine、Vulkan实现卷积。Tengine、Vulkan特别适用于移动设备和边缘计算,它们内部是如何实现的?
Vulkan是一个渲染库,与OpenGL、DirectX等GPU渲染库相比,移动设备上使用较多,而深度学习模型又需要在移动设备上部署。仿古源码因此,探索是否可以使用Vulkan实现卷积等深度学习操作。
接下来,让我们看看OpenCV是如何使用Vulkan实现深度神经网络中的卷积。
打开OpenCV源码库的modules/dnn/src目录,可以看到最后一个文件夹是vkcom。"vkcom"这个名字由"Vulkan"库本身与"comp"(glsl语言的源代码后缀)组成。glsl语言可以通过以下命令编译:“vkcom”。GLSL是OpenGL着色语言,用于编写OpenGL着色器的编程语言,通常与并行处理功能强大的GPU结合使用。深度学习操作如卷积、池化都是对图像颜色的处理,因此可以将这些操作实现为着色器,用GLSL编写,然后使用Vulkan调用GPU。
Vulkan实现的卷积代码示例如下:
代码中指定了输入输出变量(第3、6、9、行)。在第行计算了输出变量convolved_image_data的值。第行开始的for循环遍历卷积核的c、w、h,计算单个像素位置的卷积结果。显然,这个卷积仅计算一个像素位置的卷积结果,卷积核的滑动过程由Vulkan管理GPU,多个GPU计算单元并行完成。
在OpenCV中,文件conv.comp首先被编译为二进制,然后将此二进制作为字符串放入conv_spv.cpp中。cpp文件定义了conv_spv数组,其中包含编译后的卷积着色器执行代码。由OpBase::createShaderModule函数将此二进制送入vkCreateShaderModule,从而调度GPU。
通过分析代码,可以看到Vulkan实现的算子被调用的方式,这同样适用于CUDA、OpenCL、Ngraph、Inference Engine等实现的算子。
Vulkan渲染库在OpenCV中的调用逻辑已经阐述完毕。Tengine是如何使用的?在convolution_layer.cpp的forward函数的行,调用了tengine_forward(tengine_graph)。
Tengine_forward来自teng_run_graph函数,我们只需调用库即可得到结果。传入的graph是卷积图,由create_conv_graph在第行创建。create_conv_graph使用create_conv_node、create_input_node生成卷积算子所需的图。
使用Tengine相对使用Vulkan、CUDA等库完成算子,要简单许多。调用库内的函数生成节点,使用节点构建图即可,无需自己实现算子内的计算。
本文概述了OpenCV中卷积实现方式的多样性,以下为总结:
本文详细分析了使用Vulkan用着色器实现卷积计算的方法及其调用路径,这个路径在分析其他类型实现时也很有用。本文还探讨了不同库算子的兼容性。当然,不同算子兼容还涉及更多细节,本文仅关注卷积forward函数的传递。
本文后半部分简要介绍了Tengine在OpenCV中的集成。发现集成过程相对简单,在convolution_layer.cpp中直接运行Tengine库构建的卷积计算图。这也表明,如果存在更好的边缘计算库,很容易集成到OpenCV中。
通过几天的分析,我们已经了解了OpenCL、Vulkan、Tengine的实现方式。可以预计,CUDA、Halide、Inference Engine nn、Inference Engine NGraph等实现也会类似。
更灵活、有个性的卷积——可变形卷积(Deformable Conv)
Deformable Conv:我是个会变形的个性boy
传统的卷积操作面临复杂形变物体时,效果可能不佳。为解决这一问题,Deformable Conv 出现了,他灵活地引入了偏移量,使得感受野与物体形状更加贴近,无论物体如何形变,都能轻松应对。Deformable Conv 的大法在于为每个点引入偏移量,这使得输出特征图的每个点加上对应卷积核每个位置的相对坐标后,再加上自学习的偏移量。通过双线性插值,Deformable Conv 能够计算出非整数位置的像素值,最终实现可变形卷积操作。解析源码,我们看到常规操作中使用 nn.Module 的子类封装了可变形卷积,引入了可选参数 modulation,以及生成偏移量的卷积 p_conv 和实际进行卷积的卷积 conv。通过初始化权重和计算偏移后的位置,Deformable Conv 能够计算出每个位置的像素值,实现真正的卷积操作。总结,Deformable Conv 是处理复杂形变物体的有效方法,其源码解析让我们深入了解了这一技术的核心。感谢阅读,欢迎在评论区交流讨论!
3d稀疏卷积——spconv源码剖析(一)
本文主要阐述卷积的基本理论,并以spconv源码为例进行解析。首先,介绍2D与3D卷积的基础知识及其分类。随后,深入探讨3D稀疏卷积的工作原理。
2D卷积涉及卷积核在二维图像空间上的滑动操作。它分为单通道卷积与多通道卷积。单通道卷积在输入图像的单一通道上进行,得到特征图。多通道卷积在同一图像中不同通道上进行,每个通道得到一个对应的新通道,最终通过相加生成特征图。
3D卷积在此基础上扩展到三维空间,涉及单通道与多通道情况。三维单通道卷积在立方体上进行,而三维多通道卷积则处理拥有多个通道的三维图像。
2D与3D卷积计算涉及输入层、输出层与参数关系的数学公式。考虑偏置参数与计算量,FLOPS(浮点运算量)也在此阶段被计算。
稀疏卷积分为SC(Sparse Convolution)与VSC(Valid Sparse Convolution)两种类型。SC卷积计算激活站点并丢弃非激活站点,而VSC卷积在SC的基础上进行了简化。
卷积神经网络对三维点云数据处理时,面临计算量增加的问题,而SC与VSC卷积利用稀疏性实现高效处理。构建输入与输出哈希表,对点云数据进行快速访问。GetOffset()函数用于定位卷积操作的位置,Rulebook用于存储原子操作规则,指导稀疏卷积过程。
稀疏卷积的关键在于构建输入、输出哈希表以及建立两者之间的联系,实现对稀疏数据的有效处理。spconv库中的get_indice_pairs函数通过调用getIndicePairs实现这一过程。
PyTorch 源码解读之 BN & SyncBN:BN 与 多卡同步 BN 详解
BatchNorm原理 BatchNorm最早在全连接网络中提出,旨在对每个神经元的输入进行归一化操作。在卷积神经网络(CNN)中,这一原理被扩展为对每个卷积核的输入进行归一化,即在channel维度之外的所有维度上进行归一化。BatchNorm带来的优势包括提高网络的收敛速度、稳定训练过程、减少过拟合现象等。 BatchNorm的数学表达式为公式[1],引入缩放因子γ和移位因子β,作者在文章中解释了它们的作用。 PyTorch中与BatchNorm相关的类主要位于torch.nn.modules.batchnorm模块中,包括如下的类:_NormBase、BatchNormNd。 具体实现细节如下: _NormBase类定义了BN相关的一些属性。 初始化过程。 模拟BN的forward过程。 running_mean、running_var的更新逻辑。 γ、β参数的更新方式。 BN在eval模式下的行为。 BatchNormNd类包括BatchNorm1d、BatchNorm2d、BatchNorm3d,它们的区别在于检查输入的合法性,BatchNorm1d接受2D或3D的输入,BatchNorm2d接受4D的输入,BatchNorm3d接受5D的输入。 接着,介绍SyncBatchNorm的实现。 BN性能与batch size密切相关。在batch size较小的场景中,如检测任务,内存占用较高,单张显卡难以处理较多,导致BN效果不佳。SyncBatchNorm提供了解决方案,其原理是所有计算设备共享同一组BN参数,从而获得全局统计量。 SyncBatchNorm在torch/nn/modules/batchnorm.py和torch/nn/modules/_functions.py中实现,前者负责输入合法性检查以及参数设置,后者负责单卡统计量计算和进程间通信。 SyncBatchNorm的forward过程。 复习方差计算方式。 单卡计算均值、方差,进行归一化处理。 同步所有卡的数据,得到全局均值mean_all和逆标准差invstd_all,计算全局统计量。 接着,介绍SyncBatchNorm的backward过程。 在backward过程中,需要在BN前后进行进程间通信。这在_functions.SyncBatchNorm中实现。 计算weight、bias的梯度以及γ、β,进一步用于计算梯度。deformable变形卷积pytorch实现(第二节deformable_conv2d 实现一)
修改理解:年3月,对num_groups参数的理解进行了修正。若仍有疑问,欢迎大家指出。
内容概述:这一节将介绍deformable_conv2d的实现细节及常见坑点。旨在帮助后来者简化实现过程。如有错误,敬请指正。文章已链接。
目标实现:仅实现所需的deformable_conv2d部分,deformable roi部分未实现。复现旨在翻译原文,理解映射规则,结果易于推导。
原理说明:deformable convolution设计目的是让网络学习卷积核形状。通过额外的Conv2d层学习每个位置的位移和置信度参数。数据经过卷积后,输出用于变形卷积的offset和mask,接着进行卷积,最终输出。
参数解释:包含两个卷积核,一个用于变形卷积,一个用于学习。输入包括数据流、卷积核、offset、mask,以及固定参数如stride、padding、dilation等。关注num_groups、deformable_groups、im2col_step,理解其功能。
实现细节:实现三个cuda核函数,分别为变形卷积前的im2col、卷积后的col2im、处理坐标信息的col2im_coord。核心在于计算卷积参数位置并进行线性插值,乘以置信mask。
代码实现:主要实现forward和backward函数。forward部分需要多次生成列矩阵以匹配结果。具体细节和cuda核函数可参阅源代码,核心在于定位参数并执行插值运算。
后续内容:其余部分如backward等将在后续文章中讨论。写作过程较为匆忙,欢迎讨论交流。
2024-11-28 05:56
2024-11-28 05:11
2024-11-28 05:04
2024-11-28 05:03
2024-11-28 04:09
2024-11-28 03:48