Commit 7c0e64ce authored by Meet Narendra's avatar Meet Narendra 💬

Merge branch 'DEV' into 'master'

First Project Evaluation

See merge request !2
parents 107e376e 12038f26
*pycache*
*.pdf
*.csv
*.ipynb
*Logs*
This diff is collapsed.
import torch
import torch.nn as NN
from logger import Logger
LOGGER = Logger().logger()
LOGGER.info("Started Feature Maps")
device=torch.device( "cuda" if (torch.cuda.is_available()) else 'cpu')
LOGGER.info("Running the model cuda_available = "+str(torch.cuda.is_available()))
#Author: @meetdoshi
class FeatureMaps():
def __init__(self,arch="vgg19"):
'''
Init function
@params
arch: str {vgg11,vgg13,vgg16,vgg19,vgg19bn}
'''
super()
try:
self.model = torch.hub.load('pytorch/vision:v0.10.0',arch,pretrained=True)
except Exception as e:
LOGGER.error("Could not load model" + str(e))
return
def get_model(self):
return self.model
def get_layers(self,layers=[]):
'''
Function to extract layers
@params
layers: list
'''
weights = []
for layer in layers:
try:
weights.append(self.model.features[layer].weight)
except:
LOGGER.error("Could not fetch layer "+str(layer))
return weights
def get_fmaps_content(self,img,layer=[21]):
'''
Function which will pass the image through the model and get the respective fmaps
@params
img: numpy image f64
layer: list
'''
fmaps = []
layer_num = 0
for layer_i in self.model.features:
img = layer_i(img)
if layer_num in layer:
fmaps.append(img)
layer_num+=1
return fmaps
def get_fmaps_style(self,img,layer=[0,5,10,19,28]):
'''
Function which will pass the image through the model and get the respective fmaps
@params
img: numpy image f64
layer: list
'''
fmaps = []
layer_num = 0
for layer_i in self.model.features:
img = layer_i(img)
if layer_num in layer:
fmaps.append(img)
layer_num+=1
return fmaps
'''
if __name__ == "__main__":
fmap = FeatureMaps()
model = fmap.get_model()
print(model.features)
weights = fmap.get_layers([4,2,6])
print(len(weights))
for weight in weights:
print(type(weight),weight.shape)
'''
import imageio
import os
fnames = []
newNameFolder = 'content-4_2'
path = 'styled_images/'+newNameFolder
for img in os.listdir(path):
fnames.append(os.path.join(path+"/", img))
fnames.sort()
with imageio.get_writer('gifs/'+newNameFolder+".gif", mode='I',duration = 0.2) as writer:
for fname in fnames:
image = imageio.imread(fname)
writer.append_data(image)
import logging
import os
from xml.dom.minidom import Identified
#Author: @meetdoshi
class Logger:
'''
Singleton logger class
'''
_instance = None
_logHandler = None
_formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
def __new__(cls,*args,**kwargs):
if not cls._instance:
identifier = 'content-4_2'
if not os.path.isdir("Logs/"):
os.mkdir("Logs/")
logHandler = logging.FileHandler("Logs/style_transfer_"+identifier+".log")
logHandler.setFormatter(cls._formatter)
cls._logHandler = logging.getLogger("Logs/style_transfer_"+identifier+".log")
cls._logHandler.setLevel(logging.INFO)
cls._logHandler.addHandler(logHandler)
cls._instance = super(Logger, cls).__new__(cls,*args,**kwargs)
return cls._instance
def logger(self):
return self._logHandler
'''
#Demo use
if __name__ == "__main__":
a = Logger()
b = Logger()
print(a is b)
INFO = a.logger()
ERROR = b.logger()
INFO.info("TEST")
ERROR.info("ERROR")
'''
import numpy as np
import torch
from logger import Logger
LOGGER = Logger().logger()
class Loss:
@staticmethod
def content_loss(F,P):
'''
Function to compute content loss between two feature representations at a particular layer
@params
F: 2D numpy array
P: 2D numpy array
Author: @meetdoshi
'''
l2_norm_sq = None
try:
diff = F-P
l2_norm_sq = torch.mean((diff)**2)
except Exception as e:
LOGGER.error("Error computing loss",e)
return l2_norm_sq
@staticmethod
def gram_matrix(F):
'''
Function to compute the gram matrix of a feature representation at a layer
Author: @himalisaini
'''
shape_mat = F.shape
num_channels = shape_mat[1]
height = shape_mat[2]
width = shape_mat[3]
return torch.mm(F.view(num_channels,(height*width)),F.view(num_channels,(height*width)).t())
@staticmethod
def style_loss(F,A):
'''
Function to compute style loss between two feature representations at multiple layers
@params
Author: @soumyagupta
'''
num_channels = F.shape[1]
h = F.shape[2]
w = F.shape[3]
style_gram_matrix = Loss.gram_matrix(F)
target_gram_matrix = Loss.gram_matrix(A)
loss_s = torch.mean((style_gram_matrix-target_gram_matrix)**2)
#constant = 1/(4.0*(num_channels**2)*((h*w)**2))
return loss_s
@staticmethod
def total_loss(alpha,beta,cont_fmap_real,style_fmap_real,generated_fmaps_content,generated_fmaps_style):
'''
Function which computes total loss and returns it
@params
Author: @jiteshg
'''
loss_t = 0.0
a = 0.0
b = 0.0
for cont,gen_cont in zip(cont_fmap_real,generated_fmaps_content):
loss_cont = Loss.content_loss(cont,gen_cont)
a+= loss_cont
for gen_style,sty in zip(generated_fmaps_style,style_fmap_real):
loss_style = Loss.style_loss(sty,gen_style)
b+= loss_style
loss_t += alpha*a + beta*b
return loss_t,a,b
\ No newline at end of file
from loss import Loss
from feature_maps import LOGGER, FeatureMaps
import torch.optim as optim
from torchvision.utils import save_image
import matplotlib.pyplot as plt
import os
plt.ion()
class Optimizer:
@staticmethod
def gradient_descent(content_img, style_img, content_img_clone):
'''
Fuction to apply gradient descent on the content image
@params
content_img: Original Image
style_img: Styling Image
content_img_clone: Copy of Original Image
Author: @gaurangathavale
'''
LOGGER.info("Running gradient descent with the following parameters")
epoch = 4000
learning_rate = 0.01
alpha = 1
beta = 0.01
identifier = "content-4_2"
os.mkdir("styled_images/"+identifier)
LOGGER.info(f"{epoch},{learning_rate},{alpha},{beta}")
optimizer=optim.Adam([content_img_clone],lr=learning_rate)
LOGGER.info("Optimizer = " + str(optimizer))
#fig = plt.figure()
#ax = fig.add_subplot(111)
feature_maps = FeatureMaps()
for e in range(epoch):
content_fmaps = feature_maps.get_fmaps_content(content_img)
style_fmaps = feature_maps.get_fmaps_style(style_img)
generated_fmaps_content = feature_maps.get_fmaps_content(content_img_clone)
generated_fmaps_style = feature_maps.get_fmaps_style(content_img_clone)
total_loss,total_cont_loss,total_style_loss = Loss.total_loss(alpha, beta, content_fmaps, style_fmaps,generated_fmaps_content,generated_fmaps_style)
# clears x.grad for every parameter x in the optimizer.
# It’s important to call this before total_loss.backward(), otherwise it will accumulate the gradients from multiple passes.
optimizer.zero_grad()
# total_loss.backward() computes dtotal_loss/dx for every parameter x which has requires_grad=True
total_loss.backward()
# Optimization Step / Update Rule
optimizer.step()
#plt.clf()
#plt.plot(content_img_clone)
if(e%10 == 0):
LOGGER.info(f"Epoch = {e} Total Loss = {total_loss} content Loss = {total_cont_loss} style Loss = {total_style_loss}")
name = "styled_images/"+identifier+"/styled_" + str(e) +".png"
save_image(content_img_clone,name)
\ No newline at end of file
from os import device_encoding
from logger import Logger
import torch
import torchvision.transforms as transforms
from PIL import Image
import numpy as np
LOGGER = Logger().logger()
device=torch.device( "cuda" if (torch.cuda.is_available()) else 'cpu')
#Author: @meetdoshi
class Preprocessor:
@staticmethod
def load_image(path):
'''
Function to load image
@params
path: os.path
'''
img = Image.open(path)
return img
@staticmethod
def subtract_mean(img):
'''
Function to subtract mean values of RGB channels computed over whole ImageNet dataset
@params
img: 3d numpy array
'''
mean = np.reshape([103.939, 116.779, 123.68],(1,1,3))#b,g,r
return img-mean
@staticmethod
def reshape_img(img):
'''
Function to reshpae image in 224x224xnum_of_channels shape
@params
img: 3d numpy array
'''
#loader = transforms.Compose([transforms.ToTensor(),transforms.Resize([224,224]),transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225],),])
loader = transforms.Compose([transforms.ToTensor(),transforms.Resize([224,224])])
img = loader(img).unsqueeze(0)
#assert img.shape == (1,3,224,224)
return img.to(device,torch.float)
@staticmethod
def process(path):
'''
Function to preprocess the image
@params
path: os.path
'''
img = Preprocessor.load_image(path)
img = Preprocessor.reshape_img(img)
#img = Preprocessor.subtract_mean(img)
return img
'''
if __name__=="__main__":
prec = Preprocessor()
img = np.zeros(shape=(4,4,3))
img = prec.process('test/sem8.jpeg')
'''
matplotlib==3.5.1
numpy==1.21.5
Pillow==9.2.0
torch==1.12.1+cpu
torchvision==0.13.1+cpu
import os
import warnings
from optimizer import Optimizer
from loss import Loss
from preprocess import Preprocessor
from feature_maps import FeatureMaps
import numpy as np
import time
import torch
import argparse
import torchvision.models as models
import torch.optim as optim
from torchvision.utils import save_image
warnings.filterwarnings('ignore')
from logger import Logger
LOGGER = Logger().logger()
LOGGER.info("Started Style Transfer")
class StyleTransfer:
'''
Style Transfer Base Class
'''
def __init__(self) -> None:
pass
@staticmethod
def pipeline():
'''
Pipeline for style transfer
@params: None
Author: @gaurangathavale
'''
device = torch.device( "cuda" if (torch.cuda.is_available()) else 'cpu')
content_img_path = 'test/content.jpg'
style_img_path = 'test/style.jpg'
content_img = Preprocessor.process(content_img_path)
style_img = Preprocessor.process(style_img_path)
content_img_clone = content_img.clone().requires_grad_(True)
Optimizer.gradient_descent(content_img, style_img, content_img_clone)
if __name__ == "__main__":
stf = StyleTransfer()
stf.pipeline()
\ No newline at end of file
import logging
import os
#Author: @meetdoshi
class Logger:
'''
Singleton logger class
'''
_instance = None
_logHandler = None
_formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
def __new__(cls,*args,**kwargs):
if not cls._instance:
os.system("rm -rf Logs/")
os.mkdir("Logs/")
logHandler = logging.FileHandler("Logs/style_transfer.log")
logHandler.setFormatter(cls._formatter)
cls._logHandler = logging.getLogger("Logs/style_transfer.log")
cls._logHandler.setLevel(logging.INFO)
cls._logHandler.addHandler(logHandler)
cls._instance = super(Logger, cls).__new__(cls,*args,**kwargs)
return cls._instance
def logger(self):
return self._logHandler
'''
#Demo use
if __name__ == "__main__":
a = Logger()
b = Logger()
print(a is b)
INFO = a.logger()
ERROR = b.logger()
INFO.info("TEST")
ERROR.info("ERROR")
'''
import numpy as np
import torch
from logger import Logger
LOGGER = Logger().logger()
class Loss:
@staticmethod
def adversarial_G():
'''
L_gan(G,Dy,X,Y) =
'''
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment