Я предложу более общее решение, которое работает для любого уровня (и избегает других проблем, таких как изменение словаря при его циклическом просмотре или когда есть рекурсивные nn.modules
внутри друг друга).
def replace_bn(module, name):
'''
Recursively put desired batch norm in nn.module module.
set module = net to start code.
'''
# go through all attributes of module nn.module (e.g. network or layer) and put batch norms if present
for attr_str in dir(module):
target_attr = getattr(m, attr_str)
if type(target_attr) == torch.nn.BatchNorm2d:
print('replaced: ', name, attr_str)
new_bn = torch.nn.BatchNorm2d(target_attr.num_features, target_attr.eps, target_attr.momentum, target_attr.affine,
track_running_stats=False)
setattr(module, attr_str, new_bn)
# iterate through immediate child modules. Note, the recursion is done by our code no need to use named_modules()
for name, immediate_child_module in module.named_children():
replace_bn(immediate_child_module, name)
replace_bn(model, 'model')
суть в том, что вам нужно рекурсивно менять слои (в основном потому, что иногда вы можете встретить атрибуты, которые имеют сами модули). Я думаю, что лучший код, чем приведенный выше, заключался бы в добавлении еще одного оператора if (после нормы партии), определяющего, нужно ли вам рекурсировать и рекурсивно, если это так. Вышеупомянутое работает, но сначала меняет пакетную норму на внешнем слое (то есть в первом цикле), а затем с другим циклом, чтобы убедиться, что никакой другой объект, который должен быть повторен, не пропущен (а затем повторяется).
Исходное сообщение: https://discuss.pytorch.org/t/how-to-modify-a-pretrained-model/60509/10
кредиты: https://discuss.pytorch.org/t/replacing-convs-modules-with-custom-convs-then-notimplementederror/17736/3?u=brando_miranda
person
Charlie Parker
schedule
01.10.2020