最新要闻
- 极品墨玉不透光
- 中国电池企业装机量排名:宁德时代、比亚迪太猛 吃下超7成市场
- “杜苏芮”台风登陆福建晋江:福建史上第二强台风 直插内陆地区
- 审美真在线!比亚迪B级纯电猎装SUV宋L谍照曝光:20万或卖爆
- 微信等多平台已把“帐号”改为“账号”:两字用法不同 极易混淆
- 第6号台风卡努生成 专家:台风登陆时最好别开空调
- 发现最美铁路:一路欢歌看草原
- 九黎城NPC神秘故事解读蚩尤手下美女可爱兽人风祖大神等你来揭秘
- 倍杰特07月27日获深股通增持17.69万股
- 麻辣鸡加盟《使命召唤》
- 理想L8为啥会加不进油?官方回应加油跳枪:高压油箱的锅 解锁就行了
- 伺候过女王的路虎 终于知道怎么在中国卖车了
- 特斯拉被曝有一秘密团队 专门压制续航不足相关投诉
- 999元起 荣耀平板X8 Pro开售:11.5寸120Hz 2K屏
- 中央气象台:“杜苏芮”登陆在即 福建浙江等地进入风雨影响最强时段
- 碧水源:融资净偿还145.2万元,融资余额9.2亿元(07-27)
手机
英国房地产因利率上升陷入困境 房价正以2011年来最快速度下跌
宁夏评选出上半年10名“宁夏好人” 95后消防员因敬业奉献入选
- 英国房地产因利率上升陷入困境 房价正以2011年来最快速度下跌
- 宁夏评选出上半年10名“宁夏好人” 95后消防员因敬业奉献入选
- 离婚时共同债务应该怎么处理?
- 华为云盘古大模型3.0正式发布
- 支持自动长文生成,WPS AI发布:基于大语言模型的智能办公助手
- 《街头霸王6》全球总销量突破200万份 卡普空再次为其玩家送上礼物
家电
MegEngine Python 层模块串讲(中)
在前面的文章中,我们简单介绍了在MegEngine imperative中的各模块以及它们的作用。对于新用户而言可能不太了解各个模块的使用方法,对于模块的结构和原理也是一头雾水。Python作为现在深度学习领域的主流编程语言,其相关的模块自然也是深度学习框架的重中之重。
模块串讲将对MegEngine的python层相关模块分别进行更加深入的介绍,会涉及到一些原理的解释和代码解读。Python层模块串讲共分为上、中、下三个部分,本文将介绍 Python层的functional、module和optimizer模块。理解并掌握这几个模块对于高效搭建神经网络非常重要。
Python 层计算接口 —— functional 模块
我们在定义网络结构时经常需要包含一些计算操作,这些计算操作就定义在functional中。
(资料图)
functional中实现了各类计算函数,包含对很多op的封装,供实现模型时调用。
functional中有些op完全是由Python代码实现,有些则需要调用C++接口完成计算(没错,这里的计算就需要MegDNN kernel)。对于后者,需要有机制确保我们的实现能够转发到底层正确执行,所以你在functional的许多op实现中会看到builtin和apply:
builtinbuiltin封装了所有的op,我们在functional中通过builtin.SomeOp(param)的方式获得一个算子SomeOp,param表示获取SomeOp需要的参数。apply通过
builtin获取到op后,需要调用apply接口来调用op的底层实现进行计算。apply是在Python层调用底层op的接口,apply的第一个参数是op(通过builtin获得),后面的参数是执行这个op需要的参数,都为Tensor。在imperative中op计算通过apply(op, inputs)的方式向下传递并最终调用到MegDNN中的kernel``。
Functional中的许多op都需要通过builtin和apply调用底层MegDNN的op来进行计算操作。然而在实际的计算发生前,很多时候需要在Python层做一些预处理。
来看下面这个例子:
def concat(inps: Iterable[Tensor], axis: int = 0, device=None) -> Tensor: ... if len(inps) == 1: return inps[0] if device is None: device = get_device(inps) device = as_device(device) (result,) = apply(builtin.Concat(axis=axis, comp_node=device.to_c()), *inps) return result这里concat方法先对输入tensor数量、device在python层做了一些预处理,然后才调用builtin和apply向下转发。
而对于diag这个op,无需预处理直接向下传递即可:
def diag(inp, k=0) -> Tensor: ... op = builtin.Diag(k=k) (result,) = apply(op, inp) return result对于实现了对应kernel的op,其在imperative层的实现通常非常的短。
上面concat和diag的apply调用会进入py_apply函数,并通过解析Python中的参数,将它们转换成C++中的对应类型,然后调用imperative::apply,进入dispatch层。
部分functional的op不直接调用py_apply而是有对应的cpp实现,比如squeeze:
def squeeze(inp: Tensor, axis: Optional[Union[int, Sequence[int]]] = None) -> Tensor: return squeeze_cpp(inp, axis)这样的实现往往是需要在调用py_apply之前做一些预处理,但使用python实现性能较差,所以我们将相关预处理以及py_apply的逻辑在C++层面实现。
本文主要介绍Python层的方法,关于C++部分的实现会在之后的文章进行更深入的介绍。
在这里我们只需要知道,functional中包装了所有关于Tensor计算相关的接口,是所有计算的入口,实际的计算操作通常会被转发到更底层的C++实现。
用户可以参考官方文档获取所有functional中的方法介绍。
模块结构的小型封装版本 —— module 模块
神经网络模型是由对输入数据执行操作的各种层(Layer),或者说模块(Module)组成。
Module用来定义网络模型结构,用户实现算法时要用组合模块Module (megengine/module)的方式搭建模型,定义神经网络时有些结构经常在模型中反复使用,将这样的结构封装为一个Module,既可以减少重复代码也降低了复杂模型编码的难度。
一个module类主要有两类函数:
__init__:构造函数,定义了模型各个层的大小。用户自定义的Module都源自基类class Module,所以在构造函数中一定要先调用super().__init__(),设置Module的一些基本属性。模型要使用的所有层 / 模块都需要在构造函数中声明。
class Module(metaclass=ABCMeta): r"""Base Module class. Args: name: module"s name, can be initialized by the ``kwargs`` parameter of child class. """ def __init__(self, name=None): self._modules = [] if name is not None: assert ( isinstance(name, str) and name.strip() ), "Module"s name must be a non-empty string" self.name = name # runtime attributes self.training = True self.quantize_disabled = False # hooks self._forward_pre_hooks = OrderedDict() self._forward_hooks = OrderedDict() # used for profiler and automatic naming self._name = None self._short_name = None # 抽象方法,由继承的 Module 自己实现 @abstractmethod def forward(self, inputs): pass # 其他方法 ...forward:定义模型结构,实现前向传播,也就是将数据输入模型到输出的过程。这里会调用Functional (megengine/functional)中的函数进行前向计算,forward表示的是模型实现的逻辑。来看一个例子:
class Simple(Module): def __init__(self): super().__init__() self.a = Parameter([1.23], dtype=np.float32) def forward(self, x): x = x * self.a return x__init__表明模型中有一个参数a,它的初值是固定的,forward中实现了具体的计算逻辑,也就是对传入的参数与a进行乘法运算。
对于一些更复杂的计算操作(如卷积、池化等)就需要借助functional中提供的方法来完成。
除了__init__和forward,基类class Module提供了很多属性和方法,常用的有:
def buffers(self, recursive: bool = True, **kwargs) -> Iterable[Tensor]:返回一个可迭代对象,遍历当前模块的所有buffers;def parameters(self, recursive: bool = True, **kwargs) -> Iterable[Parameter]:返回一个可迭代对象,遍历当前模块所有的parameters;def tensors(self, recursive: bool = True, **kwargs) -> Iterable[Parameter]:返回一个此module的Tensor的可迭代对象;def children(self, **kwargs) -> "Iterable[Module]":返回一个可迭代对象,该对象包括属于当前模块的直接属性的子模块;def named_buffers(self, prefix: Optional[str] = None, recursive: bool = True, **kwargs) -> Iterable[Tuple[str, Tensor]]:返回当前模块中key与buffer的键值对的可迭代对象,这里key是从该模块至buffer的点路径(dotted path);def named_parameters(self, prefix: Optional[str] = None, recursive: bool = True, **kwargs) -> Iterable[Tuple[str, Parameter]]:返回当前模块中key与parameter的键值对的可迭代对象,这里key是从该模块至buffer的点路径(dotted path);def named_tensors(self, prefix: Optional[str] = None, recursive: bool = True, **kwargs) -> Iterable[Tuple[str, Tensor]]:返回当前模块中key与Tensor(buffer + parameter) 的键值对的可迭代对象,这里key是从该模块至Tensor的点路径(dotted path);def named_modules(self, prefix: Optional[str] = None, **kwargs) -> "Iterable[Tuple[str, Module]]":返回一个可迭代对象,该对象包括当前模块自身在内的其内部所有模块组成的key-module键-模块对,这里key是从该模块至各子模块的点路径(dotted path);def named_children(self, **kwargs) -> "Iterable[Tuple[str, Module]]":返回一个可迭代对象,该对象包括当前模块的所有子模块(submodule)与键(key)组成的key-submodule对,这里key是子模块对应的属性名;def state_dict(self, rst=None, prefix="", keep_var=False):返回模块的状态字典,状态字典是一个保存当前模块所有可学习的Tensor(buffer + parameter)的字典。出于兼容性考虑,字典中的value的数据结构类型为numpy.ndarray(而不是Tensor),并且不可修改,是只读的;def load_state_dict(self, state_dict: Union[dict, Callable[[str, Tensor], Optional[np.ndarray]]], strict=True, ):加载一个模块的状态字典,这个方法常用于模型训练过程的保存与加载。
值得一提的是,Parameters和Buffer都是与Module相关的Tensor,它们的区别可以理解为:
Parameter是模型的参数,在训练过程中会通过反向传播进行更新,因此值是可能改变的,常见的有weight、bias等;Buffer是模型用到的统计量,不会在反向传播过程中更新,常见的有mean、var等。
在MegEngine的module目录下可以看到已经有很多常见的module实现,用户实现自己的模型可以根据需要复用其中的模块。
使用 optimizer 模块优化模型参数
MegEngine中的optimizer模块实现了基于各种常见优化策略的优化器,为用户提供了包括SGD、ADAM在内的常见优化器实现。这些优化器能够基于参数的梯度信息,按照算法所定义的策略执行更新。
大部分情况下用户不会自己实现优化器,这里以SGD优化器为例,优化神经网络模型参数的基本流程如下:
from megengine.autodiff import GradManagerimport megengine.optimizer as optimmodel = MyModel()gm = GradManager().attach(model.parameters())optimizer = optim.SGD(model.parameters(), lr=0.01) # lr may vary with different modelfor data, label in dataset: with gm: pred = model(data) loss = loss_fn(pred, label) gm.backward() optimizer.step().clear_grad()这里我们构造了一个优化器
optimizer,传入参数是model需要被优化的Parameter,和learning rate;优化器通过执行
step()方法进行一次优化;优化器通过执行
clear_grad()方法清空参数梯度。为何要手动清空梯度?
梯度管理器执行
backward()方法时, 会将当前计算所得到的梯度以累加的形式积累到原有梯度上,而不是直接做替换。 因此对于新一轮的梯度计算,通常需要将上一轮计算得到的梯度信息清空。 何时进行梯度清空是由人为控制的,这样可允许灵活进行梯度的累积。
用户也可以继承class Optimizer,实现自己的优化器。
以上就是关于functional,Module,optimizer的模块的基本介绍,这几个模块是我们搭建模型训练的最核心的部分,熟悉这部分后,我们就可以高效搭建神经网络了。
附
更多 MegEngine 信息获取,您可以:查看文档和 GitHub 项目,或加入 MegEngine 用户交流 QQ 群:1029741705。欢迎参与 MegEngine 社区贡献,成为 Awesome MegEngineer,荣誉证书、定制礼品享不停。
关键词:
-
-
-
-
MegEngine Python 层模块串讲(中)
直播平台源码开发提高直播质量的关键:视频编码和解码技术
数字化时代的农业新篇章
极品墨玉不透光
中国电池企业装机量排名:宁德时代、比亚迪太猛 吃下超7成市场
“杜苏芮”台风登陆福建晋江:福建史上第二强台风 直插内陆地区
审美真在线!比亚迪B级纯电猎装SUV宋L谍照曝光:20万或卖爆
微信等多平台已把“帐号”改为“账号”:两字用法不同 极易混淆
第6号台风卡努生成 专家:台风登陆时最好别开空调
发现最美铁路:一路欢歌看草原
九黎城NPC神秘故事解读蚩尤手下美女可爱兽人风祖大神等你来揭秘
全国首部涉融资租赁行业的地方法规出炉
倍杰特07月27日获深股通增持17.69万股
麻辣鸡加盟《使命召唤》
理想L8为啥会加不进油?官方回应加油跳枪:高压油箱的锅 解锁就行了
伺候过女王的路虎 终于知道怎么在中国卖车了
特斯拉被曝有一秘密团队 专门压制续航不足相关投诉
999元起 荣耀平板X8 Pro开售:11.5寸120Hz 2K屏
中央气象台:“杜苏芮”登陆在即 福建浙江等地进入风雨影响最强时段
对重点领域和薄弱环节支持力度持续加大——金融监管总局详解上半年金融支持实体经济成效
碧水源:融资净偿还145.2万元,融资余额9.2亿元(07-27)
13岁女孩体内抽出2000毫升乳白色血:平时暴饮暴食 爱吃零食
iPhone 15的最强敌手!华为Mate 60标准版渲染图出炉
千万粉大V留几手:BBA车主换理想等杂牌新能源 品味还是LOW
微信帐号改为账号:一个手机可以有两个账号了
《封神》导演自曝电影失败需用10年还债:目前最新票房已经突破7亿
协鑫能科07月27日被深股通减持18.64万股
中国新能源汽车平均电量出炉:商用车磷酸铁锂电芯将三元锂屠戮殆尽
理想L8表显车速大于实际车速 表显50km/h实际仅43km/h?官方回应
美国油价飙升欲进 “4元时代” 车主吐槽不敢开车:为何不买对电动车?
真有人用腾势N8玩游戏:方向盘就是手柄 体验碾压特斯拉
选读SQL经典实例笔记14_层次查询
冲击世界杯遭遇究极差签!国足如何冲出死亡之组?
你背的《静夜思》 李白没见过 竟敢篡改李白的诗?
家电使用秘籍:不花一分钱让老电器多活10年
Docker学习路线13:部署容器
看完这篇,SpringBoot再也不用写try/catch了
【防御“杜苏芮”】永春:农户抢收水稻
realme真我GT5来了:骁龙8 Gen2 下月登场
《封神第一部》申公豹“飞头术”太惊悚 夏雨揭秘幕后
妙鸭相机爆火!央视起底9.9元AI写真乱象:业内人士建议谨慎用
排放11.1亿吨二氧化碳!加拿大森林大火严重污染地球
SpaceX火箭在地球上空击穿了一个洞:干扰GPS
七月的天山写的哪个季节(七月的天山写作顺序)
孙军林(关于孙军林简述)
有惊无险!《英雄联盟》LPL季后赛JDG3:2战胜LNG:EDG拿“复活甲”
又一起?电动汽车自燃引发货轮大火 日产汽车或遭重创
五分钟了解Spark之RDD!!
南昌经开区:公益托管班让孩子们乐享缤纷夏日
恒大汽车:股票将于28日上午9时复牌
联想拯救者R9000X 2023配置出炉:锐龙7 7840H+RTX 4060
德国之后 法国部长也大赞中国汽车:希望能在法国生产
新组件制作中 中国制造商暗示新Switch24年初发布!
uni-app写微信小程序,data字段循环引用
营收首破10000亿!佳能Q2财报出炉:相机居然卖这么好
东方甄选直播间被关3天?官方火速澄清:账号正常营业 别误读
剑指比亚迪宋EV!全新哈弗枭龙EV谍照曝光
空调不能长时间吹 身体受不了!真的吗?
快递向服务生产延伸 “铁陆空”支撑让快递“快”到极致
丝丝关爱沁心脾!炎炎夏日,长征镇为养老机构老人送清凉
网传理想汽车起诉成都一家“理想画室” 理想官方回应
部分已支持5nm 国产EDA老大华大九天利润翻倍:“芯片之母”大卖
从121米高悬崖驾车坠落 iPhone 14成功救了他一命
一杯啤酒几百块 是智商税吗?
游戏、AI全都要 摩尔线程国产显卡解锁新技能:一键安装AI画图应用
新洲区人才安居购房补贴申请流程
税控盘锁死可以跨区解锁吗 金税盘锁死可以跨区解锁吗
智能制造:数字化未来,开启工业新纪元!
Shiro实战教程(整合SpringBoot,全网最强)
灵雀云Alauda MLOps 现已支持 Meta LLaMA 2 全系列模型
69岁单霁翔院长录综艺好拼,清理荷塘亲力亲为!
哈尔滨红旗大街道路更新改造东直路至先锋路段完工
永鼎股份:全资孙公司获得线束项目定点通知书
澳洲11岁女孩拥有百万资产打算12岁退休:已是一家玩具公司CEO
Win11更新“复活”老问题!部分应用将导致开始菜单失效
NVIDIA AI显卡炒作到50万元:国内想买还得看跟黄仁勋关系
大众巨资入股小鹏!小鹏汽车:我们提供平台和技术 大众做制造
曝光FSD撞路障被解雇后 前员工又搞事:特斯拉自动驾驶会闯红灯
白居易花非花歌曲创作背景(白居易的《花非花》的写作背景)
郑州市未来路执法中队深化建筑垃圾清理共创宜居环境
[数据结构笔记] 线性表
Python数据可视化-地图可视化
2023-7-27WPF的ContextMenu的传参绑定方式
中央财经大学绿金院支持中财绿指发布企业绿棕收入数据库
每日机构分析:7月27日
常州城建60亿元小公募审核“终止”,项目受理日期超1年
私募资管迎备案新规
cmo是什么职位(cio是什么职位)
女足世界杯彩经:山姆大婶再拔郁金香
韩国称发现世界首个室温超导体 Epic:要是真的 我送10款游戏
起猛了!日本Key社母公司Visual Art's卖身腾讯成子公司
终于坐不住了!奔驰V级正式曝光 竞争国产MPV市场
信阳市首家街头机采献血屋,启用!
东风集团股份(00489)7月27日斥资约934.17万港元回购253万股
开创电气(301448)7月27日主力资金净卖出319.06万元
万科与万达长春合作项目纠纷已基本达成和解 万达商管部分被冻结股权即将解冻
痛失网易30K之二:看你牛逼轰轰,请写一个阻塞队列
GPS北斗卫星时钟服务器(NTP时间服务器)助力标准化考场建设
资源成本降低70%!华为MetaERP资产核算的Serverless架构实践
人大金仓V8R6版本体验