Ved Gupta commited on
Commit
1c7b15f
·
1 Parent(s): 77b60c4

initially repo created

Browse files
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ model/ImageColorizationModel.pth
Pipfile.lock ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_meta": {
3
+ "hash": {
4
+ "sha256": "fedbd2ab7afd84cf16f128af0619749267b62277b4cb6989ef16d4bef6e4eef2"
5
+ },
6
+ "pipfile-spec": 6,
7
+ "requires": {
8
+ "python_version": "3.10"
9
+ },
10
+ "sources": [
11
+ {
12
+ "name": "pypi",
13
+ "url": "https://pypi.org/simple",
14
+ "verify_ssl": true
15
+ }
16
+ ]
17
+ },
18
+ "default": {},
19
+ "develop": {}
20
+ }
image-colorization-using-gan-main.ipynb CHANGED
The diff for this file is too large to render. See raw diff
 
main.py CHANGED
@@ -1,4 +1,5 @@
1
  import warnings
 
2
  warnings.filterwarnings("ignore")
3
 
4
  import os
@@ -28,15 +29,18 @@ model_path = "model/ImageColorizationModel.pth"
28
 
29
 
30
  model = None
31
- if not os.path.exists(model_path) :
32
  print("Model not find")
33
  download_from_drive()
34
  print("Model Downloaded")
35
  else:
36
- model = load_model(model_class=MainModel , file_path=model_path)
37
  print("Model Loaded")
38
 
 
39
  def predict_and_return_image(image):
 
 
40
  data = create_lab_tensors(image)
41
  model.net_G.eval()
42
  with torch.no_grad():
@@ -48,8 +52,7 @@ def predict_and_return_image(image):
48
  return fake_imgs[0]
49
 
50
 
51
-
52
-
53
 
54
  title = "Black&White to Color image"
55
  description = "Transforming Black & White Image in to colored image. Upload a black and white image to see it colorized by our deep learning model."
@@ -59,7 +62,5 @@ gr.Interface(
59
  title=title,
60
  description=description,
61
  inputs=[gr.Image(label="Gray Scale Image")],
62
- outputs=[
63
- gr.Image(label="Predicted Colored Image")
64
- ],
65
  ).launch(share=True, debug=True)
 
1
  import warnings
2
+
3
  warnings.filterwarnings("ignore")
4
 
5
  import os
 
29
 
30
 
31
  model = None
32
+ if not os.path.exists(model_path):
33
  print("Model not find")
34
  download_from_drive()
35
  print("Model Downloaded")
36
  else:
37
+ model = load_model_with_cpu(model_class=MainModel, file_path=model_path)
38
  print("Model Loaded")
39
 
40
+
41
  def predict_and_return_image(image):
42
+ if image is None:
43
+ return None
44
  data = create_lab_tensors(image)
45
  model.net_G.eval()
46
  with torch.no_grad():
 
52
  return fake_imgs[0]
53
 
54
 
55
+ import gradio as gr
 
56
 
57
  title = "Black&White to Color image"
58
  description = "Transforming Black & White Image in to colored image. Upload a black and white image to see it colorized by our deep learning model."
 
62
  title=title,
63
  description=description,
64
  inputs=[gr.Image(label="Gray Scale Image")],
65
+ outputs=[gr.Image(label="Predicted Colored Image")],
 
 
66
  ).launch(share=True, debug=True)
model/Discriminator.py CHANGED
@@ -16,22 +16,37 @@ from torch.utils.data import Dataset, DataLoader
16
 
17
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
18
 
 
19
  class PatchDiscriminator(nn.Module):
20
  def __init__(self, input_c, num_filters=64, n_down=3):
21
  super().__init__()
22
  model = [self.get_layers(input_c, num_filters, norm=False)]
23
- model += [self.get_layers(num_filters * 2 ** i, num_filters * 2 ** (i + 1), s=1 if i == (n_down-1) else 2)
24
- for i in range(n_down)] # the 'if' statement is taking care of not using
25
- # stride of 2 for the last block in this loop
26
- model += [self.get_layers(num_filters * 2 ** n_down, 1, s=1, norm=False, act=False)] # Make sure to not use normalization or
27
- # activation for the last layer of the model
28
- self.model = nn.Sequential(*model)
29
-
30
- def get_layers(self, ni, nf, k=4, s=2, p=1, norm=True, act=True): # when needing to make some repeatitive blocks of layers,
31
- layers = [nn.Conv2d(ni, nf, k, s, p, bias=not norm)] # it's always helpful to make a separate method for that purpose
32
- if norm: layers += [nn.BatchNorm2d(nf)]
33
- if act: layers += [nn.LeakyReLU(0.2, True)]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  return nn.Sequential(*layers)
35
-
36
  def forward(self, x):
