georgescutelnicu commited on
Commit
f6ca457
1 Parent(s): 2e8d54d

Upload 11 files

Browse files
app.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from model import create_vgg_model
3
+ from data_setup import preprocess, deprocess, get_features, gram_matrix
4
+ from loss_functions import content_loss, style_loss, total_loss
5
+ from torch import optim
6
+ from pathlib import Path
7
+ import numpy as np
8
+ import gradio as gr
9
+ from PIL import Image
10
+
11
+
12
+ def predict(content_image, style_image):
13
+
14
+ # Create model
15
+ model = create_vgg_model()
16
+
17
+ # Transform images
18
+ content_img = preprocess(content_image)
19
+ style_img = preprocess(style_image)
20
+ target_img = content_img.clone().requires_grad_(True)
21
+
22
+ content_features = get_features(content_img, model)
23
+ style_features = get_features(style_img, model)
24
+
25
+ style_gram = {layer: gram_matrix(style_features[layer]) for layer in style_features}
26
+
27
+ # Inference
28
+ optimizer = optim.Adam([target_img], lr=0.06)
29
+
30
+ alpha_param = 1
31
+ beta_param = 1e2
32
+ epochs = 60
33
+
34
+ for i in range(epochs):
35
+ target_features = get_features(target_img, model)
36
+
37
+ c_loss = content_loss(target_features['layer_4'], content_features['layer_4'])
38
+ s_loss = style_loss(target_features, style_gram)
39
+ t_loss = total_loss(c_loss, s_loss, alpha_param, beta_param)
40
+
41
+ optimizer.zero_grad()
42
+ t_loss.backward()
43
+ optimizer.step()
44
+
45
+ results = deprocess(target_img)
46
+
47
+ return Image.fromarray((results * 255).astype(np.uint8))
48
+
49
+ # Gradio Interface
50
+
51
+ example_list = [['content/content1.jpg',
52
+ 'style/style1.jpg'],
53
+ ['content/content2.jpg',
54
+ 'style/style2.jpg'],
55
+ ['content/content3.jpg',
56
+ 'style/style3.jpg']]
57
+
58
+ title = "Neural Style Transfer 🎨"
59
+ description = "It will take about 1 minute for the result to be displayed. Since the algorithm runs a small number of epochs (to reduce the waiting time), the result will not always be as good as it should be."
60
+
61
+ demo = gr.Interface(fn=predict,
62
+ inputs=['image', 'image'],
63
+ outputs=gr.Image().style(width=256, height=256),
64
+ examples=example_list,
65
+ title=title,
66
+ description=description)
67
+
68
+
69
+ demo.launch(debug=False,
70
+ share=False)
content/content1.jpg ADDED
content/content2.jpg ADDED
content/content3.jpg ADDED
data_setup.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import torch
3
+ from torchvision import transforms
4
+ from PIL import Image
5
+ import numpy as np
6
+
7
+ def preprocess(img):
8
+
9
+ image = Image.fromarray(img).convert('RGB')
10
+ imsize = 196
11
+
12
+ transform = transforms.Compose([
13
+ transforms.Resize((imsize, imsize)),
14
+ transforms.ToTensor(),
15
+ transforms.Normalize(mean=[0.485, 0.456, 0.406],
16
+ std=[0.229, 0.224, 0.225])
17
+ ])
18
+
19
+ image = transform(image)
20
+ image = image.unsqueeze(dim=0)
21
+
22
+ return image
23
+
24
+
25
+ def deprocess(image): # def show_image
26
+
27
+ image = image.clone()
28
+ image = image.squeeze(0)
29
+ image = image.permute(1,2,0)
30
+ image = image.detach().numpy()
31
+ image = image * np.array([0.229, 0.224, 0.225]) + np.array([0.485, 0.456, 0.406])
32
+ image = image.clip(0,1)
33
+
34
+ return image
35
+
36
+ def get_features(image, model):
37
+
38
+ features = {}
39
+ layers = {
40
+ '0': 'layer_1',
41
+ '5': 'layer_2',
42
+ '10': 'layer_3',
43
+ '19': 'layer_4',
44
+ '28': 'layer_5'
45
+ }
46
+ x = image
47
+
48
+ for name, layer in model._modules.items():
49
+ x = layer(x)
50
+ if name in layers:
51
+ features[layers[name]] = x
52
+
53
+ return features
54
+
55
+
56
+ def gram_matrix(image):
57
+
58
+ b, c, h, w = image.size()
59
+ image = image.view(c, h*w)
60
+ gram = torch.mm(image, image.t())
61
+ return gram
loss_functions.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import torch
3
+ from data_setup import gram_matrix
4
+
5
+ def content_loss(target, content):
6
+
7
+ loss = torch.mean((target - content) ** 2)
8
+
9
+ return loss
10
+
11
+
12
+ def style_loss(target_features, style_grams):
13
+
14
+ loss = 0
15
+
16
+ for layer in target_features:
17
+ target_f = target_features[layer]
18
+ target_gram = gram_matrix(target_f)
19
+ style_gram = style_grams[layer]
20
+ b,c,h,w = target_f.shape
21
+ layer_loss = 0.2 * torch.mean((target_gram - style_gram) ** 2)
22
+ loss += layer_loss/(c*h*w)
23
+
24
+ return loss
25
+
26
+
27
+ def total_loss(content_loss, style_loss, alpha, beta):
28
+
29
+ loss = alpha * content_loss + beta * style_loss
30
+
31
+ return loss
model.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import torchvision
3
+
4
+ def create_vgg_model():
5
+
6
+ # Create model
7
+ model_weights = torchvision.models.VGG19_Weights.DEFAULT
8
+ model = torchvision.models.vgg19(weights=model_weights)
9
+
10
+
11
+ # Freeze layers
12
+ for param in model.parameters():
13
+ param.requires_grad = False
14
+
15
+ # Kepp only the features of the model
16
+ model = model.features
17
+
18
+ return model
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ torch==1.12.0
2
+ torchvision==0.13.0gradio==3.1.4
style/style1.jpg ADDED
style/style2.jpg ADDED
style/style3.jpg ADDED