# -*- coding: utf-8 -*- """Copy NGANof .ipynb Automatically generated by Colab. Original file is located at https://colab.research.google.com/drive/1w2sRg7uNq-lx67zg9Afcr58f2P_R-5ca """ !pip install ninja !sudo apt-get update !sudo apt-get install build-essential !rm -rf ~/.cache/torch_extensions/ !pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu121 !pip install requests tqdm # Commented out IPython magic to ensure Python compatibility. !git clone https://github.com/NVlabs/stylegan2-ada-pytorch.git # %cd stylegan2-ada-pytorch !wget https://nvlabs-fi-cdn.nvidia.com/stylegan2-ada-pytorch/pretrained/ffhq.pkl from google.colab import drive drive.mount('/content/drive') # Import necessary libraries import torch from torch.utils.data import Dataset, DataLoader from torchvision import transforms import os import PIL.Image import numpy as np import dnnlib import legacy # Load pre-trained model import pickle with open('ffhq.pkl', 'rb') as f: data = pickle.load(f) print(data.keys()) # Check if CUDA is available, and if so, move the model to GPU if torch.cuda.is_available(): G = data['G_ema'].cuda() D = data['D'].cuda() print("Model loaded on GPU.") else: G = data['G_ema'] # Keep the model on CPU D = data['D'].cuda() print("CUDA not available, model loaded on CPU.") print(type(G)) print(G) print(type(D)) print(D) def generate_images(G, z=None, num_images=1, truncation_psi=0.7, seed=None): if seed is not None: torch.manual_seed(seed) device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') if torch.cuda.is_available(): print("CUDA is available. Using GPU.") else: print("CUDA is not available. Using CPU.") if z is None: z = torch.randn((num_images, G.z_dim), device=device) else: z = z.to(device) print("Latent vectors prepared.") ws = G.mapping(z, None, truncation_psi=truncation_psi) print("Mapping done.") img = G.synthesis(ws, noise_mode='const') print("Synthesis done.") img = (img.permute(0, 2, 3, 1) * 127.5 + 128).clamp(0, 255).to(torch.uint8).cpu().numpy() print("Image tensor converted to numpy array.") return [Image.fromarray(i) for i in img] from PIL import Image # Add this import # Generate 4 images generated_images = generate_images(G, num_images=4, truncation_psi=0.7, seed=42) # Generate and display 4 images #generated_images = generate_images(G, num_images=4, truncation_psi=0.7, seed=42) print("Images generated.") for i, img in enumerate(generated_images): display(img) # Fine-tuning setup import os from torch.utils.data import Dataset, DataLoader from torchvision import transforms # Advanced fine-tuning setup import torch from torch.optim import Adam from torch.utils.data import Dataset, DataLoader from torchvision import transforms from torchvision.utils import save_image # Custom dataset class CustomDataset(Dataset): def __init__(self, image_dir, transform=None): self.image_dir = image_dir self.image_files = [f for f in os.listdir(image_dir) if f.endswith('.jpg') or f.endswith('.png')] if len(self.image_files) == 0: raise ValueError(f"No image files found in directory: {image_dir}") self.transform = transform def __len__(self): return len(self.image_files) def __getitem__(self, idx): img_path = os.path.join(self.image_dir, self.image_files[idx]) image = PIL.Image.open(img_path).convert('RGB') if self.transform: image = self.transform(image) return image !pip install datasets from datasets import load_dataset ds = load_dataset("TrainingDataPro/black-people-liveness-detection-video-dataset") # Set up data loading transform = transforms.Compose([ transforms.Resize((G.img_resolution, G.img_resolution)), transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) ]) dataset = CustomDataset("/content/drive/MyDrive/Colab Notebooks/part2", transform=transform) dataloader = DataLoader(dataset, batch_size=4, shuffle=True) # Fine-tuning loop (advanced) optimizer_g = Adam(G.parameters(), lr=0.0001, betas=(0, 0.99), eps=1e-8) optimizer_d = Adam(D.parameters(), lr=0.0001, betas=(0, 0.99), eps=1e-8) scheduler_g = torch.optim.lr_scheduler.ExponentialLR(optimizer_g, gamma=0.99) scheduler_d = torch.optim.lr_scheduler.ExponentialLR(optimizer_d, gamma=0.99) num_epochs = 100 for epoch in range(num_epochs): for batch in dataloader: real_images = batch.cuda() # Generate fake images z = torch.randn([batch.shape[0], G.z_dim]).cuda() fake_images = G(z, None) # Replace None with actual labels if available # Ensure fake_images requires gradients fake_images.requires_grad_(True) # Prepare a dummy label (replace with actual labels if available) c = None # Replace 'some_dimension' with the correct size # Compute loss (using BCE loss) g_loss = torch.mean(torch.log(1 - D(fake_images, c))) # Pass the dummy label to D d_loss_real = torch.mean(torch.log(D(real_images, c))) # Pass the dummy label to D d_loss_fake = torch.mean(torch.log(1 - D(fake_images, c))) # Pass the dummy label to D d_loss = -d_loss_real - d_loss_fake # Check for NaNs if torch.isnan(g_loss) or torch.isnan(d_loss): #print("NaN detected in loss. Skipping update.") continue # Update generator optimizer_g.zero_grad() g_loss.backward() torch.nn.utils.clip_grad_norm_(G.parameters(), max_norm=1) # Clip gradients optimizer_g.step() # Update discriminator optimizer_d.zero_grad() d_loss.backward() torch.nn.utils.clip_grad_norm_(D.parameters(), max_norm=1) # Clip gradients optimizer_d.step() # Update learning rate scheduler_g.step() scheduler_d.step() print(f"Epoch {epoch+1}/{num_epochs}, G Loss: {g_loss.item()}") # Save the full model torch.save(G, '/content/drive/MyDrive/full_model_stylegan.pt') for param in G.parameters(): param.requires_grad = True # Generate new images with fine-tuned model z = torch.randn([4, G.z_dim]).cuda() # Generate 4 random latent vectors imgs = generate_images(G, z, truncation_psi=0.7) # Display each generated image for img in imgs: display(img) # Save the fine-tuned model torch.save(G.state_dict(), 'fine_tuned_stylegan.pth') !pip install gradio import torch import torchvision.transforms as transforms from PIL import Image import gradio as gr from tqdm import tqdm def optimize_latent_vector(G, target_image, num_iterations=1000): device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') target_image = transforms.Resize((G.img_resolution, G.img_resolution))(target_image) target_tensor = transforms.ToTensor()(target_image).unsqueeze(0).to(device) target_tensor = (target_tensor * 2) - 1 # Normalize to [-1, 1] latent_vector = torch.randn((1, G.z_dim), device=device, requires_grad=True) optimizer = torch.optim.Adam([latent_vector], lr=0.1) for i in tqdm(range(num_iterations), desc="Optimizing latent vector"): optimizer.zero_grad() generated_image = G(latent_vector, None) loss = torch.nn.functional.mse_loss(generated_image, target_tensor) loss.backward() optimizer.step() if (i + 1) % 100 == 0: print(f'Iteration {i+1}/{num_iterations}, Loss: {loss.item()}') return latent_vector.detach() def generate_from_upload(uploaded_image): device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # Optimize latent vector for the uploaded image optimized_z = optimize_latent_vector(G, uploaded_image) # Generate variations num_variations = 4 variation_strength = 0.1 varied_z = optimized_z + torch.randn((num_variations, G.z_dim), device=device) * variation_strength # Generate the variations with torch.no_grad(): imgs = G(varied_z, c=None, truncation_psi=0.7, noise_mode='const') imgs = (imgs * 127.5 + 128).clamp(0, 255).to(torch.uint8) imgs = imgs.permute(0, 2, 3, 1).cpu().numpy() # Convert the generated image tensors to PIL Images generated_images = [Image.fromarray(img) for img in imgs] # Return the images separately return generated_images[0], generated_images[1], generated_images[2], generated_images[3] # Create the Gradio interface iface = gr.Interface( fn=generate_from_upload, inputs=gr.Image(type="pil"), outputs=[gr.Image(type="pil") for _ in range(4)], title="StyleGAN Image Variation Generator" ) # Launch the Gradio interface iface.launch(share=True, debug=True) # If you want to test it without the Gradio interface: """ # Load an image explicitly image_path = "path/to/your/image.jpg" image = Image.open(image_path) # Call the generate method explicitly generated_images = generate_from_upload(image) # Display the generated images for img in generated_images: img.show() """