37
- return self.model(x)
 
16
 
17
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
18
 
19
+
20
  class PatchDiscriminator(nn.Module):
21
  def __init__(self, input_c, num_filters=64, n_down=3):
22
  super().__init__()
23
  model = [self.get_layers(input_c, num_filters, norm=False)]
24
+ model += [
25
+ self.get_layers(
26
+ num_filters * 2**i,
27
+ num_filters * 2 ** (i + 1),
28
+ s=1 if i == (n_down - 1) else 2,
29
+ )
30
+ for i in range(n_down)
31
+ ] # the 'if' statement is taking care of not using
32
+ # stride of 2 for the last block in this loop
33
+ model += [
34
+ self.get_layers(num_filters * 2**n_down, 1, s=1, norm=False, act=False)
35
+ ] # Make sure to not use normalization or
36
+ # activation for the last layer of the model
37
+ self.model = nn.Sequential(*model)
38
+
39
+ def get_layers(
40
+ self, ni, nf, k=4, s=2, p=1, norm=True, act=True
41
+ ): # when needing to make some repeatitive blocks of layers,
42
+ layers = [
43
+ nn.Conv2d(ni, nf, k, s, p, bias=not norm)
44
+ ] # it's always helpful to make a separate method for that purpose
45
+ if norm:
46
+ layers += [nn.BatchNorm2d(nf)]
47
+ if act:
48
+ layers += [nn.LeakyReLU(0.2, True)]
49
  return nn.Sequential(*layers)
50
+
51
  def forward(self, x):
52
+ return self.model(x)
model/Generator.py CHANGED
@@ -16,40 +16,53 @@ from torch.utils.data import Dataset, DataLoader
16
 
17
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
18
 
 
19
  class UnetBlock(nn.Module):
20
- def __init__(self, nf, ni, submodule=None, input_c=None, dropout=False,
21
- innermost=False, outermost=False):
 
 
 
 
 
 
 
 
22
  super().__init__()
23
  self.outermost = outermost
24
- if input_c is None: input_c = nf
25
- downconv = nn.Conv2d(input_c, ni, kernel_size=4,
26
- stride=2, padding=1, bias=False)
 
 
27
  downrelu = nn.LeakyReLU(0.2, True)
28
  downnorm = nn.BatchNorm2d(ni)
29
  uprelu = nn.ReLU(True)
30
  upnorm = nn.BatchNorm2d(nf)
31
-
32
  if outermost:
33
- upconv = nn.ConvTranspose2d(ni * 2, nf, kernel_size=4,
34
- stride=2, padding=1)
35
  down = [downconv]
36
  up = [uprelu, upconv, nn.Tanh()]
37
  model = down + [submodule] + up
38
  elif innermost:
39
- upconv = nn.ConvTranspose2d(ni, nf, kernel_size=4,
40
- stride=2, padding=1, bias=False)
 
41
  down = [downrelu, downconv]
42
  up = [uprelu, upconv, upnorm]
43
  model = down + up
44
  else:
45
- upconv = nn.ConvTranspose2d(ni * 2, nf, kernel_size=4,
46
- stride=2, padding=1, bias=False)
 
47
  down = [downrelu, downconv, downnorm]
48
  up = [uprelu, upconv, upnorm]
49
- if dropout: up += [nn.Dropout(0.5)]
 
50
  model = down + [submodule] + up
51
  self.model = nn.Sequential(*model)
52
-
53
  def forward(self, x):
54
  if self.outermost:
55
  return self.model(x)
@@ -62,12 +75,16 @@ class Unet(nn.Module):
62
  super().__init__()
63
  unet_block = UnetBlock(num_filters * 8, num_filters * 8, innermost=True)
64
  for _ in range(n_down - 5):
65
- unet_block = UnetBlock(num_filters * 8, num_filters * 8, submodule=unet_block, dropout=True)
 
 
66
  out_filters = num_filters * 8
67
  for _ in range(3):
68
  unet_block = UnetBlock(out_filters // 2, out_filters, submodule=unet_block)
69
  out_filters //= 2
70
- self.model = UnetBlock(output_c, out_filters, input_c=input_c, submodule=unet_block, outermost=True)
71
-
 
 
72
  def forward(self, x):
73
- return self.model(x)
 
16
 
17
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
18
 
19
+
20
  class UnetBlock(nn.Module):
21
+ def __init__(
22
+ self,
23
+ nf,
24
+ ni,
25
+ submodule=None,
26
+ input_c=None,
27
+ dropout=False,
28
+ innermost=False,
29
+ outermost=False,
30
+ ):
31
  super().__init__()
32
  self.outermost = outermost
33
+ if input_c is None:
34
+ input_c = nf
35
+ downconv = nn.Conv2d(
36
+ input_c, ni, kernel_size=4, stride=2, padding=1, bias=False
37
+ )
38
  downrelu = nn.LeakyReLU(0.2, True)
39
  downnorm = nn.BatchNorm2d(ni)
40
  uprelu = nn.ReLU(True)
41
  upnorm = nn.BatchNorm2d(nf)
42
+
43
  if outermost:
44
+ upconv = nn.ConvTranspose2d(ni * 2, nf, kernel_size=4, stride=2, padding=1)
 
45
  down = [downconv]
46
  up = [uprelu, upconv, nn.Tanh()]
47
  model = down + [submodule] + up
48
  elif innermost:
49
+ upconv = nn.ConvTranspose2d(
50
+ ni, nf, kernel_size=4, stride=2, padding=1, bias=False
51
+ )
52
  down = [downrelu, downconv]
53
  up = [uprelu, upconv, upnorm]
54
  model = down + up
55
  else:
56
+ upconv = nn.ConvTranspose2d(
57
+ ni * 2, nf, kernel_size=4, stride=2, padding=1, bias=False
58
+ )
59
  down = [downrelu, downconv, downnorm]
60
  up = [uprelu, upconv, upnorm]
61
+ if dropout:
62
+ up += [nn.Dropout(0.5)]
63
  model = down + [submodule] + up
64
  self.model = nn.Sequential(*model)
65
+
66
  def forward(self, x):
67
  if self.outermost:
68
  return self.model(x)
 
75
  super().__init__()
76
  unet_block = UnetBlock(num_filters * 8, num_filters * 8, innermost=True)
77
  for _ in range(n_down - 5):
78
+ unet_block = UnetBlock(
79
+ num_filters * 8, num_filters * 8, submodule=unet_block, dropout=True
80
+ )
81
  out_filters = num_filters * 8
82
  for _ in range(3):
83
  unet_block = UnetBlock(out_filters // 2, out_filters, submodule=unet_block)
84
  out_filters //= 2
85
+ self.model = UnetBlock(
86
+ output_c, out_filters, input_c=input_c, submodule=unet_block, outermost=True
87
+ )
88
+
89
  def forward(self, x):
90
+ return self.model(x)
model/__init__.py CHANGED
@@ -14,46 +14,54 @@ from torchvision import transforms
14
  from torchvision.utils import make_grid
15
  from torch.utils.data import Dataset, DataLoader
16
 
17
- from .Generator import UnetBlock , Unet
18
  from .Discriminator import PatchDiscriminator
19
  from .weights import init_weights
 
20
 
21
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
22
 
 
23
  def init_model(model, device):
24
  model = model.to(device)
25
  model = init_weights(model)
26
  return model
27
 
 
28
  class MainModel(nn.Module):
29
- def __init__(self, net_G=None, lr_G=2e-4, lr_D=2e-4,
30
- beta1=0.5, beta2=0.999, lambda_L1=100.):
 
31
  super().__init__()
32
-
33
  self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
34
  self.lambda_L1 = lambda_L1
35
-
36
  if net_G is None:
37
- self.net_G = init_model(Unet(input_c=1, output_c=2, n_down=8, num_filters=64), self.device)
 
 
38
  else:
39
  self.net_G = net_G.to(self.device)
40
- self.net_D = init_model(PatchDiscriminator(input_c=3, n_down=3, num_filters=64), self.device)
41
- self.GANcriterion = GANLoss(gan_mode='vanilla').to(self.device)
 
 
42
  self.L1criterion = nn.L1Loss()
43
  self.opt_G = optim.Adam(self.net_G.parameters(), lr=lr_G, betas=(beta1, beta2))
44
  self.opt_D = optim.Adam(self.net_D.parameters(), lr=lr_D, betas=(beta1, beta2))
45
-
46
  def set_requires_grad(self, model, requires_grad=True):
47
  for p in model.parameters():
48
  p.requires_grad = requires_grad
49
-
50
  def setup_input(self, data):
51
- self.L = data['L'].to(self.device)
52
- self.ab = data['ab'].to(self.device)
53
-
54
  def forward(self):
55
  self.fake_color = self.net_G(self.L)
56
-
57
  def backward_D(self):
58
  fake_image = torch.cat([self.L, self.fake_color], dim=1)
59
  fake_preds = self.net_D(fake_image.detach())
@@ -63,7 +71,7 @@ class MainModel(nn.Module):
63
  self.loss_D_real = self.GANcriterion(real_preds, True)
64
  self.loss_D = (self.loss_D_fake + self.loss_D_real) * 0.5
65
  self.loss_D.backward()
66
-
67
  def backward_G(self):
68
  fake_image = torch.cat([self.L, self.fake_color], dim=1)
69
  fake_preds = self.net_D(fake_image)
@@ -71,7 +79,7 @@ class MainModel(nn.Module):
71
  self.loss_G_L1 = self.L1criterion(self.fake_color, self.ab) * self.lambda_L1
72
  self.loss_G = self.loss_G_GAN + self.loss_G_L1
73
  self.loss_G.backward()
74
-
75
  def optimize(self):
76
  self.forward()
77
  self.net_D.train()
@@ -79,9 +87,9 @@ class MainModel(nn.Module):
79
  self.opt_D.zero_grad()
80
  self.backward_D()
81
  self.opt_D.step()
82
-
83
  self.net_G.train()
84
  self.set_requires_grad(self.net_D, False)
85
  self.opt_G.zero_grad()
86
  self.backward_G()
87
- self.opt_G.step()
 
14
  from torchvision.utils import make_grid
15
  from torch.utils.data import Dataset, DataLoader
16
 
17
+ from .Generator import UnetBlock, Unet
18
  from .Discriminator import PatchDiscriminator
19
  from .weights import init_weights
20
+ from .loss import GANLoss
21
 
22
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
23
 
24
+
25
  def init_model(model, device):
26
  model = model.to(device)
27
  model = init_weights(model)
28
  return model
29
 
30
+
31
  class MainModel(nn.Module):
32
+ def __init__(
33
+ self, net_G=None, lr_G=2e-4, lr_D=2e-4, beta1=0.5, beta2=0.999, lambda_L1=100.0
34
+ ):
35
  super().__init__()
36
+
37
  self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
38
  self.lambda_L1 = lambda_L1
39
+
40
  if net_G is None:
41
+ self.net_G = init_model(
42
+ Unet(input_c=1, output_c=2, n_down=8, num_filters=64), self.device
43
+ )
44
  else:
45
  self.net_G = net_G.to(self.device)
46
+ self.net_D = init_model(
47
+ PatchDiscriminator(input_c=3, n_down=3, num_filters=64), self.device
48
+ )
49
+ self.GANcriterion = GANLoss(gan_mode="vanilla").to(self.device)
50
  self.L1criterion = nn.L1Loss()
51
  self.opt_G = optim.Adam(self.net_G.parameters(), lr=lr_G, betas=(beta1, beta2))
52
  self.opt_D = optim.Adam(self.net_D.parameters(), lr=lr_D, betas=(beta1, beta2))
53
+
54
  def set_requires_grad(self, model, requires_grad=True):
55
  for p in model.parameters():
56
  p.requires_grad = requires_grad
57
+
58
  def setup_input(self, data):
59
+ self.L = data["L"].to(self.device)
60
+ self.ab = data["ab"].to(self.device)
61
+
62
  def forward(self):
63
  self.fake_color = self.net_G(self.L)
64
+
65
  def backward_D(self):
66
  fake_image = torch.cat([self.L, self.fake_color], dim=1)
67
  fake_preds = self.net_D(fake_image.detach())
 
71
  self.loss_D_real = self.GANcriterion(real_preds, True)
72
  self.loss_D = (self.loss_D_fake + self.loss_D_real) * 0.5
73
  self.loss_D.backward()
74
+
75
  def backward_G(self):
76
  fake_image = torch.cat([self.L, self.fake_color], dim=1)
77
  fake_preds = self.net_D(fake_image)
 
79
  self.loss_G_L1 = self.L1criterion(self.fake_color, self.ab) * self.lambda_L1
80
  self.loss_G = self.loss_G_GAN + self.loss_G_L1
81
  self.loss_G.backward()
82
+
83
  def optimize(self):
84
  self.forward()
85
  self.net_D.train()
 
87
  self.opt_D.zero_grad()
88
  self.backward_D()
89
  self.opt_D.step()
90
+
91
  self.net_G.train()
92
  self.set_requires_grad(self.net_D, False)
93
  self.opt_G.zero_grad()
94
  self.backward_G()
95
+ self.opt_G.step()
model/loss.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import warnings
2
+
3
+ warnings.filterwarnings("ignore")
4
+
5
+ import os
6
+ import sys
7
+ import glob
8
+ import time
9
+ import numpy as np
10
+ from PIL import Image
11
+ from pathlib import Path
12
+ from tqdm.notebook import tqdm
13
+ import matplotlib.pyplot as plt
14
+ from skimage.color import rgb2lab, lab2rgb
15
+
16
+ import torch
17
+ from torch import nn, optim
18
+ from torchvision import transforms
19
+ from torchvision.utils import make_grid
20
+ from torch.utils.data import Dataset, DataLoader
21
+
22
+
23
+ class GANLoss(nn.Module):
24
+ def __init__(self, gan_mode="vanilla", real_label=1.0, fake_label=0.0):
25
+ super().__init__()
26
+ self.register_buffer("real_label", torch.tensor(real_label))
27
+ self.register_buffer("fake_label", torch.tensor(fake_label))
28
+ if gan_mode == "vanilla":
29
+ self.loss = nn.BCEWithLogitsLoss()
30
+ elif gan_mode == "lsgan":
31
+ self.loss = nn.MSELoss()
32
+
33
+ def get_labels(self, preds, target_is_real):
34
+ if target_is_real:
35
+ labels = self.real_label
36
+ else:
37
+ labels = self.fake_label
38
+ return labels.expand_as(preds)
39
+
40
+ def __call__(self, preds, target_is_real):
41
+ labels = self.get_labels(preds, target_is_real)
42
+ loss = self.loss(preds, labels)
43
+ return loss
model/weights.py CHANGED
@@ -16,24 +16,24 @@ from torch.utils.data import Dataset, DataLoader
16
 
17
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
18
 
19
- def init_weights(net, init='norm', gain=0.02):
20
-
21
  def init_func(m):
22
  classname = m.__class__.__name__
23
- if hasattr(m, 'weight') and 'Conv' in classname:
24
- if init == 'norm':
25
  nn.init.normal_(m.weight.data, mean=0.0, std=gain)
26
- elif init == 'xavier':
27
  nn.init.xavier_normal_(m.weight.data, gain=gain)
28
- elif init == 'kaiming':
29
- nn.init.kaiming_normal_(m.weight.data, a=0, mode='fan_in')
30
-
31
- if hasattr(m, 'bias') and m.bias is not None:
32
  nn.init.constant_(m.bias.data, 0.0)
33
- elif 'BatchNorm2d' in classname:
34
- nn.init.normal_(m.weight.data, 1., gain)
35
- nn.init.constant_(m.bias.data, 0.)
36
-
37
  net.apply(init_func)
38
  print(f"model initialized with {init} initialization")
39
- return net
 
16
 
17
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
18
 
19
+
20
+ def init_weights(net, init="norm", gain=0.02):
21
  def init_func(m):
22
  classname = m.__class__.__name__
23
+ if hasattr(m, "weight") and "Conv" in classname:
24
+ if init == "norm":
25
  nn.init.normal_(m.weight.data, mean=0.0, std=gain)
26
+ elif init == "xavier":
27
  nn.init.xavier_normal_(m.weight.data, gain=gain)
28
+ elif init == "kaiming":
29
+ nn.init.kaiming_normal_(m.weight.data, a=0, mode="fan_in")
30
+
31
+ if hasattr(m, "bias") and m.bias is not None:
32
  nn.init.constant_(m.bias.data, 0.0)
33
+ elif "BatchNorm2d" in classname:
34
+ nn.init.normal_(m.weight.data, 1.0, gain)
35
+ nn.init.constant_(m.bias.data, 0.0)
36
+
37
  net.apply(init_func)
38
  print(f"model initialized with {init} initialization")
39
+ return net
requirements.txt ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiofiles==23.1.0
2
+ aiohttp==3.8.4
3
+ aiosignal==1.3.1
4
+ altair==4.2.2
5
+ anyio==3.6.2
6
+ async-timeout==4.0.2
7
+ attrs==23.1.0
8
+ beautifulsoup4==4.12.2
9
+ black==23.3.0
10
+ certifi==2022.12.7
11
+ charset-normalizer==3.1.0
12
+ click==8.1.3
13
+ cmake==3.26.3
14
+ contourpy==1.0.7
15
+ cycler==0.11.0
16
+ entrypoints==0.4
17
+ fastapi==0.95.1
18
+ ffmpy==0.3.0
19
+ filelock==3.11.0
20
+ fonttools==4.39.3
21
+ frozenlist==1.3.3
22
+ fsspec==2023.4.0
23
+ gdown==4.7.1
24
+ gradio==3.27.0
25
+ gradio_client==0.1.3
26
+ h11==0.14.0
27
+ httpcore==0.17.0
28
+ httpx==0.24.0
29
+ huggingface-hub==0.13.4
30
+ idna==3.4
31
+ imageio==2.27.0
32
+ Jinja2==3.1.2
33
+ joblib==1.2.0
34
+ jsonschema==4.17.3
35
+ kiwisolver==1.4.4
36
+ lazy_loader==0.2
37
+ linkify-it-py==2.0.0
38
+ lit==16.0.1
39
+ markdown-it-py==2.2.0
40
+ MarkupSafe==2.1.2
41
+ matplotlib==3.7.1
42
+ mdit-py-plugins==0.3.3
43
+ mdurl==0.1.2
44
+ mpmath==1.3.0
45
+ multidict==6.0.4
46
+ mypy-extensions==1.0.0
47
+ networkx==3.1
48
+ numpy==1.24.2
49
+ nvidia-cublas-cu11==11.10.3.66
50
+ nvidia-cuda-cupti-cu11==11.7.101
51
+ nvidia-cuda-nvrtc-cu11==11.7.99
52
+ nvidia-cuda-runtime-cu11==11.7.99
53
+ nvidia-cudnn-cu11==8.5.0.96
54
+ nvidia-cufft-cu11==10.9.0.58
55
+ nvidia-curand-cu11==10.2.10.91
56
+ nvidia-cusolver-cu11==11.4.0.1
57
+ nvidia-cusparse-cu11==11.7.4.91
58
+ nvidia-nccl-cu11==2.14.3
59
+ nvidia-nvtx-cu11==11.7.91
60
+ orjson==3.8.10
61
+ packaging==23.1
62
+ pandas==2.0.0
63
+ pathspec==0.11.1
64
+ Pillow==9.5.0
65
+ platformdirs==3.2.0
66
+ pydantic==1.10.7
67
+ pydub==0.25.1
68
+ pyparsing==3.0.9
69
+ pyrsistent==0.19.3
70
+ PySocks==1.7.1
71
+ python-dateutil==2.8.2
72
+ python-multipart==0.0.6
73
+ pytz==2023.3
74
+ PyWavelets==1.4.1
75
+ PyYAML==6.0
76
+ requests==2.28.2
77
+ scikit-image==0.20.0
78
+ scikit-learn==1.2.2
79
+ scipy==1.10.1
80
+ semantic-version==2.10.0
81
+ six==1.16.0
82
+ sniffio==1.3.0
83
+ soupsieve==2.4
84
+ starlette==0.26.1
85
+ sympy==1.11.1
86
+ threadpoolctl==3.1.0
87
+ tifffile==2023.4.12
88
+ tomli==2.0.1
89
+ toolz==0.12.0
90
+ torch==2.0.0
91
+ torchvision==0.15.1
92
+ tqdm==4.65.0
93
+ triton==2.0.0
94
+ typing_extensions==4.5.0
95
+ tzdata==2023.3
96
+ uc-micro-py==1.0.1
97
+ urllib3==1.26.15
98
+ uvicorn==0.21.1
99
+ websockets==11.0.1
100
+ yarl==1.8.2
utility/__init__.py CHANGED
@@ -1 +1 @@
1
- from .helper import *
 
1
+ from .helper import *
utility/helper.py CHANGED
@@ -19,6 +19,9 @@ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
19
  import requests
20
  import gdown
21
 
 
 
 
22
  def download_from_drive():
23
  url = "https://drive.google.com/uc?id=1EhuMET76c02VFyRW8Pie7BwNCDHmQiad"
24
  try:
@@ -33,15 +36,16 @@ def download_from_drive():
33
  class AverageMeter:
34
  def __init__(self):
35
  self.reset()
36
-
37
  def reset(self):
38
- self.count, self.avg, self.sum = [0.] * 3
39
-
40
  def update(self, val, count=1):
41
  self.count += count
42
  self.sum += count * val
43
  self.avg = self.sum / self.count
44
 
 
45
  def create_loss_meters():
46
  loss_D_fake = AverageMeter()
47
  loss_D_real = AverageMeter()
@@ -49,33 +53,38 @@ def create_loss_meters():
49
  loss_G_GAN = AverageMeter()
50
  loss_G_L1 = AverageMeter()
51
  loss_G = AverageMeter()
52
-
53
- return {'loss_D_fake': loss_D_fake,
54
- 'loss_D_real': loss_D_real,
55
- 'loss_D': loss_D,
56
- 'loss_G_GAN': loss_G_GAN,
57
- 'loss_G_L1': loss_G_L1,
58
- 'loss_G': loss_G}
 
 
 
59
 
60
  def update_losses(model, loss_meter_dict, count):
61
  for loss_name, loss_meter in loss_meter_dict.items():
62
  loss = getattr(model, loss_name)
63
  loss_meter.update(loss.item(), count=count)
64
 
 
65
  def lab_to_rgb(L, ab):
66
  """
67
  Takes a batch of images
68
  """
69
-
70
- L = (L + 1.) * 50.
71
- ab = ab * 110.
72
  Lab = torch.cat([L, ab], dim=1).permute(0, 2, 3, 1).cpu().numpy()
73
  rgb_imgs = []
74
  for img in Lab:
75
  img_rgb = lab2rgb(img)
76
  rgb_imgs.append(img_rgb)
77
  return np.stack(rgb_imgs, axis=0)
78
-
 
79
  def visualize(model, data, save=True):
80
  model.net_G.eval()
81
  with torch.no_grad():
@@ -90,7 +99,7 @@ def visualize(model, data, save=True):
90
  fig = plt.figure(figsize=(15, 8))
91
  for i in range(5):
92
  ax = plt.subplot(3, 5, i + 1)
93
- ax.imshow(L[i][0].cpu(), cmap='gray')
94
  ax.axis("off")
95
  ax = plt.subplot(3, 5, i + 1 + 5)
96
  ax.imshow(fake_imgs[i])
@@ -101,11 +110,13 @@ def visualize(model, data, save=True):
101
  plt.show()
102
  if save:
103
  fig.savefig(f"colorization_{time.time()}.png")
104
-
 
105
  def log_results(loss_meter_dict):
106
  for loss_name, loss_meter in loss_meter_dict.items():
107
  print(f"{loss_name}: {loss_meter.avg:.5f}")
108
-
 
109
  def create_lab_tensors(image):
110
  """
111
  This function receives an image path or a direct image input and creates a dictionary of L and ab tensors.
@@ -116,22 +127,28 @@ def create_lab_tensors(image):
116
  """
117
  if isinstance(image, str):
118
  # Open the image and convert it to RGB format
119
- img = Image.open(image).convert('RGB')
120
  else:
121
- img = image.convert('RGB')
122
-
123
- custom_transforms = transforms.Compose([
124
- transforms.Resize((SIZE, SIZE), Image.BICUBIC),
125
- transforms.RandomHorizontalFlip(), # A little data augmentation!
126
- ])
 
 
 
 
 
 
127
  img = custom_transforms(img)
128
  img = np.array(img)
129
- img_lab = rgb2lab(img).astype("float32") # Converting RGB to L*a*b
130
  img_lab = transforms.ToTensor()(img_lab)
131
- L = img_lab[[0], ...] / 50. - 1. # Between -1 and 1
132
- L = L.unsqueeze(0)
133
- ab = img_lab[[1, 2], ...] / 110. # Between -1 and 1
134
- return {'L': L, 'ab': ab}
135
 
136
 
137
  def predict_and_visualize_single_image(model, data, save=True):
@@ -143,18 +160,19 @@ def predict_and_visualize_single_image(model, data, save=True):
143
  L = model.L
144
  fake_imgs = lab_to_rgb(L, fake_color)
145
  fig, axs = plt.subplots(1, 2, figsize=(8, 4))
146
- axs[0].imshow(L[0][0].cpu(), cmap='gray')
147
  axs[0].set_title("Grey Image")
148
- axs[0].axis('off')
149
 
150
  axs[1].imshow(fake_imgs[0])
151
  axs[1].set_title("Colored Image")
152
- axs[1].axis('off')
153
  plt.show()
154
  if save:
155
  fig.savefig(f"colorization_{time.time()}.png")
156
-
157
- def predict_color(model , image , save=False):
 
158
  """
159
  This function receives an image path or a direct image input and creates a dictionary of L and ab tensors.
160
  Args:
@@ -165,14 +183,30 @@ def predict_color(model , image , save=False):
165
  predict_and_visualize_single_image(model, data, save)
166
 
167
 
168
- def load_model(model_class, file_path):
169
  """
170
  Load PyTorch model from file.
171
-
172
  Args:
173
  model_class (torch.nn.Module): PyTorch model class to load.
174
  file_path (str): File path to load the model from.
175
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  Returns:
177
  model (torch.nn.Module): Loaded PyTorch model.
178
  """
 
19
  import requests
20
  import gdown
21
 
22
+ SIZE = 256
23
+
24
+
25
  def download_from_drive():
26
  url = "https://drive.google.com/uc?id=1EhuMET76c02VFyRW8Pie7BwNCDHmQiad"
27
  try:
 
36
  class AverageMeter:
37
  def __init__(self):
38
  self.reset()
39
+
40
  def reset(self):
41
+ self.count, self.avg, self.sum = [0.0] * 3
42
+
43
  def update(self, val, count=1):
44
  self.count += count
45
  self.sum += count * val
46
  self.avg = self.sum / self.count
47
 
48
+
49
  def create_loss_meters():
50
  loss_D_fake = AverageMeter()
51
  loss_D_real = AverageMeter()
 
53
  loss_G_GAN = AverageMeter()
54
  loss_G_L1 = AverageMeter()
55
  loss_G = AverageMeter()
56
+
57
+ return {
58
+ "loss_D_fake": loss_D_fake,
59
+ "loss_D_real": loss_D_real,
60
+ "loss_D": loss_D,
61
+ "loss_G_GAN": loss_G_GAN,
62
+ "loss_G_L1": loss_G_L1,
63
+ "loss_G": loss_G,
64
+ }
65
+
66
 
67
  def update_losses(model, loss_meter_dict, count):
68
  for loss_name, loss_meter in loss_meter_dict.items():
69
  loss = getattr(model, loss_name)
70
  loss_meter.update(loss.item(), count=count)
71
 
72
+
73
  def lab_to_rgb(L, ab):
74
  """
75
  Takes a batch of images
76
  """
77
+
78
+ L = (L + 1.0) * 50.0
79
+ ab = ab * 110.0
80
  Lab = torch.cat([L, ab], dim=1).permute(0, 2, 3, 1).cpu().numpy()
81
  rgb_imgs = []
82
  for img in Lab:
83
  img_rgb = lab2rgb(img)
84
  rgb_imgs.append(img_rgb)
85
  return np.stack(rgb_imgs, axis=0)
86
+
87
+
88
  def visualize(model, data, save=True):
89
  model.net_G.eval()
90
  with torch.no_grad():
 
99
  fig = plt.figure(figsize=(15, 8))
100
  for i in range(5):
101
  ax = plt.subplot(3, 5, i + 1)
102
+ ax.imshow(L[i][0].cpu(), cmap="gray")
103
  ax.axis("off")
104
  ax = plt.subplot(3, 5, i + 1 + 5)
105
  ax.imshow(fake_imgs[i])
 
110
  plt.show()
111
  if save:
112
  fig.savefig(f"colorization_{time.time()}.png")
113
+
114
+
115
  def log_results(loss_meter_dict):
116
  for loss_name, loss_meter in loss_meter_dict.items():
117
  print(f"{loss_name}: {loss_meter.avg:.5f}")
118
+
119
+
120
  def create_lab_tensors(image):
121
  """
122
  This function receives an image path or a direct image input and creates a dictionary of L and ab tensors.
 
127
  """
128
  if isinstance(image, str):
129
  # Open the image and convert it to RGB format
130
+ img = Image.open(image).convert("RGB")
131
  else:
132
+ if isinstance(image, np.ndarray):
133
+ img = Image.fromarray(image)
134
+ else:
135
+ img = image
136
+ img = img.convert("RGB")
137
+
138
+ custom_transforms = transforms.Compose(
139
+ [
140
+ transforms.Resize((SIZE, SIZE), Image.BICUBIC),
141
+ transforms.RandomHorizontalFlip(), # A little data augmentation!
142
+ ]
143
+ )
144
  img = custom_transforms(img)
145
  img = np.array(img)
146
+ img_lab = rgb2lab(img).astype("float32") # Converting RGB to L*a*b
147
  img_lab = transforms.ToTensor()(img_lab)
148
+ L = img_lab[[0], ...] / 50.0 - 1.0 # Between -1 and 1
149
+ L = L.unsqueeze(0)
150
+ ab = img_lab[[1, 2], ...] / 110.0 # Between -1 and 1
151
+ return {"L": L, "ab": ab}
152
 
153
 
154
  def predict_and_visualize_single_image(model, data, save=True):
 
160
  L = model.L
161
  fake_imgs = lab_to_rgb(L, fake_color)
162
  fig, axs = plt.subplots(1, 2, figsize=(8, 4))
163
+ axs[0].imshow(L[0][0].cpu(), cmap="gray")
164
  axs[0].set_title("Grey Image")
165
+ axs[0].axis("off")
166
 
167
  axs[1].imshow(fake_imgs[0])
168
  axs[1].set_title("Colored Image")
169
+ axs[1].axis("off")
170
  plt.show()
171
  if save:
172
  fig.savefig(f"colorization_{time.time()}.png")
173
+
174
+
175
+ def predict_color(model, image, save=False):
176
  """
177
  This function receives an image path or a direct image input and creates a dictionary of L and ab tensors.
178
  Args:
 
183
  predict_and_visualize_single_image(model, data, save)
184
 
185
 
186
+ def load_model_with_cpu(model_class, file_path):
187
  """
188
  Load PyTorch model from file.
189
+
190
  Args:
191
  model_class (torch.nn.Module): PyTorch model class to load.
192
  file_path (str): File path to load the model from.
193
+
194
+ Returns:
195
+ model (torch.nn.Module): Loaded PyTorch model.
196
+ """
197
+ model = model_class()
198
+ model.load_state_dict(torch.load(file_path, map_location=torch.device("cpu")))
199
+ return model
200
+
201
+
202
+ def load_model_with_gpu(model_class, file_path):
203
+ """
204
+ Load PyTorch model from file.
205
+
206
+ Args:
207
+ model_class (torch.nn.Module): PyTorch model class to load.
208
+ file_path (str): File path to load the model from.
209
+
210
  Returns:
211
  model (torch.nn.Module): Loaded PyTorch model.
212
  """