ttoosi commited on
Commit
e98a2b8
·
verified ·
1 Parent(s): ab559c9

Update app.py

Browse files

fix params and grad

Files changed (1) hide show
  1. app.py +34 -52
app.py CHANGED
@@ -64,74 +64,56 @@ from torchvision import transforms
64
  from PIL import Image
65
  import numpy as np
66
 
67
- # Simple Generative Inference function
68
- def simple_generative_inference(
69
- image, mode, model, n_iterations=10, step_size=0.01, noise_ratio=0.1, eps=0.1
70
- ):
71
- """
72
- Perform Generative Perceptual Inference on the input image.
73
- :param image: Input image as a PIL image.
74
- :param mode: Either 'increase confidence' or 'ReverseDiffuse'.
75
- :param model: Pretrained PyTorch model.
76
- :param n_iterations: Number of inference iterations.
77
- :param step_size: Step size for gradient-based updates.
78
- :param noise_ratio: Ratio of noise to be added in ReverseDiffuse mode.
79
- :param eps: Constraint on perturbation magnitude.
80
- :return: Processed image and gradient visualization.
81
- """
82
  # Preprocess image
83
  transform = transforms.Compose([
84
- transforms.Resize((224, 224)),
85
  transforms.ToTensor(),
86
- transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) # Adjust normalization as needed
87
  ])
88
- image_tensor = transform(image).unsqueeze(0)
89
- image_tensor.requires_grad_(True) # Enable gradient computation for the image tensor
90
-
91
- optimizer = torch.optim.SGD([image_tensor], lr=step_size)
92
-
93
- # Define least likely classes for "increase confidence" mode
94
- if mode == "increase confidence":
95
- with torch.no_grad():
96
- output = model(image_tensor)
97
- probs = torch.nn.functional.softmax(output, dim=1)
98
- _, least_likely_classes = torch.topk(probs, k=5, largest=False, dim=1)
99
-
100
- # Create noisy image (only for ReverseDiffuse mode)
101
- if mode == "ReverseDiffuse":
102
- noisy_image = image_tensor + torch.randn_like(image_tensor) * noise_ratio
103
 
104
  for _ in range(n_iterations):
105
- optimizer.zero_grad()
 
 
 
 
106
  output = model(image_tensor)
107
 
108
  # Define inference loss based on mode
109
  if mode == "increase confidence":
 
 
110
  losses = []
111
- for idx in least_likely_classes[0]: # Iterate over least likely classes
112
  target = torch.full((1,), idx, dtype=torch.long, device=output.device)
113
- loss = torch.nn.functional.cross_entropy(output, target)
114
  losses.append(loss)
115
- loss = torch.stack(losses).mean() # Average loss over least likely classes
116
  elif mode == "ReverseDiffuse":
 
117
  loss = torch.nn.functional.mse_loss(image_tensor, noisy_image)
118
  else:
119
  raise ValueError("Invalid mode selected. Choose 'increase confidence' or 'ReverseDiffuse'.")
120
 
121
- # Compute gradients and update the image
122
  loss.backward()
123
- grad = image_tensor.grad.data
 
 
124
  grad_norm = grad.view(grad.shape[0], -1).norm(dim=1, keepdim=True).view(grad.shape[0], 1, 1, 1)
125
- scaled_grad = grad / (grad_norm + 1e-10)
126
- image_tensor = torch.clamp(
127
- image_tensor + step_size * scaled_grad,
128
- min=image_tensor - eps,
129
- max=image_tensor + eps
130
- )
131
 
132
  # Generate gradient visualization
133
- grad_visualization = image_tensor.grad.abs().mean(dim=1).squeeze().cpu().numpy()
134
- grad_image = (grad_visualization - grad_visualization.min()) / (grad_visualization.max() - grad_visualization.min())
135
  grad_image = Image.fromarray((grad_image * 255).astype(np.uint8))
136
 
137
  # Convert final processed image back to PIL format
