fbientrigo / grav_lensing

A Python toy model for gravitational lensing with educative means
0 stars 0 forks source link

Permitir el uso de modelos siameses #5

Closed fbientrigo closed 2 months ago

fbientrigo commented 2 months ago

Para permitir varias funciones de perida que no se sobrepongan unas con otras, es necesario hacer dos cosas Una de ellas es mapear los datos de training para que tengan los nombres correctos de la funcion de perdida y la otra es la de crear modelos que tengan operaciones de identidad para copiar las salidas con distintos errores pero sin ingresar funciones de activación extras.

Descripción del Problema

Cuando trabajas con un modelo Keras que tiene múltiples salidas, cada salida generalmente necesita ser mapeada a un objetivo correspondiente (por ejemplo, y_true). Sin embargo, si estás utilizando un DataGenerator o tf.data.Dataset que solo proporciona un único y_true, mapear esta única salida a las múltiples salidas del modelo puede ser un desafío.

El problema surge cuando intentas compilar y entrenar un modelo con múltiples salidas utilizando un único y_true, ya que TensorFlow espera que la forma y la estructura del y_true coincidan con cada salida del modelo.

Solución Propuesta

Para resolver este problema, puedes mapear el único y_true a cada una de las salidas del modelo creando una función de mapeo personalizada. Esta función se puede aplicar a tu dataset para asegurar que el único y_true se duplique y se alinee correctamente con cada salida del modelo.

Definir una Función de Mapeo:

La función map_to_multiple_outputs tomará los datos de entrada X, la salida y_true, y una lista de nombres de salidas (output_names). Devolverá la entrada original X y un diccionario donde cada clave corresponde a uno de los nombres de las salidas, todos mapeados al mismo y_true.

def map_to_multiple_outputs(X, y, output_names):
    outputs = {name: y for name in output_names}  # Mapea y_true a todos los nombres de salida
    return X, outputs

# aplicarla antes del training, validacion o cualquier operacion
output_names = ['output_image', 'output_mae', 'output_mse', 'output_logcosh', 'output_dice']
train_dataset = train_dataset.map(lambda X, y: map_to_multiple_outputs(X, y, output_names))

Luego en el modelo esto se var[a como

model.compile(optimizer='adam', 
              loss={'output_image': 'mae', 
                    'output_mae': 'mae',
                    'output_mse': 'mse',
                    'output_logcosh': 'logcosh',
                    'output_dice': 'binary_crossentropy'},
              loss_weights={'output_image': 1.0, 
                            'output_mae': 1.0,
                            'output_mse': 1.0,
                            'output_logcosh': 1.0,
                            'output_dice': 1.0})
# ...
# Idealmetne debe ser capaz de correr
model.fit(train_dataset, epochs=1)