同一个网络模块的多层叠加是深度学习中常用的操作,如果使用nn.Sequential将这些模块叠加到一起就会显得很呆:
self.block=nn.Sequential(capsule_net(),capsule_net(),capsule_net(),capsule_net(),capsule_net(),capsule_net(), )
对于这种方法,如果需要调整模块叠加的数量也很不方便。可以使用setattr()和getattr()实现相同的效果:
# 定义时
for i in range(layer_num):setattr(self, "capsule_layer" + str(i + 1), capsule_net().cuda())
self.capsule_layers = [getattr(self, "capsule_layer" + str(i + 1)) for i in range(layer_num)]
# 使用时
for capsule_layer in self.capsule_layers:result =capsule_layer(input)
官方文档地址:setattr(),getattr()
setattr(object, name, value)
此函数与 getattr() 两相对应。 其参数为一个对象、一个字符串和一个任意值。 字符串指定一个现有属性或者新增属性。 函数会将值赋给该属性,只要对象允许这种操作。 例如,setattr(x, ‘foobar’, 123) 等价于 x.foobar = 123。
getattr(object, name,[default])
返回对象命名属性的值。name 必须是字符串。如果该字符串是对象的属性之一,则返回该属性的值。例如, getattr(x, ‘foobar’) 等同于 x.foobar。如果指定的属性不存在,且提供了 default 值,则返回它,否则触发 AttributeError。
现在我们再看看上面用setattr()和getattr()实现的多层堆叠网络:
for i in range(layer_num):setattr(self, "capsule_layer" + str(i + 1), capsule_net().cuda())
self即我们构建的模型对象,我们创建num个layer新增到self里,这个网络堆叠层的命名为"capsule_layer" + str(i + 1)。
self.capsule_layers = [getattr(self, "capsule_layer" + str(i + 1)) for i in range(layer_num)]
这个方法可以将我们上面创建的网络堆叠层整理到一个self.capsule_layers里。