@@ -149,17 +131,17 @@ iface = gr.Interface(
149
  inputs=[
150
  gr.Image(type="pil", label="Input Image"), # Input image
151
  gr.Radio(["increase confidence", "ReverseDiffuse"], label="Inference Mode"), # Mode selection
152
- gr.Slider(0.001, 1.0, value=0.01, step=0.001, label="Step Size"), # Step size
153
- gr.Slider(0.001, 0.5, value=0.1, step=0.001, label="Epsilon (eps)"), # Epsilon constraint
154
- gr.Slider(0.0, 0.5, value=0.1, step=0.01, label="Noise Ratio"), # Noise ratio
155
- gr.Slider(1, 100, value=10, step=1, label="Number of Iterations"), # Number of iterations
156
  ],
157
  outputs=[
158
  gr.Image(label="Processed Image"), # Processed image
159
  gr.Image(label="Gradient Visualization") # Gradient visualization
160
  ],
161
- title="Generative Perceptual Inference (GPI)",
162
- description="Perform GPI on input images using adjustable parameters such as step size, epsilon, noise ratio, and number of iterations."
163
  )
164
 
165
 
 
64
  from PIL import Image
65
  import numpy as np
66
 
67
+ def simple_generative_inference(image, mode, model, n_iterations=10, step_size=0.01, eps=0.1, noise_ratio=0.1):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  # Preprocess image
69
  transform = transforms.Compose([
70
+ transforms.Resize((224, 224)), # Enforce fixed size
71
  transforms.ToTensor(),
72
+ transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
73
  ])
74
+ image_tensor = transform(image).unsqueeze(0).requires_grad_(True)
75
+ image_tensor.retain_grad() # Ensure gradients are retained for non-leaf tensor
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
  for _ in range(n_iterations):
78
+ # Zero gradients
79
+ if image_tensor.grad is not None:
80
+ image_tensor.grad.zero_()
81
+
82
+ # Forward pass
83
  output = model(image_tensor)
84
 
85
  # Define inference loss based on mode
86
  if mode == "increase confidence":
87
+ probs = torch.nn.functional.softmax(output, dim=1)
88
+ _, least_likely_indices = torch.topk(probs, k=2, largest=False)
89
  losses = []
90
+ for idx in least_likely_indices[0]:
91
  target = torch.full((1,), idx, dtype=torch.long, device=output.device)
92
+ loss = torch.nn.CrossEntropyLoss()(output, target)
93
  losses.append(loss)
94
+ loss = torch.stack(losses).mean()
95
  elif mode == "ReverseDiffuse":
96
+ noisy_image = image_tensor + torch.randn_like(image_tensor) * noise_ratio
97
  loss = torch.nn.functional.mse_loss(image_tensor, noisy_image)
98
  else:
99
  raise ValueError("Invalid mode selected. Choose 'increase confidence' or 'ReverseDiffuse'.")
100
 
101
+ # Backward pass
102
  loss.backward()
103
+
104
+ # Access gradient
105
+ grad = image_tensor.grad # Gradient is now retained
106
  grad_norm = grad.view(grad.shape[0], -1).norm(dim=1, keepdim=True).view(grad.shape[0], 1, 1, 1)
107
+ grad = grad / (grad_norm + 1e-10) # Avoid division by zero
108
+
109
+ # Update image tensor
110
+ with torch.no_grad():
111
+ image_tensor += step_size * grad
112
+ image_tensor.clamp_(-eps, eps) # Keep within range
113
 
114
  # Generate gradient visualization
115
+ grad_image = grad.abs().mean(dim=1).squeeze().cpu().numpy()
116
+ grad_image = (grad_image - grad_image.min()) / (grad_image.max() - grad_image.min())
117
  grad_image = Image.fromarray((grad_image * 255).astype(np.uint8))
118
 
119
  # Convert final processed image back to PIL format
 
131
  inputs=[
132
  gr.Image(type="pil", label="Input Image"), # Input image
133
  gr.Radio(["increase confidence", "ReverseDiffuse"], label="Inference Mode"), # Mode selection
134
+ gr.Slider(0.1, 20, value=1, step=0.1, label="Step Size"), # Step size
135
+ gr.Slider(0.1, 40, value=0.5, step=0.1, label="Epsilon (eps)"), # Epsilon constraint
136
+ gr.Slider(0.0, 1.0, value=0.5, step=0.1, label="Noise Ratio"), # Noise ratio
137
+ gr.Slider(1, 1000, value=100, step=1, label="Number of Iterations"), # Number of iterations
138
  ],
139
  outputs=[
140
  gr.Image(label="Processed Image"), # Processed image
141
  gr.Image(label="Gradient Visualization") # Gradient visualization
142
  ],
143
+ title="Generative Inference",
144
+ description="Perform generative inference on input images using adjustable parameters such as step size, epsilon, noise ratio, and number of iterations."
145
  )
146
 
147