-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathablation_study.py
More file actions
128 lines (104 loc) · 5.13 KB
/
Copy pathablation_study.py
File metadata and controls
128 lines (104 loc) · 5.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import torch
import matplotlib.pyplot as plt
import numpy as np
from tqdm import tqdm
from models.diffusion import Model as DiffusionModel
from utils.metrics import calculate_fid
class DiffSearchAblation:
def __init__(self, model, dataloader, lambda_values=[0, 0.2, 0.4, 0.6, 0.8, 1.0],
eta_values=[0, 0.5, 1.0, 1.5, 2.5]):
self.model = model
self.dataloader = dataloader
self.lambda_values = lambda_values
self.eta_values = eta_values
self.importance_weights_history = {}
self.fid_scores = {}
def initialize_architecture_weights(self):
# Initialize weights for different components
self.arch_weights = {
'resblocks': torch.ones(self.model.num_res_blocks, requires_grad=True),
'attention': torch.ones(self.model.num_attention_layers, requires_grad=True),
'timestep_embed': torch.ones(1, requires_grad=True)
}
return self.arch_weights
def importance_regularization(self, weights, eta):
# L1 regularization for sparsity
return eta * torch.sum(torch.abs(weights))
def train_with_differentiable_search(self, lambda_val, eta_val, epochs=10):
arch_weights = self.initialize_architecture_weights()
optimizer = torch.optim.Adam([
{'params': self.model.parameters(), 'lr': 1e-4},
{'params': list(arch_weights.values()), 'lr': 5e-3}
])
weights_history = {k: [] for k in arch_weights.keys()}
for epoch in range(epochs):
for batch in tqdm(self.dataloader):
optimizer.zero_grad()
# Apply architecture weights to corresponding components
self.model.apply_arch_weights(arch_weights)
# Regular model loss
loss = self.model.compute_loss(batch)
# Add importance regularization
reg_loss = sum(self.importance_regularization(w, eta_val) for w in arch_weights.values())
total_loss = loss + lambda_val * reg_loss
total_loss.backward()
optimizer.step()
# Normalize weights after update
for k, w in arch_weights.items():
arch_weights[k] = torch.softmax(w, dim=0)
# Store weights history
for k, w in arch_weights.items():
weights_history[k].append(w.detach().cpu().numpy())
# Calculate FID score
fid = calculate_fid(self.model, self.dataloader)
return weights_history, fid
def run_ablation(self):
for lambda_val in self.lambda_values:
self.fid_scores[lambda_val] = {}
for eta_val in self.eta_values:
print(f"Running with λ={lambda_val}, η={eta_val}")
weights_history, fid = self.train_with_differentiable_search(lambda_val, eta_val)
key = f"lambda_{lambda_val}_eta_{eta_val}"
self.importance_weights_history[key] = weights_history
self.fid_scores[lambda_val][eta_val] = fid
def visualize_weights_evolution(self):
plt.figure(figsize=(12, 5))
# Plot evolution of weights (similar to Figure 5.5a)
plt.subplot(1, 2, 1)
for i, k in enumerate(['resblocks', 'attention', 'timestep_embed']):
weights = self.importance_weights_history['lambda_0.6_eta_1.0'][k]
if len(weights[0].shape) > 0: # For multi-dimensional weights
for j in range(len(weights[0])):
plt.plot(self.lambda_values, [w[j] for w in weights],
marker='o', label=f"{k}-{j}")
else:
plt.plot(self.lambda_values, weights, marker='o', label=k)
plt.title('Evolution of Branch Importance Weights')
plt.xlabel('Iteration')
plt.ylabel('Importance Weights')
plt.grid(True)
plt.legend()
# Plot FID scores (similar to Figure 5.5b)
plt.subplot(1, 2, 2)
for eta in self.eta_values:
fids = [self.fid_scores[lambda_val][eta] for lambda_val in self.lambda_values]
plt.plot(self.lambda_values, fids, marker='o', label=f"η={eta}")
plt.title('Generation Quality')
plt.xlabel('λ')
plt.ylabel('FID')
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.savefig('importance_weights_ablation.png')
plt.show()
def analyze_components_importance(self):
# Analyze importance across denoising stages
key = f"lambda_0.6_eta_1.0" # Use the best hyperparameters
final_weights = {k: w[-1] for k, w in self.importance_weights_history[key].items()}
# This would depend on your model's specific architecture
print("Component Importance Analysis:")
for k, w in final_weights.items():
if len(w.shape) > 0:
print(f"{k}: {w}")
else:
print(f"{k}: {float(w)}")