(self, generator, z, residual_layers)
ResidualGenerator(generator, z, ['z', 'layer1', 'layer2'])
        Returns a model that computes generator(z), but which has
        additional internal parameters dz, d1, d2, etc, that
        adjust the computation so that the output of layerN is
        adjusted by dN, for example, if a network normally computes

        x = layer4(layer3(layer2(layer1(z)))), then specifying

        the innermost three layers will cause this to compute:

        x = layer4(d3 + layer3(d2 + layer2(d1 + layer1(dz + z))))
ResidualGenerator(generator, z, ['z', 'layer1', 'layer2'])
        Returns a model that computes generator(z), but which has
        additional internal parameters dz, d1, d2, etc, that
        adjust the computation so that the output of layerN is
        adjusted by dN, for example, if a network normally computes
ResidualGenerator ( generator z [ z layer1 layer2 ] ) Returns a model that computes generator ( z ) but which has additional internal parameters dz d1 d2 etc that adjust the computation so that the output of layerN is adjusted by dN for example if a network normally computes
def __init__(self, generator, z, residual_layers):
        '''
        ResidualGenerator(generator, z, ['z', 'layer1', 'layer2'])
        Returns a model that computes generator(z), but which has
        additional internal parameters dz, d1, d2, etc, that
        adjust the computation so that the output of layerN is
        adjusted by dN, for example, if a network normally computes

        x = layer4(layer3(layer2(layer1(z)))), then specifying

        the innermost three layers will cause this to compute:

        x = layer4(d3 + layer3(d2 + layer2(d1 + layer1(dz + z))))
        '''
        # First temporarily hook the layers of the generator to
        # collect initial values (and output shapes) of each layer.
        with torch.no_grad(), nethook.InstrumentedModel(generator) as g:
            g.retain_layers([n for n in residual_layers if n != 'z'])
            init_out = g(z)
            init_layers = g.retained_features()
            init_layers['z'] = z
        # Then, permanently hook the layers of the generator to add
        # residual adjustments dz, d1, d2, etc at each layer.
        super().__init__(generator)
        for k, v in init_layers.items():
            # layer3.conv1 -> 3_conv1, shortened name.
            name = k.replace('layer', '', 1).replace('.', '_')
            # 3_conv1 -> self.init_3_conv1, buffer with unperturbed value
            self.register_buffer('init_%s' % name, v.clone())
            # Add parameter 'dz', etc for any variable listed in residuals
            if k in residual_layers:
                # 3_conv1 -> self.d3_conv1, parameter initialized to 0
                dname = 'd' + name
                setattr(self, dname, torch.nn.Parameter(torch.zeros_like(v)))
                # Change model to add self.d[name] after computing layer k.
                if k != 'z':
                    self.edit_layer(k, add_adjustment, attr=dname)
def __init__ ( self , generator , z , residual_layers ) : # First temporarily hook the layers of the generator to # collect initial values (and output shapes) of each layer. with torch . no_grad ( ) , nethook . InstrumentedModel ( generator ) as g : g . retain_layers ( [ n for n in residual_layers if n != 'z' ] ) init_out = g ( z ) init_layers = g . retained_features ( ) init_layers [ 'z' ] = z # Then, permanently hook the layers of the generator to add # residual adjustments dz, d1, d2, etc at each layer. super ( ) . __init__ ( generator ) for k , v in init_layers . items ( ) : # layer3.conv1 -> 3_conv1, shortened name. name = k . replace ( 'layer' , '' , 1 ) . replace ( '.' , '_' ) # 3_conv1 -> self.init_3_conv1, buffer with unperturbed value self . register_buffer ( 'init_%s' % name , v . clone ( ) ) # Add parameter 'dz', etc for any variable listed in residuals if k in residual_layers : # 3_conv1 -> self.d3_conv1, parameter initialized to 0 dname = 'd' + name setattr ( self , dname , torch . nn . Parameter ( torch . zeros_like ( v ) ) ) # Change model to add self.d[name] after computing layer k. if k != 'z' : self . edit_layer ( k , add_adjustment , attr = dname )