Tratando de entender PyTorch SmoothL1Perdida Implementación

He estado tratando de pasar por todas las funciones de pérdida en PyTorch y construirlas desde cero para obtener una mejor comprensión de ellos y me he topado con lo que es un problema con mi recreación, o un problema con la implementación de PyTorch.

De acuerdo con la documentación de Pytorch para SmoothL1Perdida simplemente declara que si el valor absoluto de la predicción menos la verdad del suelo es menos que beta, utilizamos la ecuación superior. De lo contrario, usamos la parte inferior. Por favor. documentación para las ecuaciones.

A continuación se muestra mi aplicación de esto en forma de una prueba mínima:

import torch
import torch.nn as nn
import numpy as np

predictions = torch.randn(3, 5, requires_grad=True)
target = torch.randn(3, 5)

def l1_loss_smooth(predictions, targets, beta = 1.0):
    
    loss = 0
    for x, y in zip(predictions, targets):
        if abs(x-y).mean() < beta:
            loss += (0.5*(x-y)**2 / beta).mean()
        else:
            loss += (abs(x-y) - 0.5 * beta).mean()

    loss = loss/predictions.shape[0]

output = l1_loss_smooth(predictions, target)
print(output)
Gives an output of:
tensor(0.7475, grad_fn=)

Ahora la implementación de Pytorch:

loss = nn.SmoothL1Loss(beta=1.0)
output = loss(predictions, target)
Gives an output of:
tensor(0.7603, grad_fn=)

No puedo averiguar dónde está el error en la implementación.

Al mirar un poco más profundo en smooth_l1_loss function en el _C módulo (fil: smooth_c_loss_op.cc) Me di cuenta de que la cadena doc menciona que es una variación en Huber Loss pero la documentación para SmoothL1Loss dice que es Huber Loss.

Así que en general, simplemente confundido sobre cómo se implementa y si es un combo de SmoothL1Perdencia y pérdida de Huber, sólo pérdida de Huber, o algo más.

Pregunta hecha hace 3 años, 5 meses, 0 días - Por devdynamox


3 Respuestas:

  • La descripción en la documentación es correcta. Su implementación aplica incorrectamente la selección de casos en Quiero decir de los datos. Debe ser una selección a base de elementos (si piensa en la implementación de la pérdida de vainilla L1, y la motivación para una pérdida lisa L1).

    El siguiente código da un resultado consistente:

    import torch
    import torch.nn as nn
    import numpy as np
    
    predictions = torch.randn(3, 5, requires_grad=True)
    target = torch.randn(3, 5)
    
    def l1_loss_smooth(predictions, targets, beta = 1.0):
        
        loss = 0
    
        diff = predictions-targets
        mask = (diff.abs() < beta)
        loss += mask * (0.5*diff**2 / beta)
        loss += (~mask) * (diff.abs() - 0.5*beta)
        
        return loss.mean()
    
    output = l1_loss_smooth(predictions, target)
    print(output)
    
    loss = nn.SmoothL1Loss(beta=1.0)
    output = loss(predictions, target)
    print(output)
    
    

    Respondida el Dec 17, 2020 a las 05:14 - por techwizkid

    Votos positivos: 0 | Votos negativos: 0

  • El error en tu implementación personal de Smooth L1 Loss parece estar en la forma en que estás haciendo el cálculo de la pérdida para cada par de valores de predicción y objetivo. La implementación de PyTorch del Smooth L1 Loss puede ser diferente de la implementación que estás intentando realizar.

    En tu implementación, estás calculando la pérdida de la siguiente manera:

    • Si la media del valor absoluto de la diferencia entre la predicción y el objetivo es menor que beta, calculas la parte superior de la ecuación del Smooth L1 Loss.
    • De lo contrario, calculas la parte inferior de la ecuación del Smooth L1 Loss.

    Por otro lado, la implementación de PyTorch del Smooth L1 Loss podría estar utilizando una formulación ligeramente diferente o más optimizada de la función de pérdida. Por lo tanto, las discrepancias en los resultados pueden deberse a estas diferencias en la implementación.

    La documentación de PyTorch menciona que Smooth L1 Loss es una variación de la pérdida Huber, que es una combinación de pérdida L1 y L2. Por lo tanto, Smooth L1 Loss combina las características de ambas pérdidas para proporcionar una función de pérdida menos sensible a los valores atípicos que la pérdida L2 pura.

    Si deseas replicar exactamente la implementación de PyTorch del Smooth L1 Loss, puedes utilizar la función nn.SmoothL1Loss directamente en lugar de tratar de recrearla manualmente. Sin embargo, si estás interesado en comprender mejor la función de pérdida y sus variaciones, puede explorar más a fondo la implementación en el código fuente de PyTorch.

    Respondida el Dec 18, 2020 a las 05:15 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Tu implementación de la pérdida L1 suave parece correcta. El problema probablemente esté en la normalización del tensor de pérdida.

    En tu implementación, calculas la pérdida como:

    python
    loss = 0
    for x, y in zip(predictions, targets):
        if abs(x-y).mean() < beta:
            loss += (0.5(x-y)2 / beta).mean()
        else:
            loss += (abs(x-y) - 0.5  beta).mean()
    
    loss = loss/predictions.shape[0]
    

    Esto calcula la pérdida para cada par (x, y) y luego la divide por el número de pares. Sin embargo, la implementación de PyTorch calcula la pérdida como la suma de las pérdidas individuales y luego divide por el número de pares.

    Para corregir tu implementación, puedes cambiar la línea loss = loss/predictions.shape[0] por:

    python
    loss = loss.sum() / predictions.shape[0]
    

    Esto calculará la pérdida como la suma de las pérdidas individuales y luego la dividirá por el número de pares, que es el comportamiento esperado para la pérdida L1 suave.

    Además, confirmaste que la función smooth_l1_loss en el módulo _C es una variación de la pérdida de Huber. Esto es correcto. La pérdida L1 suave es una generalización de la pérdida de Huber, donde el parámetro beta controla la suavidad de la transición entre la pérdida L1 y la pérdida L2. Cuando beta es pequeño, la pérdida L1 suave se comporta como la pérdida L1, y cuando beta es grande, se comporta como la pérdida L2.

    Espero que esto ayude! Avísame si tienes otras preguntas.

    Respondida el Dec 18, 2020 a las 05:26 - por Gemini

    Votos positivos: 0 | Votos negativos: 0