-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathloss.py
57 lines (49 loc) · 2.06 KB
/
loss.py
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
import torch
import torch.nn as nn
class NutritionLoss(nn.Module):
"""Custom Loss Function for Food Nutrition Estimation."""
def __init__(self, num_tasks=5, epsilon=1e-6):
super(NutritionLoss, self).__init__()
self.num_tasks = num_tasks
self.epsilon = epsilon # Small constant to avoid division by zero
def forward(self, predictions, targets):
"""
Args:
predictions: Tensor of shape (batch_size, num_tasks), model outputs.
targets: Tensor of shape (batch_size, num_tasks), ground truth values.
Returns:
loss: Scalar, total normalized MAE loss.
"""
# Calculate per-task normalized MAE
task_losses = []
for i in range(self.num_tasks):
# Select predictions and targets for the current task
pred_task = predictions[:, i]
target_task = targets[:, i]
# Mean value of the target to normalize MAE
target_mean = torch.mean(target_task) + self.epsilon # Avoid division by zero
# Normalized MAE for the current task
task_loss = torch.mean(torch.abs(pred_task - target_task) / target_mean)
task_losses.append(task_loss)
# Average loss across all tasks
total_loss = torch.mean(torch.stack(task_losses))
return total_loss
# Example Usage
if __name__ == "__main__":
# Dummy Predictions and Targets (Batch size = 4, Number of Tasks = 5)
predictions = torch.tensor([
[100.0, 200.0, 10.0, 20.0, 15.0],
[120.0, 210.0, 11.0, 18.0, 16.0],
[130.0, 220.0, 12.0, 19.0, 14.0],
[110.0, 205.0, 10.5, 21.0, 15.5]
], dtype=torch.float32)
targets = torch.tensor([
[110.0, 195.0, 12.0, 22.0, 16.0],
[115.0, 200.0, 11.5, 20.0, 15.5],
[125.0, 215.0, 13.0, 18.5, 14.5],
[112.0, 198.0, 10.8, 20.5, 15.8]
], dtype=torch.float32)
# Instantiate Loss Function
loss_fn = NutritionLoss(num_tasks=5)
loss = loss_fn(predictions, targets)
print(f"Loss: {loss.item()}")