1.PyTorch进阶1:C++扩展
2.强化学习ppo算法源码
3.图解大模型训练之:Megatron源码解读2,反向反模型并行
4.Pytorch源码剖析:nn.Module功能介绍及实现原理
5.å·ç§¯ç¥ç»ç½ç»
6.3d稀疏卷积——spconv源码剖析(五)
PyTorch进阶1:C++扩展
本文介绍如何使用C++扩展来优化PyTorch模型性能,以实现LLTM(Long-Long-Term-Memory)循环单元为例。源码源码通过自定义扩展,反向反可以显著提升模型在Python解释器和CUDA核心加载方面的传播传播效率。
实现LLTM模型时,源码源码smpp源码直接通过PyTorch的反向反Module或Function实现前向传播可能已足够,但为了进一步优化性能,传播传播可以使用C++或CUDA重写关键部分。源码源码C++扩展有预先构建和即时构建两种风格。反向反
预先构建风格通过setuptools的传播传播setup.py脚本完成,简化了配置和管理混合C++/CUDA扩展的源码源码编译流程。预先构建风格在编译时完成所有步骤,反向反适用于模型优化中需要频繁调用的传播传播特定操作。
即时构建则通过torch.utils.cpp_extension.load()函数实现,源码源码提供了一种简便的编译和加载扩展方法,无需维护单独的构建文件。即时构建在首次运行时可能需要额外时间来编译扩展,但后续加载速度较快,尤其当源码未改变时。
在实现C++操作时,关键在于编写前向传播和反向传播函数。反向传播函数通常需要额外实现,以计算损失关于每个输入的导数。这些函数被整合进torch.autograd.Function以创建Python绑定。
绑定C++扩展到Python使用pybind,确保了Python和C++代码之间的ssccdl源码无缝交互。设置目录结构和导入torch库后,将C++扩展导入PyTorch,从而能够从Python调用C++函数。
性能对比方面,C++版本相较于纯Python实现展现出显著加速,尤其是在前向传播环节。反向传播的加速效果可能不明显,但整体上,PyTorch的自动微分引擎通过C++实现,提供高效的操作流。
在GPU设备上,通过CUDA张量实现性能提升更为明显。ATen后端的设备抽象特性使得同样的代码能够在CPU和GPU上运行,并利用GPU优化的实现加速关键操作。对于大规模计算,利用CUDA核心编写特定的核心代码可以进一步提升性能。
总的来说,使用C++扩展优化PyTorch模型性能是一种有效策略,尤其是在模型计算密集型场景中,能够显著提升运行效率。通过选择预先构建或即时构建风格,开发者可以根据具体需求和场景灵活选择实现方式。
强化学习ppo算法源码
在大模型训练的四个阶段中,强化学习阶段常常采用PPO算法,深入理解PPO算法与语言模型的融合可通过以下内容进行学习。以下代码解析主要参考了一篇清晰易懂的hostcms源码文章。 通过TRL包中的PPO实现,我们来逐步分析其与语言模型的结合过程。核心代码涉及到question_tensors、response_tensors和rewards,分别代表输入、模型生成的回复和奖励模型对输入加回复的评分。 训练过程中,trainer.step主要包含以下步骤:首先,将question_tensors和response_tensors输入语言模型,获取all_logprobs(每个token的对数概率)、logits_or_none(词表概率)、values(预估收益)和masks(掩码)。其中,如果没有设置return_logits=True,logits_or_none将为None,若设置则为[batch_size, response_length, vocab_size]。
接着,将输入传递给参考语言模型,得到类似的结果。
计算reward的过程涉及reference model和reward model,最终的奖励rewards通过compute_rewards函数计算,参考公式1和2。
计算优势advantage,依据公式3和4调整。
在epoch和batch中,对question_tensors和response_tensors再次处理,roadhog 源码并设置return_logits=True,进入minbatch训练。
训练中,loss分为critic_loss(评论家损失,参考公式8)和actor_loss(演员损失,参考公式7),两者通过公式9合并,反向传播更新语言模型参数。
PPO相较于TRPO算法有两大改进:PPO-Penalty通过拉格朗日乘数法限制策略更新的KL散度,体现在actor_loss中的logprobs - old_logprobs;PPO-Clip则在目标函数中设定阈值,确保策略更新的平滑性,pg_losses2(加上正负号)部分体现了这一点。 对于初学者来说,这个过程可能有些复杂,但理解和实践后,将有助于掌握PPO在语言模型中的应用。参考资源可继续深入学习。图解大模型训练之:Megatron源码解读2,模型并行
源码解读系列将深入探讨Megatron的预训练部分代码,聚焦于模型并行策略。在上一篇文章中,我们详细介绍了如何在分布式环境中初始化模型,包括按照DP/TP/PP对进程进行分组,并为每个进程分配GPU。接下来,我们将探索如何将模型进行切分,bashbunny源码并将其整合到分布式环境定义好的DP/TP/PP组中。
在Megatron中,通过预先设定的DP/TP/PP组,我们能够将模型进行有效的切割。这种切割方法既考虑了模型的并行性,又兼顾了内存和计算资源的优化。为了实现这一目标,我们需要在CPU上定义并初始化模型,然后将其搬运到当前进程所对应的GPU上。
模型切割的核心思想是面向进程编程,这意味着我们的脚本处理的是发生在单个进程上的任务。这样做的好处是,我们只需维护一份脚本,然后将其部署到不同机器的GPU上执行,从而实现全局并行计算。然而,每个进程处理的模型部分不同,比如在GPT模型中,预处理层涉及词嵌入计算,而后续层则涉及到softmax和损失函数的计算。为了解决模型差异性问题,我们可以通过进程ID来控制随机种子的设定,确保模型初始化的一致性。
在分布式训练中,随机种子的设定至关重要,它直接影响到模型的复现性。例如,当我们采用激活检查点技术来节省内存时,在反向传播过程中需要重新计算前向传播得到的激活值,此时就需要确保模型能够完全复现前向过程的初始化结果。通过设定不同的随机种子,我们能够确保每个模型部分在切割后仍能保持初始化的独立性和一致性。
在模型切割部分,我们有两种主要的初始化方式:先进行整体初始化再进行切割(称为“CPU上的初始化”),以及直接在GPU上进行局部初始化(称为“在GPU上的初始化”)。这两种方式的核心区别在于随机种子的设定策略。正确选择随机种子的策略,对于确保模型的复现性至关重要。
模型并行框架在Megatron中通过预定义的函数实现,例如在megatron/training.py中的pretrain函数。这个函数作为模型并行的入口,主要包含了模型架构定义、模型切割、设置优化器和学习率调整等关键步骤。在具体实现中,模型切割主要通过定义预处理层(pre_process)和后处理层(post_process)来完成,这有助于确保模型切割后首尾层和中间层的架构一致性。
在分布式模型中,如CodeGeeX,模型的切割遵循特定的策略,以确保模型在不同GPU上的并行执行。每个进程对应模型的一部分,通过AllReduce操作确保模型输出的完整性,以便下一层能够接收正确的输入。同时,每个进程负责独立计算模型的一部分,从而实现高效的并行处理。
在Megatron中,模型切割部分涉及到一系列的类定义和函数实现,包括MegatronModule、Embedding、VocabParallelEmbedding、ParallelSelfAttention等。这些类和函数在模型切割、并行层和交叉熵计算等方面发挥着关键作用。例如,MegatronModule类确保了模型的输入和输出层共用词嵌入,以满足特定的并行要求。同时,模型中的注意力层(如ParallelSelfAttention)通过“列切割”和“行切割”策略实现高效的并行计算。
模型的最后一层,即交叉熵的计算,同样通过类定义实现。在Megatron中,交叉熵计算通过平行化处理来优化内存使用和加速计算。通过将计算逻辑进行精简和优化,Megatron能够实现高效的并行交叉熵计算,以满足大规模模型训练的需求。
总之,Megatron的模型并行策略通过一系列的代码实现,旨在优化大规模模型的训练过程,提高计算效率和资源利用。通过合理地切割模型、设置随机种子、实现并行层和交叉熵计算,Megatron能够在分布式环境中实现高效、稳定的模型训练。
Pytorch源码剖析:nn.Module功能介绍及实现原理
nn.Module作为Pytorch的核心类,是构建模型的基础。它提供了一系列功能,包括记录模型的参数,实现网络的前向传播,加载和保存模型数据,以及进行设备和数据类型转换等。这些功能在模型的训练和应用中起到关键作用。
在训练与评估模式间切换,模块的行为会有所不同,如rrelu、dropout、batchnorm等操作在两种模式下表现不同。可学习的参数,如权重和偏置,需要通过梯度下降进行更新。非学习参数,比如batchnorm的running_mean,是训练过程中的统计结果。_buffers包含的Tensor不作为模型的一部分保存。
模块内部包含一系列钩子(hook)函数,用于在特定的前向传播或反向传播阶段执行自定义操作。子模块列表用于存储模型中的所有子模块。
魔术函数__init__在声明对象时自动调用,优化性能的关键在于使用super().__setattr__而非直接赋值。super调用父类的方法,避免不必要的检查,提高效率。使用register_buffer为模块注册可变的中间结果,例如BatchNorm的running_mean。register_parameter用于注册需要梯度下降更新的参数。
递归应用函数用于对模型进行操作,如参数初始化。可以将模型移动到指定设备,转换数据类型,以及注册钩子函数以实现对网络的扩展和修改。
调用魔术方法__call__执行前向传播。nn.Module未实现forward函数,子类需要提供此方法的具体实现。对于线性层等,forward函数定义了特定的运算流程。从检查点加载参数时,模块自动处理兼容性问题,确保模型结构与参数值的兼容。
模块的__setattr__方法被重写,以区别对待Parameter、Module和Buffer。当尝试设置这些特定类型的属性时,执行注册或更新操作。其他属性的设置遵循标准的Python行为。
模块的save方法用于保存模型参数和状态,确保模型结构和参数值在不同设备间转移时的一致性。改变训练状态(如将模型切换到训练或评估模式)是模块管理过程的重要组成部分。
å·ç§¯ç¥ç»ç½ç»
1ãäºç»´äºç¸å ³è¿ç®
äºç»´äºç¸å ³ï¼cross-correlationï¼è¿ç®çè¾å ¥æ¯ä¸ä¸ªäºç»´è¾å ¥æ°ç»åä¸ä¸ªäºç»´æ ¸ï¼kernelï¼æ°ç»ï¼è¾åºä¹æ¯ä¸ä¸ªäºç»´æ°ç»ï¼å ¶ä¸æ ¸æ°ç»é常称为å·ç§¯æ ¸æè¿æ»¤å¨ï¼filterï¼ãå·ç§¯æ ¸ç尺寸é常å°äºè¾å ¥æ°ç»ï¼å·ç§¯æ ¸å¨è¾å ¥æ°ç»ä¸æ»å¨ï¼å¨æ¯ä¸ªä½ç½®ä¸ï¼å·ç§¯æ ¸ä¸è¯¥ä½ç½®å¤çè¾å ¥åæ°ç»æå ç´ ç¸ä¹å¹¶æ±åï¼å¾å°è¾åºæ°ç»ä¸ç¸åºä½ç½®çå ç´ ãå¾1å±ç¤ºäºä¸ä¸ªäºç¸å ³è¿ç®çä¾åï¼é´å½±é¨ååå«æ¯è¾å ¥ç第ä¸ä¸ªè®¡ç®åºåãæ ¸æ°ç»ä»¥å对åºçè¾åºã
2ãäºç»´å·ç§¯å±
å·ç§¯å±å¾åäºå·ç§¯è¿ç®ï¼ä½å·ç§¯å±ä¸ç¨å°ç并éå·ç§¯è¿ç®èæ¯äºç¸å ³è¿ç®ãæ们å°æ ¸æ°ç»ä¸ä¸ç¿»è½¬ãå·¦å³ç¿»è½¬ï¼åä¸è¾å ¥æ°ç»åäºç¸å ³è¿ç®ï¼è¿ä¸è¿ç¨å°±æ¯å·ç§¯è¿ç®ãç±äºå·ç§¯å±çæ ¸æ°ç»æ¯å¯å¦ä¹ çï¼æ以使ç¨äºç¸å ³è¿ç®ä¸ä½¿ç¨å·ç§¯è¿ç®å¹¶æ æ¬è´¨åºå«ã
äºç»´å·ç§¯å±å°è¾å ¥åå·ç§¯æ ¸åäºç¸å ³è¿ç®ï¼å¹¶å ä¸ä¸ä¸ªæ éåç½®æ¥å¾å°è¾åºãå·ç§¯å±ç模ååæ°å æ¬å·ç§¯æ ¸åæ éåç½®ã
3ãç¹å¾å¾ä¸æåé
äºç»´å·ç§¯å±è¾åºçäºç»´æ°ç»å¯ä»¥çä½æ¯è¾å ¥å¨ç©ºé´ç»´åº¦ï¼å®½åé«ï¼ä¸æä¸çº§ç表å¾ï¼ä¹å«ç¹å¾å¾ï¼feature mapï¼ãå½±åå ç´ xçåå计ç®çææå¯è½è¾å ¥åºåï¼å¯è½å¤§äºè¾å ¥çå®é 尺寸ï¼å«åxçæåéï¼receptive fieldï¼ã
以å¾1为ä¾ï¼è¾å ¥ä¸é´å½±é¨åçå个å ç´ æ¯è¾åºä¸é´å½±é¨åå ç´ çæåéãæ们å°å¾ä¸å½¢ç¶ä¸º2Ã2çè¾åºè®°ä¸ºYï¼å°Yä¸å¦ä¸ä¸ªå½¢ç¶ä¸º2Ã2çæ ¸æ°ç»åäºç¸å ³è¿ç®ï¼è¾åºå个å ç´ zãé£ä¹ï¼zå¨Yä¸çæåéå æ¬Yçå ¨é¨å个å ç´ ï¼å¨è¾å ¥ä¸çæåéå æ¬å ¶ä¸å ¨é¨9个å ç´ ãå¯è§ï¼æ们å¯ä»¥éè¿æ´æ·±çå·ç§¯ç¥ç»ç½ç»ä½¿ç¹å¾å¾ä¸å个å ç´ çæåéåå¾æ´å 广éï¼ä»èææè¾å ¥ä¸æ´å¤§å°ºå¯¸çç¹å¾ã
4ãå¡«å åæ¥å¹
æ们ä»ç»å·ç§¯å±çä¸¤ä¸ªè¶ åæ°ï¼å³å¡«å åæ¥å¹ ï¼å®ä»¬å¯ä»¥å¯¹ç»å®å½¢ç¶çè¾å ¥åå·ç§¯æ ¸æ¹åè¾åºå½¢ç¶ã
4.1 å¡«å ï¼paddingï¼
æ¯æå¨è¾å ¥é«å宽ç两侧填å å ç´ ï¼é常æ¯0å ç´ ï¼ï¼å¾2éæ们å¨åè¾å ¥é«å宽ç两侧åå«æ·»å äºå¼ä¸º0çå ç´ ã
å¦æåè¾å ¥çé«åå®½æ¯ å ï¼å·ç§¯æ ¸çé«åå®½æ¯ å ï¼å¨é«ç两侧ä¸å ±å¡«å è¡ï¼å¨å®½ç两侧ä¸å ±å¡«å åï¼åè¾åºå½¢ç¶ä¸ºï¼
)
æ们å¨å·ç§¯ç¥ç»ç½ç»ä¸ä½¿ç¨å¥æ°é«å®½çæ ¸ï¼æ¯å¦3Ã3ï¼5Ã5çå·ç§¯æ ¸ï¼å¯¹äºé«åº¦ï¼æ宽度ï¼ä¸ºå¤§å°ä¸º2k+1çæ ¸ï¼ä»¤æ¥å¹ 为1ï¼å¨é«ï¼æ宽ï¼ä¸¤ä¾§éæ©å¤§å°ä¸ºkçå¡«å ï¼ä¾¿å¯ä¿æè¾å ¥ä¸è¾åºå°ºå¯¸ç¸åã
4.2 æ¥å¹ ï¼strideï¼
å¨äºç¸å ³è¿ç®ä¸ï¼å·ç§¯æ ¸å¨è¾å ¥æ°ç»ä¸æ»å¨ï¼æ¯æ¬¡æ»å¨çè¡æ°ä¸åæ°å³æ¯æ¥å¹ ï¼strideï¼ãæ¤åæ们使ç¨çæ¥å¹ é½æ¯1ï¼å¾3å±ç¤ºäºå¨é«ä¸æ¥å¹ 为3ãå¨å®½ä¸æ¥å¹ 为2çäºç»´äºç¸å ³è¿ç®ã
ä¸è¬æ¥è¯´ï¼å½é«ä¸æ¥å¹ 为 ï¼å®½ä¸æ¥å¹ 为 æ¶ï¼è¾åºå½¢ç¶ä¸ºï¼
å¦æ ,é£ä¹è¾åºå½¢ç¶å°ç®å为ï¼
æ´è¿ä¸æ¥ï¼å¦æè¾å ¥çé«å宽è½åå«è¢«é«å宽ä¸çæ¥å¹ æ´é¤ï¼é£ä¹è¾åºå½¢ç¶å°æ¯:(nh/sh)Ã(nw/sw)
å½ æ¶ï¼æ们称填å 为pï¼å½ æ¶ï¼æ们称æ¥å¹ 为sã
5ãå¤è¾å ¥ééåå¤è¾åºéé
ä¹åçè¾å ¥åè¾åºé½æ¯äºç»´æ°ç»ï¼ä½çå®æ°æ®ç维度ç»å¸¸æ´é«ãä¾å¦ï¼å½©è²å¾åå¨é«å宽2个维度å¤è¿æRGBï¼çº¢ã绿ãèï¼3个é¢è²ééãå设彩è²å¾åçé«å宽åå«æ¯håwï¼åç´ ï¼ï¼é£ä¹å®å¯ä»¥è¡¨ç¤ºä¸ºä¸ä¸ª3ÃhÃwçå¤ç»´æ°ç»ï¼æ们å°å¤§å°ä¸º3çè¿ä¸ç»´ç§°ä¸ºééï¼channelï¼ç»´ã
5.1 å¤è¾å ¥éé
å·ç§¯å±çè¾å ¥å¯ä»¥å å«å¤ä¸ªééï¼å¾4å±ç¤ºäºä¸ä¸ªå«2个è¾å ¥ééçäºç»´äºç¸å ³è®¡ç®çä¾åã
5.2 å¤è¾åºéé
å·ç§¯å±çè¾åºä¹å¯ä»¥å å«å¤ä¸ªééï¼è®¾å·ç§¯æ ¸è¾å ¥ééæ°åè¾åºééæ°åå«ä¸ºciåcoï¼é«å宽åå«ä¸ºkhåkwãå¦æå¸æå¾å°å«å¤ä¸ªééçè¾åºï¼æ们å¯ä»¥ä¸ºæ¯ä¸ªè¾åºééåå«å建形ç¶ä¸ºciÃkhÃkwçæ ¸æ°ç»ï¼å°å®ä»¬å¨è¾åºééç»´ä¸è¿ç»ï¼å·ç§¯æ ¸çå½¢ç¶å³coÃciÃkhÃkwã
对äºè¾åºééçå·ç§¯æ ¸ï¼æ们æä¾è¿æ ·ä¸ç§ç解ï¼ä¸ä¸ªciÃkhÃkwçæ ¸æ°ç»å¯ä»¥æåæç§å±é¨ç¹å¾ï¼ä½æ¯è¾å ¥å¯è½å ·æç¸å½ä¸°å¯çç¹å¾ï¼æ们éè¦æå¤ä¸ªè¿æ ·çciÃkhÃkwçæ ¸æ°ç»ï¼ä¸åçæ ¸æ°ç»æåçæ¯ä¸åçç¹å¾ã
5.3 1x1å·ç§¯å±
æå讨论形ç¶ä¸º1Ã1çå·ç§¯æ ¸ï¼æ们é常称è¿æ ·çå·ç§¯è¿ç®ä¸º1Ã1å·ç§¯ï¼ç§°å å«è¿ç§å·ç§¯æ ¸çå·ç§¯å±ä¸º1Ã1å·ç§¯å±ãå¾5å±ç¤ºäºä½¿ç¨è¾å ¥ééæ°ä¸º3ãè¾åºééæ°ä¸º2ç1Ã1å·ç§¯æ ¸çäºç¸å ³è®¡ç®ã
1Ã1å·ç§¯æ ¸å¯å¨ä¸æ¹åé«å®½çæ åµä¸ï¼è°æ´ééæ°ã1Ã1å·ç§¯æ ¸ä¸è¯å«é«å宽维度ä¸ç¸é»å ç´ ææç模å¼ï¼å ¶ä¸»è¦è®¡ç®åçå¨ééç»´ä¸ãå设æ们å°ééç»´å½ä½ç¹å¾ç»´ï¼å°é«å宽维度ä¸çå ç´ å½ææ°æ®æ ·æ¬ï¼é£ä¹1Ã1å·ç§¯å±çä½ç¨ä¸å ¨è¿æ¥å±çä»·ã
6ãå·ç§¯å±ä¸å ¨è¿æ¥å±ç对æ¯
äºç»´å·ç§¯å±ç»å¸¸ç¨äºå¤çå¾åï¼ä¸æ¤åçå ¨è¿æ¥å±ç¸æ¯ï¼å®ä¸»è¦æ两个ä¼å¿ï¼
ä¸æ¯å ¨è¿æ¥å±æå¾åå±å¹³æä¸ä¸ªåéï¼å¨è¾å ¥å¾åä¸ç¸é»çå ç´ å¯è½å 为å±å¹³æä½ä¸åç¸é»ï¼ç½ç»é¾ä»¥ææå±é¨ä¿¡æ¯ãèå·ç§¯å±ç设计ï¼å¤©ç¶å°å ·ææåå±é¨ä¿¡æ¯çè½åã
äºæ¯å·ç§¯å±çåæ°éæ´å°ãä¸èèåç½®çæ åµä¸ï¼ä¸ä¸ªå½¢ç¶ä¸º(ci,co,h,w)çå·ç§¯æ ¸çåæ°éæ¯ciÃcoÃhÃwï¼ä¸è¾å ¥å¾åç宽é«æ å ³ãåå¦ä¸ä¸ªå·ç§¯å±çè¾å ¥åè¾åºå½¢ç¶åå«æ¯(c1,h1,w1)å(c2,h2,w2)ï¼å¦æè¦ç¨å ¨è¿æ¥å±è¿è¡è¿æ¥ï¼åæ°æ°éå°±æ¯c1Ãc2Ãh1Ãw1Ãh2Ãw2ã使ç¨å·ç§¯å±å¯ä»¥ä»¥è¾å°çåæ°æ°éæ¥å¤çæ´å¤§çå¾åã
X=torch.rand(4,2,3,5)
print(X.shape)
conv2d=nn.Conv2d(in_channels=2,out_channels=3,kernel_size=(3,5),stride=1,padding=(1,2))
Y=conv2d(X)
print('Y.shape: ',Y.shape)
print('weight.shape: ',conv2d.weight.shape)
print('bias.shape: ',conv2d.bias.shape)
è¾åºï¼
torch.Size([4, 2, 3, 5])
Y.shape: torch.Size([4, 3, 3, 5])
weight.shape: torch.Size([3, 2, 3, 5])
bias.shape: torch.Size([3])
7ãæ± å
7.1 äºç»´æ± åå±
æ± åå±ä¸»è¦ç¨äºç¼è§£å·ç§¯å±å¯¹ä½ç½®çè¿åº¦æææ§ãåå·ç§¯å±ä¸æ ·ï¼æ± åå±æ¯æ¬¡å¯¹è¾å ¥æ°æ®çä¸ä¸ªåºå®å½¢ç¶çªå£ï¼åç§°æ± åçªå£ï¼ä¸çå ç´ è®¡ç®è¾åºï¼æ± åå±ç´æ¥è®¡ç®æ± åçªå£å å ç´ çæ大å¼æè å¹³åå¼ï¼è¯¥è¿ç®ä¹åå«å«åæå¤§æ± åæå¹³åæ± åãå¾6å±ç¤ºäºæ± åçªå£å½¢ç¶ä¸º2Ã2çæå¤§æ± åã
äºç»´å¹³åæ± åçå·¥ä½åçä¸äºç»´æå¤§æ± å类似ï¼ä½å°æ大è¿ç®ç¬¦æ¿æ¢æå¹³åè¿ç®ç¬¦ãæ± åçªå£å½¢ç¶ä¸ºpÃqçæ± åå±ç§°ä¸ºpÃqæ± åå±ï¼å ¶ä¸çæ± åè¿ç®å«ä½pÃqæ± åã
æ± åå±ä¹å¯ä»¥å¨è¾å ¥çé«å宽两侧填å 并è°æ´çªå£ç移å¨æ¥å¹ æ¥æ¹åè¾åºå½¢ç¶ãæ± åå±å¡«å åæ¥å¹ ä¸å·ç§¯å±å¡«å åæ¥å¹ çå·¥ä½æºå¶ä¸æ ·ã
å¨å¤çå¤ééè¾å ¥æ°æ®æ¶ï¼æ± åå±å¯¹æ¯ä¸ªè¾å ¥ééåå«æ± åï¼ä½ä¸ä¼åå·ç§¯å±é£æ ·å°åééçç»ææééç¸å ãè¿æå³çæ± åå±çè¾åºééæ°ä¸è¾å ¥ééæ°ç¸çã
CNNç½ç»ä¸å¦å¤ä¸ä¸ªä¸å¯å¯¼çç¯èå°±æ¯Poolingæ± åæä½ï¼å 为Poolingæä½ä½¿å¾feature mapç尺寸ååï¼åå¦å2Ã2çæ± åï¼å设é£ä¹ç¬¬l+1å±çfeature mapæ个梯度ï¼é£ä¹ç¬¬lå±å°±ä¼æ个梯度ï¼è¿ä½¿å¾æ¢¯åº¦æ æ³å¯¹ä½çè¿è¡ä¼ æä¸å»ãå ¶å®è§£å³è¿ä¸ªé®é¢çææ³ä¹å¾ç®åï¼å°±æ¯æ1个åç´ çæ¢¯åº¦ä¼ éç»4个åç´ ï¼ä½æ¯éè¦ä¿è¯ä¼ éçlossï¼æè 梯度ï¼æ»åä¸åãæ ¹æ®è¿æ¡ååï¼mean poolingåmax poolingçååä¼ æä¹æ¯ä¸åçã
7.2 mean pooling
mean poolingçååä¼ æå°±æ¯æä¸ä¸ªpatchä¸çå¼æ±åå¹³åæ¥åpoolingï¼é£ä¹ååä¼ æçè¿ç¨ä¹å°±æ¯ææ个å ç´ ç梯度çå为n份åé ç»åä¸å±ï¼è¿æ ·å°±ä¿è¯æ± åååç梯度ï¼æ®å·®ï¼ä¹åä¿æä¸åï¼è¿æ¯æ¯è¾ç解çï¼å¾ç¤ºå¦ä¸ï¼
mean poolingæ¯è¾å®¹æ让人ç解éçå°æ¹å°±æ¯ä¼ç®åç认为ç´æ¥æ梯度å¤å¶Néä¹åç´æ¥ååä¼ æåå»ï¼ä½æ¯è¿æ ·ä¼é ælossä¹åå为åæ¥çNåï¼ç½ç»æ¯ä¼äº§ç梯度çç¸çã
7.3 max pooling
max poolingä¹è¦æ»¡è¶³æ¢¯åº¦ä¹åä¸åçååï¼max poolingçååä¼ ææ¯æpatchä¸æ大çå¼ä¼ éç»åä¸å±ï¼èå ¶ä»åç´ çå¼ç´æ¥è¢«èå¼æãé£ä¹ååä¼ æä¹å°±æ¯æ梯度ç´æ¥ä¼ ç»åä¸å±æä¸ä¸ªåç´ ï¼èå ¶ä»åç´ ä¸æ¥å梯度ï¼ä¹å°±æ¯ä¸º0ãæ以max poolingæä½åmean poolingæä½ä¸åç¹å¨äºéè¦è®°å½ä¸æ± åæä½æ¶å°åºåªä¸ªåç´ çå¼æ¯æ大ï¼ä¹å°±æ¯max idã
æºç ä¸æä¸ä¸ªmax_idx_çåéï¼è¿ä¸ªåéå°±æ¯è®°å½æ大å¼æå¨ä½ç½®çï¼å 为å¨ååä¼ æä¸è¦ç¨å°ï¼é£ä¹å设ååä¼ æåååä¼ æçè¿ç¨å°±å¦ä¸å¾æ示ã
7.4 Pytorch å®ç°æ± åå±
æ们使ç¨Pytorchä¸çnn.MaxPool2då®ç°æå¤§æ± åå±ï¼å ³æ³¨ä»¥ä¸æé å½æ°åæ°ï¼
kernel_size â the size of the window to take a max over
stride â the stride of the window. Default value is kernel_size
padding â implicit zero padding to be added on both sides
forwardå½æ°çåæ°ä¸ºä¸ä¸ªåç»´å¼ éï¼å½¢ç¶ä¸º ï¼è¿åå¼ä¹æ¯ä¸ä¸ªåç»´å¼ éï¼å½¢ç¶ä¸º ï¼å ¶ä¸Næ¯æ¹é大å°ï¼C,H,Wåå«è¡¨ç¤ºééæ°ãé«åº¦ã宽度ã
X=torch.arange(,dtype=torch.float).view(1,2,4,4)
pool2d=nn.MaxPool2d(kernel_size=3,padding=1,stride=(2,1))
Y=pool2d(X)
print(X)
print(Y)
ç»ä¹
1ãåå¦ä½ ç¨å ¨è¿æ¥å±å¤çä¸å¼ \times Ãç彩è²ï¼RGBï¼å¾åï¼è¾åºå å«ä¸ªç¥ç»å ï¼å¨ä½¿ç¨åç½®çæ åµä¸ï¼åæ°æ°éæ¯ï¼
çï¼å¾åå±å¹³åé¿åº¦ä¸º3ÃÃï¼æéåæ°ååç½®åæ°çæ°éæ¯3à à à + =ã
2ãåå¦ä½ ç¨å ¨è¿æ¥å±å¤çä¸å¼ Ãç彩è²ï¼RGBï¼å¾åï¼å·ç§¯æ ¸çé«å®½æ¯3Ã3ï¼è¾åºå å«ä¸ªééï¼å¨ä½¿ç¨åç½®çæ åµä¸ï¼è¿ä¸ªå·ç§¯å±å ±æå¤å°ä¸ªåæ°ï¼
çï¼è¾å ¥ééæ°æ¯3ï¼è¾åºééæ°æ¯ï¼æ以åæ°æ°éæ¯Ã3Ã3Ã3+=ã
3ãconv2d = nn.Conv2d(in_channels=3, out_channels=4, kernel_size=3, padding=2)ï¼è¾å ¥ä¸å¼ å½¢ç¶ä¸º3ÃÃçå¾åï¼è¾åºçå½¢ç¶ä¸ºï¼
çï¼è¾åºééæ°æ¯4ï¼ä¸ä¸ä¸¤ä¾§æ»å ±å¡«å 4è¡ï¼å·ç§¯æ ¸é«åº¦æ¯3ï¼æ以è¾åºçé«åº¦æ¯ - 3 + 1=−3+1=ï¼å®½åº¦åçå¯å¾ã
4ãå ³äºå·ç§¯å±ï¼ä»¥ä¸åªç§è¯´æ³æ¯é误çï¼
A.1Ã1å·ç§¯å¯ä»¥çä½æ¯ééç»´ä¸çå ¨è¿æ¥
B.æ个äºç»´å·ç§¯å±ç¨äºå¤çå½¢ç¶ä¸º3ÃÃçè¾å ¥ï¼å该å·ç§¯å±æ æ³å¤çå½¢ç¶ä¸º3ÃÃçè¾å ¥
C.å·ç§¯å±éè¿å¡«å ãæ¥å¹ ãè¾å ¥ééæ°ãè¾åºééæ°çè°èè¾åºçå½¢ç¶
D .两个è¿ç»ç3Ã3å·ç§¯æ ¸çæåéä¸ä¸ä¸ª5Ã5å·ç§¯æ ¸çæåéç¸å
çï¼éBï¼å¯¹äºé«å®½ç»´åº¦ï¼åªè¦è¾å ¥çé«å®½ï¼å¡«å åçï¼å¤§äºæçäºå·ç§¯æ ¸çé«å®½å³å¯è¿è¡è®¡ç®ã
the first layer is a 3 Ã 3 convolution, the second is a fully connected layer on top of the 3 Ã 3 output grid of the first layer (see Figure 1). Sliding this small network over the input activation grid boils down to replacing the 5 Ã 5 convolution with two layers of 3 Ã 3 convolution.
æ们å设å¾çæ¯5*5ç
æ们使ç¨5*5çå·ç§¯æ ¸å¯¹å ¶å·ç§¯ï¼æ¥é¿ä¸º1ï¼å¾å°çç»ææ¯:(5-5)/1+1=1
ç¶åæ们使ç¨2个å·ç§¯æ ¸ä¸º3*3çï¼è¿éç两个æ¯æ2å±ï¼
第ä¸å±3*3ï¼
å¾å°çç»ææ¯(5-3)/1+1=3
第äºå±3*3ï¼
å¾å°çç»ææ¯(3-3)/1+1=1
æ以æ们çæç»å¾å°ç»ææåé大å°åç¨5*5çå·ç§¯æ ¸å¾å°çç»æ大å°æ¯ä¸æ ·çï¼ï¼ï¼
5ãå ³äºæ± åå±ï¼ä»¥ä¸åªç§è¯´æ³æ¯é误çï¼
A.æ± åå±ä¸åä¸ååä¼ æ
B.æ± åå±æ²¡æ模ååæ°
C.æ± åå±é常ä¼åå°ç¹å¾å¾çé«å宽
D.æ± åå±çè¾å ¥åè¾åºå ·æç¸åçééæ°
çï¼A
é项1ï¼é误ï¼æ± åå±æåä¸æ¨¡åçæ£å计ç®ï¼åæ ·ä¹ä¼åä¸ååä¼ æ
é项2ï¼æ£ç¡®ï¼æ± åå±ç´æ¥å¯¹çªå£å çå ç´ æ±æ大å¼æå¹³åå¼ï¼å¹¶æ²¡æ模ååæ°åä¸è®¡ç®
é项3ï¼æ£ç¡®
é项4ï¼æ£ç¡®
åèæç®ï¼
/
/question//answer/
/s/1PBrX...,并使用提取码:2s进行下载。在学习过程中,数值微分法虽然简便易行,但计算成本高昂,尤其在处理大量参数时。反向传播则提供了一种更为高效的方法来计算梯度,尽管实现反向传播算法时可能会遇到错误,但通过梯度检验(gradient checking)方法,可以验证反向传播的实现是否正确。