@@ -35,31 +35,36 @@ def assign_labels(
3535
3636 # Sum over time dimension (spike ordering doesn't matter).
3737 spikes = spikes .sum (1 )
38-
38+
3939 for i in range (n_labels ):
40- # Create mask (faster and allows future steps to stay on GPU) .
41- mask = ( labels == i )
40+ # Create mask.
41+ mask = labels == i
4242 # Count the number of samples with this label.
4343 n_labeled = mask .sum ().float ()
4444
4545 if n_labeled > 0 :
46- # Get indices of samples with this label (masking is faster and stays on the GPU) .
46+ # Get indices of samples with this label.
4747 label_sum = spikes [mask ].sum (0 )
4848 # Update rates.
4949 rates [:, i ] = alpha * rates [:, i ] + (label_sum / n_labeled )
5050
51- # Compute proportions (and use 'torch.where' to avoid NaN bug) .
51+ # Compute proportions of spike activity per class .
5252 total_activity = rates .sum (1 , keepdim = True )
53- proportions = torch .where (total_activity > 0 , rates / total_activity , torch .zeros_like (rates ))
53+ proportions = torch .where (
54+ total_activity > 0 , rates / total_activity , torch .zeros_like (rates )
55+ )
56+
57+ # Noise for random tie breaking.
58+ eps = 1e-6 # Small enough not to distort real decisions
59+ noise = eps * torch .randn_like (proportions )
5460
5561 # Neuron assignments are the labels they fire most for.
56- max_vals , assignments = torch .max (proportions , 1 )
57-
58- # Set unassigned (silent) neurons to -1 instead of defaulting to 0.
59- assignments [max_vals == 0 ] = - 1
62+ assignments = torch .argmax (proportions + noise , dim = 1 )
6063
6164 # Neurons that never fired have no class preference; mark them with -1 so
62- # they don't contribute a (biased) vote for class 0 in downstream schemes.
65+ # they are masked out of downstream voting (issue #736: silent neurons must
66+ # not default to a vote for class 0). Downstream schemes only match
67+ # ``assignments == i`` for i >= 0, so -1 neurons are excluded.
6368 assignments [rates .sum (1 ) == 0 ] = - 1
6469
6570 return assignments , proportions , rates
0 commit comments