class Generator(nn.Module):
def init(
self,
size,
style_dim,
n_mlp,
channel_multiplier=2,
blur_kernel=[1, 3, 3, 1],
lr_mlp=0.01,
):
super().init()

self.size = size

self.style_dim = style_dim

layers = [PixelNorm()]

for i in range(n_mlp):
layers.append(
EqualLinear(
style_dim, style_dim, lr_mul=lr_mlp, activation=‘fused_lrelu’
)
)

self.style = nn.Sequential(*layers)

self.channels = {
4: 512,
8: 512,
16: 512,
32: 512,
64: 256 * channel_multiplier,
128: 128 * channel_multiplier,
256: 64 * channel_multiplier,
512: 32 * channel_multiplier,
1024: 16 * channel_multiplier,
}

self.input = ConstantInput(self.channels[4])
self.conv1 = StyledConv(
self.channels[4], self.channels[4], 3, style_dim, blur_kernel=blur_kernel
)
self.to_rgb1 = ToRGB(self.channels[4], style_dim, upsample=False)

self.log_size = int(math.log(size, 2))
self.num_layers = (self.log_size - 2) * 2 + 1

self.convs = nn.ModuleList()
self.upsamples = nn.ModuleList()
self.to_rgbs = nn.ModuleList()
self.noises = nn.Module()

in_channel = self.channels[4]

for layer_idx in range(self.num_layers):
res = (layer_idx + 5) // 2
shape = [1, 1, 2 ** res, 2 ** res]
self.noises.register_buffer(f’noise_{layer_idx}‘, torch.randn(*shape))

for i in range(3, self.log_size + 1):
out_channel = self.channels[2 ** i]

self.convs.append(
StyledConv(
in_channel,
out_channel,
3,
style_dim,
upsample=True,
blur_kernel=blur_kernel,
)
)

self.convs.append(
StyledConv(
out_channel, out_channel, 3, style_dim, blur_kernel=blur_kernel
)
)

self.to_rgbs.append(ToRGB(out_channel, style_dim))

in_channel = out_channel

self.n_latent = self.log_size * 2 - 2

def make_noise(self):
device = self.input.input.device

noises = [torch.randn(1, 1, 2 ** 2, 2 ** 2, device=device)]

for i in range(3, self.log_size + 1):
for _ in range(2):
noises.append(torch.randn(1, 1, 2 ** i, 2 ** i, device=device))

return noises

def mean_latent(self, n_latent):
latent_in = torch.randn(
n_latent, self.style_dim, device=self.input.input.device
)
latent = self.style(latent_in).mean(0, keepdim=True)

return latent

def get_latent(self, input):
return self.style(input)

def forward(
self,
styles,
return_latents=False,
return_features=False,
inject_index=None,
truncation=1,
truncation_latent=None,
input_is_latent=False,
noise=None,
randomize_noise=True,
):
if not input_is_latent:
styles = [self.style(s) for s in styles]

if noise is None:
if randomize_noise:
noise = [None] * self.num_layers
else:
noise = [
getattr(self.noises, f’noise_{i}’) for i in range(self.num_layers)
]

if truncation < 1:
style_t = []

for style in styles:
style_t.append(
truncation_latent + truncation * (style - truncation_latent)
)

styles = style_t

if len(styles) < 2:
inject_index = self.n_latent

if styles[0].ndim < 3:
latent = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
else:
latent = styles[0]

else:
if inject_index is None:
inject_index = random.randint(1, self.n_latent - 1)

latent = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
latent2 = styles[1].unsqueeze(1).repeat(1, self.n_latent - inject_index, 1)

latent = torch.cat([latent, latent2], 1)

out = self.input(latent)
out = self.conv1(out, latent[:, 0], noise=noise[0])

skip = self.to_rgb1(out, latent[:, 1])

