by Anonymous » 21 Aug 2025, 08:21
Ich arbeite an der Bedeutung von Neuron für ANNs (in einer Klassifizierungsumgebung). Eine einfache Grundlinie ist die partielle Ableitung der Modellausgabe für die richtige Klasse in Bezug auf die gegebene Voraktivierung von Neuronen. Mein Ziel ist es, wichtige Neuronen für eine Gruppe verwandter Eingaben zu erhalten. Daher habe ich derzeit nur die Bedeutung der Samples in jedem Cluster gemessen, um die wichtigsten Bedeutung pro Cluster zu erhalten. Das
Problem ist, dass ich im Durchschnitt sehr kleine Teilableitungen für jeden Neuron bekomme und dass die daraus resultierenden Wichtigkeitswerte in dem Sinne nicht gut sind, dass die Leistung des Modells nicht mehr als im Vergleich zum Entfernen von Neuronen zufällig abnimmt, wenn Sie die wichtigsten Neuronen aus dem Modell entfernen. Andere Methoden, wie beispielsweise die Verwendung der Voraktivitäten als Wichtigkeitsbewertungen, funktionieren in dieser Hinsicht besser. Experimente anderer Autoren legen jedoch nahe, dass der teilweise Derivatbasierte Ansatz in vielen Umgebungen einigermaßen gut funktionieren sollte. Ich vermute also, dass ein Fehler in meinem Code enthält. < /P>
Mein aktuelles Setup ist wie folgt. Ich weiß, der Code ist nicht optimal aus einer Performance -POV - er ist mit Klarheit geschrieben. meine Frage ist, wenn der Code einen Fehler zur Berechnung der Teilleitungen in Bezug auf die Voraktivitäten der Neuronen gibt. Somit sollte das letzte Argument im Haken das partielle Abgang in Bezug auf die Voraktivierung sein. < /P>
Code: Select all
class AttributionMethod(ABC):
def __init__(self, model: nn.Module, data_loader: Dict[int, DataLoader]):
self.model = model
self.data_loader = data_loader
if self.model is not None:
self.model.eval()
@abstractmethod
def attribute(self, layer: Module, latent_class: int) -> np.ndarray:
pass
class GradientAttribution(AttributionMethod):
def attribute(self, layer: Module, latent_class: int) -> np.ndarray:
# Calculates the importance scores of the neurons in the provided layer for the provided cluster
device = next(self.model.parameters()).device
inputs, targets = next(iter(self.data_loader[latent_class]))
inputs = inputs.to(device)
targets = targets.to(device)
inputs.requires_grad = True
attributions = []
def hook_fn(module, grad_input, grad_output):
attributions.append(grad_output[0].detach().cpu())
handle = layer.register_full_backward_hook(hook_fn)
# Forward and backward pass
for i in range(len(inputs)):
input_i = inputs[i].unsqueeze(0) # Add batch dimension
output = self.model(input_i).squeeze()
target_i = targets[i].item()
output[target_i].backward()
# We do not need to zero the grads since only the model param grads are accumulated
handle.remove()
# Concatenate over batch and average per neuron
grads_tensor = torch.cat(attributions, dim=0)
grads_per_neuron = grads_tensor.mean(dim=0).numpy()
return grads_per_neuron
Ich arbeite an der Bedeutung von Neuron für ANNs (in einer Klassifizierungsumgebung). Eine einfache Grundlinie ist die partielle Ableitung der Modellausgabe für die richtige Klasse in Bezug auf die gegebene Voraktivierung von Neuronen. Mein Ziel ist es, wichtige Neuronen für eine Gruppe verwandter Eingaben zu erhalten. Daher habe ich derzeit nur die Bedeutung der Samples in jedem Cluster gemessen, um die wichtigsten Bedeutung pro Cluster zu erhalten. Das [url=viewtopic.php?t=26065]Problem[/url] ist, dass ich im Durchschnitt sehr kleine Teilableitungen für jeden Neuron bekomme und dass die daraus resultierenden Wichtigkeitswerte in dem Sinne nicht gut sind, dass die Leistung des Modells nicht mehr als im Vergleich zum Entfernen von Neuronen zufällig abnimmt, wenn Sie die wichtigsten Neuronen aus dem Modell entfernen. Andere Methoden, wie beispielsweise die Verwendung der Voraktivitäten als Wichtigkeitsbewertungen, funktionieren in dieser Hinsicht besser. Experimente anderer Autoren legen jedoch nahe, dass der teilweise Derivatbasierte Ansatz in vielen Umgebungen einigermaßen gut funktionieren sollte. Ich vermute also, dass ein Fehler in meinem Code enthält. < /P>
Mein aktuelles Setup ist wie folgt. Ich weiß, der Code ist nicht optimal aus einer Performance -POV - er ist mit Klarheit geschrieben. meine Frage ist, wenn der Code einen Fehler zur Berechnung der Teilleitungen in Bezug auf die Voraktivitäten der Neuronen gibt. Somit sollte das letzte Argument im Haken das partielle Abgang in Bezug auf die Voraktivierung sein. < /P>
[code]class AttributionMethod(ABC):
def __init__(self, model: nn.Module, data_loader: Dict[int, DataLoader]):
self.model = model
self.data_loader = data_loader
if self.model is not None:
self.model.eval()
@abstractmethod
def attribute(self, layer: Module, latent_class: int) -> np.ndarray:
pass
class GradientAttribution(AttributionMethod):
def attribute(self, layer: Module, latent_class: int) -> np.ndarray:
# Calculates the importance scores of the neurons in the provided layer for the provided cluster
device = next(self.model.parameters()).device
inputs, targets = next(iter(self.data_loader[latent_class]))
inputs = inputs.to(device)
targets = targets.to(device)
inputs.requires_grad = True
attributions = []
def hook_fn(module, grad_input, grad_output):
attributions.append(grad_output[0].detach().cpu())
handle = layer.register_full_backward_hook(hook_fn)
# Forward and backward pass
for i in range(len(inputs)):
input_i = inputs[i].unsqueeze(0) # Add batch dimension
output = self.model(input_i).squeeze()
target_i = targets[i].item()
output[target_i].backward()
# We do not need to zero the grads since only the model param grads are accumulated
handle.remove()
# Concatenate over batch and average per neuron
grads_tensor = torch.cat(attributions, dim=0)
grads_per_neuron = grads_tensor.mean(dim=0).numpy()
return grads_per_neuron
[/code]