import torch
import torch.nn as nn
import torch.nn.functional as F


class Model(nn.Module):
    def __init__(self, epsilon=1.0):
        super().__init__()
        self.epsilon = epsilon
        self.ce_loss = nn.CrossEntropyLoss(reduction='none')

    def forward(self, logits: torch.Tensor, labels: torch.Tensor) -> torch.Tensor:
        l_ce = self.ce_loss(logits, labels)

        p = F.softmax(logits, dim=-1)

        p_t = p.gather(1, labels.unsqueeze(-1)).squeeze(-1)

        poly_loss = l_ce + self.epsilon * (1.0 - p_t)

        return poly_loss.mean()


batch_size = 128
feature_dim = 10


def get_inputs():
    logits = torch.randn(batch_size, feature_dim, dtype=torch.float32)
    labels = torch.randint(0, feature_dim, (batch_size,), dtype=torch.long)
    return [logits, labels]


def get_init_inputs():
    return [1.0]