Saltar al contenido

¿Qué son las clases C para una función de pérdida NLLLoss en Pytorch?

Después de investigar con expertos en el tema, programadores de varias ramas y profesores dimos con la respuesta a la pregunta y la compartimos en esta publicación.

Solución:

Estoy de acuerdo contigo en que la documentación para nn.NLLLoss() está lejos de ser ideal, pero creo que podemos aclarar su problema aquí, en primer lugar, al aclarar que “clase” se usa a menudo como sinónimo de “categoría” en un contexto de aprendizaje automático.

Por lo tanto, cuando PyTorch habla de C clases, en realidad se refiere a la número de categorías distintas en el que está tratando de entrenar su red. Entonces, en el ejemplo clásico de una red neuronal categórica que intenta clasificar entre “gatos” y “perros”, C = 2ya que es un gato o un perro.

Específicamente para este problema de clasificación, también se cumple que solo tenemos un solo valor de verdad sobre el array de nuestras categorías (una imagen no puede representar a la vez un gato Y un perro, sino siempre uno u otro), por lo que podemos indicar convenientemente la categoría correspondiente de una imagen por su índice (digamos que 0 indicaría un gato, y 1 un perro). Ahora, simplemente podemos comparar la salida de la red con la categoría que queremos.

PERO, para que esto funcione, también debemos tener claro a qué se refieren estos valores de pérdida (en nuestra salida de red), ya que nuestra red generalmente hará predicciones a través de un softmax sobre diferentes neuronas de salida, lo que significa que generalmente tenemos más de un solo valor. Afortunadamente, PyTorch nn.NLLLoss hace esto automáticamente por usted.

Su ejemplo anterior con el LogSoftmax de hecho, solo produce un único valor de salida, que es un caso crítico para este ejemplo. De esta manera, básicamente solo tiene una indicación de si algo existe o no existe, pero no tiene mucho sentido usarlo en un ejemplo de clasificación, más aún en un caso de regresión (pero eso requeriría un totalmente diferente función de pérdida para empezar).

Por último, pero no menos importante, también debe considerar el hecho de que generalmente tenemos tensores 2D como entrada, ya que el procesamiento por lotes (el cálculo simultáneo de múltiples muestras) generalmente se considera un paso necesario para igualar el rendimiento. Incluso si elige un tamaño de lote de 1, esto aún requiere que sus entradas sean de dimensión (batch_size, input_dimensions)y en consecuencia sus tensores de forma de salida (batch_size, number_of_categories).

Esto explica por qué la mayoría de los ejemplos que encuentra en línea están realizando el LogSoftmax() terminado dim=1ya que este es el “eje de distribución”, y no el eje de lote (que sería dim=0).

Si simplemente desea solucionar su problema, la forma más fácil sería extender su tensor aleatorio en una dimensión adicional (torch.randn([1, 5], requires_grad=True)), y luego comparar por un solo valor en su tensor de salida (print(loss(output, torch.tensor([1])))

Básicamente te estás perdiendo un concepto de batch.

Para resumir, cada entrada a pérdida (y la que pasa a través de la red) requiere batch dimensión (es decir, cuántas muestras se utilizan).

Desglosándolo, paso a paso:

Tu ejemplo vs documentación

Cada paso será cada paso comparado para hacerlo más claro (documentación en la parte superior, su ejemplo a continuación)

Entradas

input = torch.randn(3, 5, requires_grad=True)
input = torch.randn(5, requires_grad=True)

En el primer caso (docs), ingrese con 5 se crean características y 3 se utilizan muestras. En tu caso solo hay batch dimensión (5 muestras), no tiene características que son necesarios. Si quería tener una muestra con 5 características que debe hacer:

input = torch.randn(5, requires_grad=True)

LogSoftmax

LogSoftmax se realiza a través de la dimensión de características, lo está haciendo a través del lote.

m = nn.LogSoftmax(dim=1) # aplicar sobre características m = nn.LogSoftmax(dim=0) # aplicar sobre lote

Por lo general, no tiene sentido para esta operación, ya que las muestras son independientes entre sí.

Objetivos

Como se trata de una clasificación multiclase y cada elemento en el vector representa una muestra, se pueden pasar tantos números como se desee (siempre y cuando sea menor que el número de características, en el caso del ejemplo de documentación, es 5por lo tanto [0-4] está bien ).

train = torch.tensor([1, 0, 4])
train = torch.tensor([1, 0, 0])

Supongo que también querías pasar un vector caliente como objetivo. PyTorch no funciona de esa manera ya que es memoria ineficiente (¿Por qué almacenar todo como codificado en caliente cuando puede identificar exactamente la clase, en su caso sería 0).

Solo las salidas de la red neuronal están codificadas en caliente para retropropagar el error a través de todos los nodos de salida, no es necesario para los objetivos.

Final

no deberías usar torch.nn.LogSoftmaxen absoluto para esta tarea Solo usa torch.nn.Linear como última capa y uso torch.nn.CrossEntropyLoss con tus objetivos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *