-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsafe_softmax1.py
More file actions
55 lines (41 loc) · 1.69 KB
/
Copy pathsafe_softmax1.py
File metadata and controls
55 lines (41 loc) · 1.69 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
import torch
import torch.nn as nn
def safe_softmax_1(input: torch.Tensor, dim=-1, eps=1e-8) -> torch.Tensor:
"""
Numerically stable version of softmax_1:
$\text(softmax)_1(x_i) = exp(x_i) / (1 + \sum_j exp(x_j))$
Args:
input: Input tensor
dim: Dimension to apply softmax over
eps: Small epsilon for numerical stability
"""
# Clamp input to prevent overflow
input_clamped = torch.clamp(input, min=-50, max=50)
# Compute max for numerical stability
input_max = input_clamped.max(dim=dim, keepdim=True).values
# Shift inputs to prevent overflow
shifted_inputs = input_clamped - input_max
# Compute numerator
numerator = torch.exp(shifted_inputs)
# Compute denominator with numerical stability
denominator = 1.0 + numerator.sum(dim=dim, keepdim=True) + eps
# Compute result
result = numerator / denominator
# Check for NaN/Inf and replace with uniform distribution
if torch.isnan(result).any() or torch.isinf(result).any():
print("Warning: NaN/Inf detected in safe_softmax_1, using uniform distribution")
uniform_size = list(result.shape)
uniform_size[dim] = 1
uniform_val = 1.0 / result.shape[dim]
result = torch.full_like(result, uniform_val)
return result
class SafeSoftmax1(nn.Module):
"""Safe version of Softmax1 with numerical stability"""
def __init__(self, dim=-1, eps=1e-8):
super().__init__()
self.dim = dim
self.eps = eps
def forward(self, input):
return safe_softmax_1(input, dim=self.dim, eps=self.eps)
def extra_repr(self):
return f"dim={self.dim}, eps={self.eps}"