Python3中*resnet_block()语法的作用:结合PyTorch ResNet代码疑问
*resnet_block() 写法的语法含义与执行效果 这个写法没有PyTorch专属的特殊设计,本质是Python3通用的*可迭代对象解包操作,作用是把可迭代对象的元素拆成独立的位置参数,传入后续的构造器。
逐环节拆解执行逻辑
- 先明确
resnet_block的返回值类型:函数内部用普通Python列表blk存储按规则生成的所有Residual残差块实例,最终把这个列表整体return出去——也就是说调用这个函数拿到的不是PyTorch可直接参与前向传播的网络模块,而是一个装着多个模块实例的普通列表。 - 如果不加
*直接把返回值传给nn.Sequential:相当于给Sequential传了1个参数(那个装着层的列表),不符合Sequential“接收任意个nn.Module实例作为位置参数”的入参要求,会直接触发类型错误。 - 加上
*之后的实际效果:把列表里的每个残差块实例拆成独立的入参,依次传给nn.Sequential的构造逻辑。以示例里的b2为例,函数返回的是包含2个残差块的列表[res_layer1, res_layer2],加*后的传参和直接手写的构造代码完全等价:
最终构造完成的b2 = nn.Sequential(res_layer1, res_layer2)b2,是一个按列表内元素顺序堆叠了两层残差结构的Sequential网络模块,层的顺序、参数配置和手动逐个定义的网络没有任何区别。
这种写法的设计初衷
D2L教材里采用这种写法,是为了简化动态残差块的构造流程:当需要按照不同的残差块数量生成对应模块时,不用手动循环把每个层append到Sequential实例里,只要按规则把所有层存在列表中,一次解包就能完成Sequential的构造,代码更简洁易读。
补充:这种解包用法是Python通用语法,并非PyTorch专属,只要是支持可变位置参数的函数/类构造器,都可以用这种方式传入可迭代对象里的元素。
内容的提问来源于stack exchange,提问作者Arun
相关产品推荐
相关产品推荐

