repos
/ ai-art master

ai-art

mirror archived upstream

Art generation with VQGAN + CLIP in Docker, with a simple web UI for anyone with a GPU. A simplified and expanded take on Kevin Costa's work.

aiai-artclipdockerdocker-composegpuhandcodedimagenetpythonpytorchtorchtorchvisionvqganvqgan-clip

2.4 KB · 76 lines · Python Raw History
 1import torch
 2import torch.nn as nn
 3import torch.nn.functional as F
 4
 5from torchvision.models import VGG
 6try:
 7    from torch.hub import load_state_dict_from_url
 8except ImportError:
 9    from torch.utils.model_zoo import load_url as load_state_dict_from_url
10
11from typing import List, Union, cast
12
13
14def adopt_weight(weight, global_step, threshold=0, value=0.):
15    if global_step < threshold:
16        weight = value
17    return weight
18
19
20def hinge_d_loss(logits_real, logits_fake):
21    loss_real = torch.mean(F.relu(1. - logits_real))
22    loss_fake = torch.mean(F.relu(1. + logits_fake))
23    d_loss = 0.5 * (loss_real + loss_fake)
24    return d_loss
25
26
27def vanilla_d_loss(logits_real, logits_fake):
28    d_loss = 0.5 * (
29        torch.mean(torch.nn.functional.softplus(-logits_real)) +
30        torch.mean(torch.nn.functional.softplus(logits_fake)))
31    return d_loss
32
33
34def normalize_tensor(x, eps=1e-10):
35    norm_factor = torch.sqrt(torch.sum(x**2, dim=1, keepdim=True))
36    return x / (norm_factor + eps)
37
38
39def spatial_average(x, keepdim=True):
40    return x.mean([2, 3], keepdim=keepdim)
41
42
43def make_layers(cfg: List[Union[str, int]], batch_norm: bool = False) -> nn.Sequential:
44    layers: List[nn.Module] = []
45    in_channels = 3
46    for v in cfg:
47        if v == 'M':
48            layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
49        else:
50            v = cast(int, v)
51            conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=1)
52            if batch_norm:
53                layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]
54            else:
55                layers += [conv2d, nn.ReLU(inplace=True)]
56            in_channels = v
57    return nn.Sequential(*layers)
58
59
60def load_vgg(model_dir: str, pretrained: bool = False, **kwargs):
61    if pretrained:
62        kwargs['init_weights'] = False
63
64    cfg = [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M']
65    model = VGG(make_layers(cfg, batch_norm=False), **kwargs)
66
67    if pretrained:
68        state_dict = load_state_dict_from_url('https://download.pytorch.org/models/vgg16-397923af.pth',
69                                              model_dir=model_dir,
70                                              file_name="vgg16-397923af.pth",
71                                              progress=True)
72        model.load_state_dict(state_dict)
73        print(f"Loaded pretrained VGG16 model from '{model_dir}/vgg16-397923af.pth'")
74
75    return model