PyTorch使用nn.Sequential报错list非Module子类及*号用法疑问
nn.Sequential的构造方法设计为接收多个独立的nn.Module子类实例作为位置参数,或者接收一个有序字典(OrderedDict)来初始化层。
你第一次写的nn.Sequential(list(model.children())[:7])是直接把一个列表对象传给了Sequential,列表本身不属于nn.Module的子类,不符合参数要求,自然会触发TypeError: list is not a Module subclass的报错。
这里的*是Python的可变位置参数解包语法,作用是把列表里的每个元素逐个拆出来,作为独立的位置参数传给Sequential,等价于你手动把列表里的7个层挨个写在Sequential的括号里,自然就能正常运行。
另外提醒一个小细节:你写的正确示例里model.children漏了括号,正确写法应该是nn.Sequential(*list(model.children())[:7]),children()是模型的方法,需要调用才能返回子模块迭代器。
这是Python语法对星号表达式的硬性限制:*解包表达式不能单独出现在赋值语句的右侧。
当你写layer = *list(model_ft.children())[:3]时,Python不知道要把解包后的多个元素包装成什么类型(列表/元组/其他)赋值给单个变量layer,所以直接抛出语法错误。
如果确实想用解包的方式生成列表,可以把解包表达式放在列表字面量里:
layer = [*list(model_ft.children())[:3]]
这种写法和你直接用layer = list(model.children())[:7]的效果完全一致,后者是更常规的写法,不需要额外解包。
星号表达式在赋值场景下通常用在多变量拆包的场景,比如:
# 把第一个元素给first,最后一个给last,中间所有元素打包成列表给middle first, *middle, last = list(model.children())
内容的提问来源于stack exchange,提问作者qicheng wang

