Skip to content
This repository was archived by the owner on Oct 2, 2025. It is now read-only.

Commit 6e0f134

Browse files
committed
Bug fixes
1 parent c95a405 commit 6e0f134

3 files changed

Lines changed: 66 additions & 51 deletions

File tree

classification_pipeline.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def construct_classifier(X: torch.tensor, t: torch.tensor, k: int, model_config:
4141
training_config.set_logits_loss(logits_loss)
4242

4343
# Create a temporary target vector where everything equal to i is 1 and the rest are 0
44-
temp_target = torch.tensor([1 if x == k else 0 for x in t])
44+
temp_target = t
4545

4646
# Training loop
4747
model, metrics = train_model(model, X, temp_target, training_config)
@@ -141,8 +141,12 @@ def train_model(model: nn.Module, X: torch.tensor, t: torch.tensor, training_con
141141
train_accuracies.append(accuracy(outputs, labels, logits_loss))
142142
val_accuracies.append(accuracy(model(X_val), t_val, logits_loss))
143143

144-
print("Epoch ", epoch, " Train Loss: ", train_losses[-1], " Train Accuracy: ", train_accuracies[-1],
145-
" Val Loss: ", val_losses[-1], " Val Accuracy: ", val_accuracies[-1])
144+
full_train_loss = criterion(model(X_train), t_train).item()
145+
full_val_loss = criterion(model(X_val), t_val).item()
146+
full_train_accuracy = accuracy(model(X_train), t_train, logits_loss)
147+
full_val_accuracy = accuracy(model(X_val), t_val, logits_loss)
148+
print("Epoch ", epoch, " Train Loss: ", full_train_loss, " Train Accuracy: ", full_train_accuracy,
149+
" Val Loss: ", full_val_loss, " Val Accuracy: ", full_val_accuracy)
146150

147151
metrics = {
148152
"train_losses": train_losses,

main.py

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -32,58 +32,60 @@
3232

3333
# Construct the set of unique labels
3434
targets = [x.item() for x in labels]
35-
unique_labels = set(targets)
35+
unique_labels = list(set(targets))
36+
37+
model_format = {
38+
"num_layers": 4,
39+
"layers": [
40+
{
41+
"layer_type": "Linear_LRP",
42+
"in_dim": 50,
43+
"out_dim": 64,
44+
"act": "ReLU",
45+
"dropout": 0.1,
46+
"batch_norm": False
47+
},
48+
{
49+
"layer_type": "Linear_LRP",
50+
"in_dim": 64,
51+
"out_dim": 128,
52+
"act": "ReLU",
53+
"dropout": 0.0,
54+
"batch_norm": False
55+
},
56+
{
57+
"layer_type": "Linear_LRP",
58+
"in_dim": 128,
59+
"out_dim": 32,
60+
"act": "ReLU",
61+
"dropout": 0.0,
62+
"batch_norm": False
63+
},
64+
{
65+
"layer_type": "Linear_LRP",
66+
"in_dim": 32,
67+
"out_dim": 1,
68+
"act": "Sigmoid",
69+
"dropout": 0.0,
70+
"batch_norm": False
71+
},
72+
]
73+
}
74+
75+
model_config = ModelConfig(model_format)
3676

3777
# Check if the models have been saved
3878
if os.path.exists("models.pkl"):
3979
models = pickle.load(open("models.pkl", "rb"))
4080
print("Models loaded")
4181
else:
4282
print("Models not found")
43-
model_format = {
44-
"num_layers": 4,
45-
"layers": [
46-
{
47-
"layer_type": "Linear_LRP",
48-
"in_dim": 50,
49-
"out_dim": 64,
50-
"act": "ReLU",
51-
"dropout": 0.1,
52-
"batch_norm": False
53-
},
54-
{
55-
"layer_type": "Linear_LRP",
56-
"in_dim": 64,
57-
"out_dim": 128,
58-
"act": "ReLU",
59-
"dropout": 0.0,
60-
"batch_norm": False
61-
},
62-
{
63-
"layer_type": "Linear_LRP",
64-
"in_dim": 128,
65-
"out_dim": 32,
66-
"act": "ReLU",
67-
"dropout": 0.0,
68-
"batch_norm": False
69-
},
70-
{
71-
"layer_type": "Linear_LRP",
72-
"in_dim": 32,
73-
"out_dim": 1,
74-
"act": "Sigmoid",
75-
"dropout": 0.0,
76-
"batch_norm": False
77-
},
78-
]
79-
}
80-
81-
model_config = ModelConfig(model_format)
8283

8384
training_config = TrainingConfig(0.01, 1, batch_size)
8485

8586
models = {}
8687

88+
# k = unique_labels[0]
8789
for k in unique_labels:
8890
print("Training model for class", k)
8991
# Create a copy of X
@@ -107,23 +109,29 @@
107109
explanations = pickle.load(open("explanations.pkl", "rb"))
108110
print("Explanations loaded")
109111
else:
112+
X.requires_grad = True
113+
110114
explanations = {}
111115

116+
if model_config.layers[-1]["act"] == "Sigmoid":
117+
criterion = nn.BCELoss()
118+
else:
119+
criterion = nn.BCEWithLogitsLoss()
120+
121+
# k = unique_labels[0]
112122
for k in unique_labels:
113123
print("Explaining model for class", k)
114124
model = models[k]
115125

116126
predictions = model.forward(X, explain=True, rule="alpha2beta1")
117127

118-
predictions = predictions[torch.arange(batch_size), predictions.max(1)[1]] # Choose maximizing output neuron
119-
120-
predictions = predictions.sum()
128+
pred = predictions.sum()
121129

122-
predictions.backward()
130+
loss = criterion(predictions, torch.reshape(torch.tensor([1 if x == k else 0 for x in labels]), (-1, 1)).float())
123131

124-
explanation = X.grad
132+
pred.backward()
125133

126-
explanations[k] = explanation
134+
explanations[k] = X.grad
127135

128136
# Save the explanations
129137
pickle.dump(explanations, open("explanations.pkl", "wb"))

model_config.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,15 @@ def __init__(self, modelConfig, lrp_bool=False):
116116

117117
self.layers = nn.ModuleList(self.layers)
118118

119-
def forward(self, x):
119+
def forward(self, x, explain=False, rule="epsilon", pattern=None):
120120
# assume X is already in the correct shape and all that
121121
out = x
122122

123123
for layer in self.layers:
124-
out = layer(out)
124+
if explain:
125+
out = layer.forward(out, explain=explain, rule=rule, pattern=pattern)
126+
else:
127+
out = layer(out)
125128

126129
return out
127130

0 commit comments

Comments
 (0)