i = 1
for conv1, conv2, noise1, noise2, to_rgb in zip(
self.convs[::2], self.convs[1::2], noise[1::2], noise[2::2], self.to_rgbs
):
out = conv1(out, latent[:, i], noise=noise1)
out = conv2(out, latent[:, i + 1], noise=noise2)
skip = to_rgb(out, latent[:, i + 2], skip)

i += 2

image = skip

if return_latents:
return image, latent
elif return_features:
return image, out
else:
return image, None

class MyHairEncoderGradualStyleWPlus(Module):
def init(self, num_layers, mode=‘ir’, opts=None):
super(MyHairEncoderGradualStyleWPlus, self).init()
assert num_layers in [50, 100, 152], ‘num_layers should be 50,100, or 152’
assert mode in [‘ir’, ‘ir_se’], ‘mode should be ir or ir_se’
self.encoder_hair = BackboneEncoderUsingLastLayerIntoWPlus(num_layers, mode=mode, opts=opts)
self.encoder_face = BackboneEncoderUsingLastLayerIntoWPlus(num_layers, mode=mode, opts=opts)
self.opts = opts

out_features = 18 * 512
in_features = out_features * 2
self.flat = Flatten()
self.map = Sequential(
Linear(in_features=in_features, out_features=out_features),
nn.LeakyReLU(negative_slope=0.2,inplace=True),
)


def forward(self, face, hair):
e_face = self.encoder_face(face)
e_hair = self.encoder_hair(hair)

e_face_flat = self.flat(e_face)
e_hair_flat = self.flat(e_hair)

e = torch.cat((e_face_flat, e_hair_flat), dim=1)


x = self.map(e)
x = x.view(-1, 18, 512)
return x

def forward_im_vec(self, face_im, hair_vec):
e_face = self.encoder_face(face_im)
e_hair = hair_vec

e_face_flat = self.flat(e_face)
e_hair_flat = self.flat(e_hair)

e = torch.cat((e_face_flat, e_hair_flat), dim=1)


x = self.map(e)
x = x.view(-1, 18, 512)
return x

def forward_vec_im(self, face_vec, hair_im):
e_face = face_vec
e_hair = self.encoder_hair(hair_im)

e_face_flat = self.flat(e_face)
e_hair_flat = self.flat(e_hair)

e = torch.cat((e_face_flat, e_hair_flat), dim=1)


x = self.map(e)
x = x.view(-1, 18, 512)
return x

def forward_vec_vec(self, face_vec, hair_vec):
e_face = face_vec
e_hair = hair_vec

e_face_flat = self.flat(e_face)
e_hair_flat = self.flat(e_hair)

e = torch.cat((e_face_flat, e_hair_flat), dim=1)


x = self.map(e)
x = x.view(-1, 18, 512)
return x

def get_embedding(self, input_im, is_face):
if is_face:
e_out = self.encoder_face(input_im)
else:
e_out = self.encoder_hair(input_im)
return e_out
def init(self, opts):
super(MypSp, self).init()
self.set_opts(opts)
self.encoder = psp_enc.MyHairEncoderGradualStyleWPlus(50, ‘ir_se’, self.opts)
self.decoder = Generator(1024, 512, 8).to(self.opts.device)
self.face_pool = torch.nn.AdaptiveAvgPool2d((256, 256))
self.load_weights()

def load_weights(self):
print(‘Loading pSp from checkpoint: {}’.format(self.opts.checkpoint_path))
# ckpt = torch.load((self.opts.checkpoint_path), map_location=‘cpu’)
ckpt = torch.load((self.opts.checkpoint_path), map_location=‘cpu’, weights_only=True)
enc = get_keys(ckpt, ‘encoder’)
self.encoder.load_state_dict(enc, strict=True)
self.decoder.load_state_dict((get_keys(ckpt, ‘decoder’)), strict=True)
how,to,fune,tne,this,model
give,me,the,code,and,everything,needed,for,this,task
i,have,that,generator,and,MyHairEncoderGradualStyleWPlus,generate,me,the,complete,code
give,me,code,for,evaluation,and,testing
i,want,personalized,give,me,complete,code