Introducción e Implementación de Redes Siamesas

Introducción y Implementación de Redes Siamesas

Introducción

Las redes siamesas ofrecen un enfoque intrigante para la clasificación, permitiendo la categorización precisa de imágenes basada en solo un ejemplo. Estas redes emplean un concepto llamado Pérdida Contrastiva para medir la similitud entre pares de imágenes dentro de un conjunto de datos. A diferencia de los métodos tradicionales que se centran en descifrar el contenido de la imagen, las redes siamesas se concentran en comprender las variaciones y similitudes entre las imágenes. Este método de aprendizaje distintivo contribuye a su resistencia en escenarios de datos limitados, mejorando el rendimiento incluso sin conocimientos específicos del dominio.

Este artículo se sumerge en el fascinante mundo de la Verificación de Firmas a través de las redes siamesas. Te guiaremos en la creación de un modelo funcional utilizando PyTorch, brindando información y pasos prácticos de implementación en el camino.

Objetivos de Aprendizaje

  • Comprender el concepto de redes siamesas y su arquitectura única que involucra subredes gemelas.
  • Diferenciar entre las funciones de pérdida utilizadas en las redes siamesas, incluyendo la Pérdida de Entropía Cruzada Binaria, la Pérdida Contrastiva y la Pérdida Triplet.
  • Identificar y describir aplicaciones del mundo real donde las redes siamesas pueden ser utilizadas de manera efectiva, como reconocimiento facial, reconocimiento de huellas dactilares y evaluación de similitud de textos.
  • Resumir las ventajas y desventajas de las redes siamesas en relación con el aprendizaje de una sola muestra, la versatilidad y el rendimiento agnóstico al dominio.

Este artículo fue publicado como parte del Data Science Blogathon.

¿Qué son las Redes Siamesas?

Las Redes Siamesas pertenecen a una categoría de redes que utilizan dos subredes idénticas para la clasificación de una sola muestra. Estas subredes comparten la misma configuración, parámetros y pesos, pero acomodan diferentes entradas. Una Red Siamesa aprende una función de similitud, a diferencia de las CNN convencionales, que se entrenan con una gran cantidad de datos para predecir múltiples clases. Esta función nos permite distinguir entre clases utilizando datos mínimos, lo que las hace particularmente efectivas para la clasificación de una sola muestra. Esta capacidad única significa que, en muchas ocasiones, un solo ejemplo es suficiente para que estas redes clasifiquen imágenes con precisión.

Una aplicación del mundo real de las Redes Siamesas se encuentra en el reconocimiento facial y la verificación de firmas. Imagina una empresa que implementa un sistema de asistencia basado en reconocimiento facial. Con solo una imagen de cada empleado disponible, las CNN tradicionales tendrían dificultades para clasificar con precisión a miles de empleados. Aquí entran en juego las redes siamesas, destacando en este tipo de escenarios.

Explorando el Aprendizaje de Pocas Muestras

En el aprendizaje de pocas muestras, los modelos se entrenan para hacer predicciones basadas en un número limitado de ejemplos. Esto contrasta con el enfoque tradicional, que requiere un volumen sustancial de datos etiquetados para fines de entrenamiento. La importancia del aprendizaje de pocas muestras surge cuando adquirir suficientes datos etiquetados se vuelve desafiante o costoso.

La arquitectura de los modelos de pocas muestras aprovecha los matices entre un pequeño puñado de muestras, lo que les permite hacer predicciones basadas en unos pocos o incluso un solo ejemplo. Diversos marcos de diseño como las Redes Siamesas, el Meta-aprendizaje y enfoques similares facilitan esta capacidad. Estos marcos permiten que el modelo extraiga representaciones significativas de los datos y las utilice para muestras novedosas y no vistas anteriormente.

Un par de ejemplos prácticos donde el aprendizaje de pocas muestras brilla incluyen:

  1. Detección de Objetos en Vigilancia: El aprendizaje de pocas muestras puede identificar eficazmente objetos dentro de imágenes de vigilancia, incluso cuando solo hay algunos ejemplos de esos objetos disponibles. Después de entrenar el modelo con un conjunto modesto de ejemplos etiquetados, posteriormente puede detectar estos objetos en nuevas imágenes, incluso si nunca los ha encontrado antes.

2. Atención Médica Personalizada: Dentro de la atención médica personalizada, los profesionales médicos pueden tener un conjunto limitado de registros médicos de un paciente, que incluyen algunas tomografías computarizadas o análisis de sangre. Utilizando un modelo de aprendizaje de pocas muestras, estas instancias de entrenamiento nos permiten predecir el bienestar prospectivo del paciente. Esto puede incluir pronósticos sobre la posible aparición de una enfermedad específica o la respuesta probable a un enfoque terapéutico particular.

La Arquitectura de las Redes Siamesas

El diseño de la red Siamesa comprende dos subredes idénticas, cada una procesando una de las entradas. Inicialmente, las entradas se someten a un procesamiento a través de una red neuronal convolucional (CNN), que extrae características significativas de las imágenes proporcionadas. Estas subredes generan entonces salidas codificadas, a menudo a través de una capa completamente conectada, resultando en una representación condensada de los datos de entrada.

La CNN consta de dos ramas y un componente compartido de extracción de características, compuesto por capas de convolución, normalización por lotes y activación ReLU, seguidas de capas de max pooling y dropout. El segmento final implica la capa FC, que mapea las características extraídas a los resultados de clasificación finales. Una función delinea una capa lineal seguida de una secuencia de activaciones ReLU y una serie de operaciones consecutivas (convolución, normalización por lotes, activación ReLU, max pooling y dropout). La función forward guía las entradas a través de ambas ramas de la red.

La capa de Diferenciación sirve para identificar similitudes entre las entradas y amplificar las diferencias entre pares no similares, logrado mediante la función de Distancia Euclidiana:

Distancia(x₁, x₂) = ∥f(x₁) – f(x₂)∥₂

En este contexto,

  • x₁, x₂ son las dos entradas.
  • f(x) representa la salida de la codificación.
  • Distancia denota la función de distancia.

Esta propiedad permite que la red adquiera representaciones efectivas de los datos y las aplique a muestras nuevas e inéditas. En consecuencia, la red genera una codificación, a menudo representada como una puntuación de similitud, que ayuda en la diferenciación entre clases.

Represente la arquitectura de la red en la figura adjunta. Es importante destacar que esta red opera como un clasificador de una sola muestra, lo que elimina la necesidad de muchos ejemplos por clase.

Funciones de pérdida utilizadas en las redes Siamesas

Una función de pérdida es una herramienta matemática para medir la disimilitud entre la salida anticipada y la salida real dentro de un modelo de aprendizaje automático, dada una entrada específica. Al entrenar un modelo, el objetivo es minimizar esta función de pérdida ajustando los parámetros del modelo.

Existen numerosas funciones de pérdida que se adaptan a diferentes tipos de problemas. Por ejemplo, el error cuadrático medio es adecuado para desafíos de regresión, mientras que la pérdida de entropía cruzada se adapta a tareas de clasificación.

A diferencia de otros tipos de redes, la Red Siamesa abarca múltiples funciones de pérdida, que se explican a continuación.

Pérdida de entropía cruzada binaria

La pérdida de entropía cruzada binaria resulta valiosa para tareas de clasificación binaria, donde el objetivo es predecir entre dos posibles resultados. En el contexto de una red Siamesa, el objetivo es clasificar una imagen como “similar” o “diferente” a otra.

Esta función cuantifica la disparidad entre la probabilidad pronosticada de la clase positiva y el resultado real. Dentro de la red Siamesa, la probabilidad pronosticada se refiere a la probabilidad de similitud de imágenes, mientras que el resultado real asume una forma binaria: 1 para similitud de imágenes y 0 para disimilitud.

La formulación de la función implica el logaritmo negativo de la probabilidad de clase real, calculada como:−(ylog(p)+(1−y)log(1−p))

Aquí,

  • y representa la etiqueta real.
  • p representa la probabilidad pronosticada.

El entrenamiento de un modelo con pérdida de entropía cruzada binaria se esfuerza por minimizar esta función mediante el ajuste de parámetros. A través de esta minimización, el modelo adquiere habilidad en la predicción precisa de clases.

Pérdida contrastiva

La pérdida contrastiva se adentra en la diferenciación de pares de imágenes mediante el uso de la distancia como medida de similitud. Esta función resulta ventajosa cuando el número de instancias de entrenamiento por clase es limitado. Es importante tener en cuenta que la pérdida contrastiva requiere pares de muestras de entrenamiento negativas y positivas. Se proporciona una visualización de esta pérdida en la figura adjunta.

La ecuación de la pérdida contrastiva puede ser:

(1 – Y) * 0.5 * D^2 + Y * 0.5 * max(0, m – D^2)

Aquí se detalla:

  • Y representa un parámetro de entrada.
  • D representa la distancia Euclidiana.
  • Cuando Y es igual a 0, las entradas pertenecen a la misma clase. Por otro lado, un valor de Y igual a 1 indica que provienen de clases diferentes.
  • El parámetro ‘m’ define un margen para la función de distancia, ayudando a identificar pares que contribuyen a la pérdida. Cabe destacar que el valor de ‘m’ siempre es mayor que 0.

Pérdida Triplete

La pérdida triplete utiliza triples de datos. La siguiente gráfica ilustra estos triples.

La función de pérdida triplete tiene como objetivo mejorar la separación entre las muestras de anclaje y negativas, al mismo tiempo que reduce la brecha entre las muestras de anclaje y positivas.

Matemáticamente, la función de pérdida triplete se define como la diferencia máxima entre la distancia de anclaje a positiva (d(a,p)) y la distancia de anclaje a negativa (d(a,n)), restada por un valor de margen. Cuando esta diferencia es positiva, el valor calculado se convierte en la pérdida; de lo contrario, se establece en cero.

Aquí hay un desglose de los componentes:

  • d representa la distancia euclidiana.
  • a representa la entrada de anclaje.
  • p denota la entrada positiva.
  • n representa la entrada negativa.

El objetivo principal es asegurar que la entrada positiva esté más cerca de la entrada de anclaje que la entrada negativa, manteniendo un margen de separación.

Construcción de un Modelo Basado en Red Siamesa para la Verificación de Firmas

La verificación de firmas implica distinguir firmas falsificadas de una colección de firmas genuinas. En este escenario, un modelo debe comprender las sutilezas entre numerosas firmas. Luego, debe discernir entre firmas auténticas y falsas cuando se le presenten. Lograr este objetivo de verificación plantea un desafío considerable para las CNN convencionales debido a las variaciones intrincadas y las instancias de entrenamiento limitadas. Agravando la dificultad, a menudo solo existe una firma solitaria por individuo, lo que exige la competencia del modelo para verificar las firmas de miles de individuos. Las secciones siguientes profundizan en la creación de un modelo basado en PyTorch para abordar esta tarea compleja.

Conjunto de datos

El conjunto de datos que utilizaremos se refiere a la validación de firmas y es ICDAR 2011. Esta colección comprende firmas holandesas, que incluyen tanto firmas auténticas como falsificadas. Aquí hay una muestra de los datos para referencia. Enlace para el conjunto de datos.

Descripción del Problema

Este artículo profundiza en la tarea de detectar firmas falsificadas dentro de un contexto de verificación de firmas. Nuestro objetivo implica aprovechar un conjunto de datos de firmas y utilizar una red siamesa para predecir la autenticidad de las firmas de prueba, distinguiendo las genuinas de las fraudulentas. Para lograr esto, debemos establecer un proceso paso a paso. Esto implica la ingestión de datos del conjunto de datos, la creación de pares de imágenes y su posterior procesamiento a través de la red siamesa. Después de entrenar la red utilizando el conjunto de datos proporcionado, luego desarrollamos funciones de predicción.

Importando Librerías Esenciales

La construcción de la Red Siamesa requiere la inclusión de varias librerías clave. Introducimos la librería Pillow (PIL) para la manipulación de imágenes, matplotlib para visualización, numpy para operaciones numéricas y tqdm para una utilidad de barra de progreso. Además, aprovechamos el poder de PyTorch y torchvision para facilitar el entrenamiento y la construcción de la red.

import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision.transforms as transforms
import torchvision.utils as tv_utils
from torch.autograd import Variable
from torch.utils.data import DataLoader, Dataset
import PIL.Image as Image
import matplotlib.pyplot as plt
import numpy as np
import os
import pandas as pd
import torch.utils.data as custom_data
from tqdm import tqdm

Funciones de Utilidad

Para visualizar las salidas de la red, se crea una función de utilidad. Esta función acepta imágenes y sus etiquetas correspondientes como entradas y las organiza en una cuadrícula para una visualización conveniente.

import numpy as np
import matplotlib.pyplot as plt

def display_image(img, caption=None, save=False):
    image_array = img.numpy()
    plt.axis("off")
    
    if caption:
        plt.text(
            75,
            8,
            caption,
            style="italic",
            fontweight="bold",
            bbox={"facecolor": "white", "alpha": 0.8, "pad": 10},
        )
    
    plt.imshow(np.transpose(image_array, (1, 2, 0)))
    plt.show()

Preprocesamiento de Datos

La estructura de datos utilizada por la red siamesa difiere notablemente de las redes convencionales de clasificación de imágenes. En lugar de proporcionar un par de imagen-etiqueta único, el Generador de Conjuntos de Datos para la red siamesa requiere el suministro de pares de imágenes. Estos pares pasan por un proceso de transformación que implica la conversión a blanco y negro, el redimensionamiento posterior y la conversión final en Tensores. Dos categorías distintas de pares son los pares positivos, caracterizados por imágenes de entrada idénticas, y los pares negativos, con imágenes diferentes. Además, una función proporciona el tamaño del Conjunto de Datos cuando se invoca.

import os
import pandas as pd
import torch
import torch.utils.data as data
from PIL import Image
import numpy as np

class PairedDataset(data.Dataset):
    def __init__(self, df_path=None, data_dir=None, transform=None, subset=None):
        self.df = pd.read_csv(df_path)
        if subset is not None:
            self.df = self.df[:subset]
        self.df.columns = ["imagen1", "imagen2", "etiqueta"]
        self.data_dir = data_dir
        self.transform = transform

    def __getitem__(self, index):
        ruta_imagen1 = os.path.join(self.data_dir, self.df.iat[index, 0])
        ruta_imagen2 = os.path.join(self.data_dir, self.df.iat[index, 1])

        imagen1 = Image.open(ruta_imagen1).convert("L")
        imagen2 = Image.open(ruta_imagen2).convert("L")

        if self.transform:
            imagen1 = self.transform(imagen1)
            imagen2 = self.transform(imagen2)

        etiqueta = torch.tensor([int(self.df.iat[index, 2])], dtype=torch.float32)

        return imagen1, imagen2, etiqueta

    def __len__(self):
        return len(self.df)

Resumen Conciso de Características

Las entradas de la red consisten en imágenes que comprenden pares de datos positivos y negativos. Representamos estos pares como datos de imagen y los transformamos en formato Tensor, encapsulando efectivamente la información de imagen subyacente. Las etiquetas asociadas a la red Siamesa son categóricas.

Proceso de Normalización de Características

Un paso crucial implica normalizar las características y convertir las imágenes a blanco y negro. Además, redimensionamos uniformemente todas las imágenes a un formato cuadrado de (105×105), ya que la Red Siamesa requiere esta dimensión. Posteriormente, convertimos todas las imágenes en Tensores, lo cual mejora la eficiencia computacional y permite utilizar la GPU.

transformacion_datos = transforms.Compose([
    transforms.Resize((105, 105)),
    transforms.ToTensor()
])

División del Conjunto de Datos

Dividimos el conjunto de datos en segmentos distintos de entrenamiento y prueba para facilitar tanto el entrenamiento como la prueba del modelo. Para facilitar la ilustración, nos enfocamos en los primeros 1000 puntos de datos. Si optamos por un valor de función “load_subset” de None, utilizaríamos el conjunto de datos completo, aunque a expensas de un tiempo de procesamiento prolongado. Considera la ampliación de datos como un enfoque para mejorar el rendimiento a largo plazo de la red.

conjunto_entrenamiento = PairedDataset(
    df_entrenamiento,
    directorio_entrenamiento,
    transform=transforms.Compose([
        transforms.Resize((105, 105)),
        transforms.ToTensor()
    ]),
    subset=1000
)

conjunto_evaluacion = PairedDataset(
    df_evaluacion,
    directorio_evaluacion,
    transform=transforms.Compose([
        transforms.Resize((105, 105)),
        transforms.ToTensor()
    ]),
    subset=1000
)

Arquitectura de la Red Neuronal

La construcción de la arquitectura descrita implica una serie de pasos. Inicialmente, establecemos una función que construye conjuntos de capas de Convolución, Normalización por Lotes y ReLU, ofreciendo la flexibilidad de incluir o excluir una capa de Dropout al final. Otra función se diseña para generar secuencias de capas Totalmente Conectadas (FC), complementadas por capas posteriores de ReLU. Una vez que el componente CNN se construye a través de las funciones mencionadas anteriormente, la atención se centra en dar forma al segmento FC de la red. Se implementan tamaños de relleno y kernel distintos en toda la red.

La parte FC consiste en bloques que comprenden capas Lineales seguidas de activaciones ReLU. Con la arquitectura definida, realizamos un pase hacia adelante para procesar los datos proporcionados a través de la red. Un aspecto importante a destacar es la función “view”, que remodela la salida del bloque anterior aplanando las dimensiones. Se establece el escenario para entrenar la red Siamesa utilizando los datos suministrados una vez establecido este mecanismo.

class SiameseNetwork(nn.Module):
    def __init__(self):
        super(SiameseNetwork, self).__init__()

        self.cnn1 = nn.Sequential(
            self.create_conv_block(1, 96, 11, 1, False),
            self.create_conv_block(96, 256, 5, 2, True),
            nn.Conv2d(256, 384, kernel_size=3, stride=1, padding=1),
            nn.BatchNorm2d(384),
            nn.ReLU(inplace=True),
            self.create_conv_block(384, 256, 3, 1, True),
        )

        self.fc1 = nn.Sequential(
            self.create_linear_relu(30976, 1024),
            nn.Dropout2d(p=0.5),
            self.create_linear_relu(1024, 128),
            nn.Linear(128, 2)
        )

    def create_linear_relu(self, input_channels, output_channels):
        return nn.Sequential(nn.Linear(input_channels, output_channels),
        nn.ReLU(inplace=True))

    def create_conv_block(self, input_channels, output_channels, kernel_size,
    padding, dropout=True):
        if dropout:
            return nn.Sequential(
                nn.Conv2d(input_channels, output_channels, kernel_size=kernel_size,
                stride=1, padding=padding),
                nn.BatchNorm2d(output_channels),
                nn.ReLU(inplace=True),
                nn.MaxPool2d(3, stride=2),
                nn.Dropout2d(p=0.3)
            )
        else:
            return nn.Sequential(
                nn.Conv2d(input_channels, output_channels, kernel_size=kernel_size,
                stride=1),
                nn.BatchNorm2d(output_channels),
                nn.ReLU(inplace=True),
                nn.MaxPool2d(3, stride=2)
            )

    def forward_once(self, x):
        salida = self.cnn1(x)
        salida = salida.view(salida.size()[0], -1)
        salida = self.fc1(salida)
        return salida

    def forward(self, entrada1, entrada2):
        out1 = self.forward_once(entrada1)
        out2 = self.forward_once(entrada2)
        return out1, out2

Función de Pérdida

La función de pérdida contrastiva sirve como la función de pérdida fundamental para la Red Siamesa. Definir esta pérdida implica utilizar las ecuaciones elucidadas anteriormente en el artículo. Para mejorar la eficiencia del código, en lugar de definir la pérdida como una función directa, se puede utilizar un enfoque alternativo que involucra la herencia de la clase nn.Module. Esto permite la creación de una clase personalizada que proporciona las salidas de la función. Dicho envoltorio permite a PyTorch optimizar la ejecución del código, mejorando así el rendimiento general del tiempo de ejecución.

class ContrastiveLoss(nn.Module):
    def __init__(self, margen=2.0):
        super(ContrastiveLoss, self).__init__()
        self.margen = margen

    def forward(self, salida1, salida2, etiqueta):
        distancia_euclidiana = F.pairwise_distance(salida1, salida2)
        pérdida_positiva = (1 - etiqueta) * torch.pow(distancia_euclidiana, 2)
        pérdida_negativa = etiqueta * torch.pow(torch.clamp(self.margen - distancia_euclidiana, min=0.0), 2)
        pérdida_total = torch.mean(pérdida_positiva + pérdida_negativa)
        return pérdida_total

Entrenamiento de la Red Siamesa

Con los datos cargados y preprocesados, se establece el escenario para iniciar el entrenamiento de la red Siamesa. Para iniciar este proceso, comenzamos estableciendo los cargadores de datos tanto para el entrenamiento como para las pruebas. Es importante destacar que el DataLoader de evaluación se configura con un tamaño de lote de 1 para facilitar evaluaciones individualizadas. Posteriormente, el modelo se despliega en la GPU y se definen componentes fundamentales como la función de pérdida contrastiva y el optimizador Adam.

train_loader = DataLoader(train_dataset,
                        shuffle=True,
                        num_workers=8,
                        batch_size=bs) 
eval_loader = DataLoader(evaluation_dataset,
                        shuffle=True,
                        num_workers=8,
                        batch_size=1) 

siamese_net = SiameseNetwork().cuda()
función_pérdida = ContrastiveLoss()
optimizador = torch.optim.Adam(siamese_net.parameters(), lr=1e-3, weight_decay=0.0005)

Posteriormente, se crea una función que acepta el DataLoader de entrenamiento como entrada. Dentro de esta función, se mantiene una matriz en curso para realizar un seguimiento de la pérdida, junto con un contador para facilitar futuros esfuerzos de trazado. El proceso iterativo subsecuente navega a través de los puntos de datos dentro del DataLoader. Para cada punto, los pares de imágenes se transfieren a la GPU, se someten a procesamiento de red y se calcula la pérdida contrastiva. Los pasos subsecuentes comprenden la ejecución de un paso de retroceso, culminando en la provisión de la pérdida neta correspondiente a un lote de datos.

def entrenar(train_loader, modelo, optimizador, función_pérdida):
    pérdida_total = 0.0
    num_lotes = len(train_loader)

    modelo.train()

    for batch_idx, (par_izquierdo, par_derecho, etiqueta) in
    enumerate(tqdm(train_loader, total=num_lotes)):
        par_izquierdo, par_derecho, etiqueta = par_izquierdo.cuda(),
        par_derecho.cuda(), etiqueta.cuda()

        optimizador.zero_grad()
        salida1, salida2 = modelo(par_izquierdo, par_derecho)

        pérdida_contrastiva = función_pérdida(salida1, salida2, etiqueta)
        pérdida_contrastiva.backward()
        optimizador.step()

        pérdida_total += pérdida_contrastiva.item()

    pérdida_media = pérdida_total / num_lotes

    return pérdida_media

El modelo se puede entrenar durante múltiples épocas utilizando nuestra función diseñada. En esta demostración, el artículo cubre solo un número limitado de épocas. Si la pérdida de evaluación alcanzada durante el entrenamiento representa el mejor rendimiento observado a lo largo de la duración del entrenamiento, el modelo se guarda para su posterior inferencia en esa época en particular.

mejor_pérdida_evaluación = float('inf')

for época in tqdm(range(1, num_epocas)):
    pérdida_entrenamiento = entrenar(train_loader)
    pérdida_evaluación = evaluar(eval_loader)

    print(f"Época: {época}")
    print(f"Pérdida de entrenamiento: {pérdida_entrenamiento}")
    print(f"Pérdida de evaluación: {pérdida_evaluación}")

    if pérdida_evaluación < mejor_pérdida_evaluación:
        mejor_pérdida_evaluación = pérdida_evaluación
        print(f"Mejor pérdida de evaluación: {mejor_pérdida_evaluación}")
        torch.save(siamese_net.state_dict(), "modelo.pth")
        print("Modelo guardado exitosamente")

Probando el Modelo

Tras el entrenamiento del modelo, se produce una fase de evaluación que nos permite evaluar su rendimiento y realizar inferencias para puntos de datos individuales. De manera análoga a la función de entrenamiento, se construye una función de evaluación que toma el cargador de datos de prueba como entrada. El cargador de datos se itera, procesando una instancia a la vez. Posteriormente, se extraen los pares de imágenes para las pruebas. Estos pares se envían a la GPU, lo que permite la ejecución del modelo. Las salidas resultantes del modelo se utilizan para calcular la pérdida contrastiva, que posteriormente se almacena en una lista designada.

def evaluar(eval_loader):
    lista_perdidas = []
    lista_contadores = []
    numero_iteracion = 0

    for i, datos in tqdm(enumerate(eval_loader, 0), total=len(eval_loader)):
        par_izquierda, par_derecha, etiqueta = datos
        par_izquierda, par_derecha, etiqueta = par_izquierda.cuda(), par_derecha.cuda(), etiqueta.cuda()
        
        salida1, salida2 = siamese_net(par_izquierda, par_derecha)
        perdida_contrastiva = loss_function(salida1, salida2, etiqueta)
        lista_perdidas.append(perdida_contrastiva.item())
    
    arreglo_perdidas = np.array(lista_perdidas)
    perdida_promedio = arreglo_perdidas.mean() / len(eval_loader)
    
    return perdida_promedio

Podemos ejecutar el código para realizar una evaluación única en todos los puntos de datos de prueba. Para evaluar el rendimiento visualmente, generaremos gráficos que representen las imágenes y mostraremos las distancias entre pares identificadas por el modelo entre los puntos de datos. Presenta estos resultados en forma de una cuadrícula.

for i, datos in enumerate(dl_eval, 0):
    x0, x1, etiqueta = datos
    imagenes_concatenadas = torch.cat((x0, x1), 0)
    salida1, salida2 = siamese_net(x0.to('cuda'), x1.to('cuda'))

    distancia_euclidiana = F.pairwise_distance(salida1, salida2)
    print(etiqueta)
    if etiqueta == torch.FloatTensor([[0]]):
        texto_etiqueta = "Par Original de Firma"
    else:
        texto_etiqueta = "Par Falsificado de Firma"

    mostrar_imagenes(torchvision.utils.make_grid(imagenes_concatenadas))
    print("Distancia Euclidiana Predicha:", distancia_euclidiana.item())
    print("Etiqueta Real:", texto_etiqueta)
    if i == 4:
        break

Resultado

Ventajas y Desventajas de las Redes Siamesas

Desventajas

  • Una desventaja notable de las redes Siamesas es su salida, que proporciona una puntuación de similitud en lugar de una distribución de probabilidad que suma 1. Esta característica puede presentar desafíos en ciertas aplicaciones donde se prefieren salidas basadas en probabilidades.

Ventajas

  • Las redes Siamesas muestran resistencia al tratar con diferentes números de ejemplos dentro de diferentes clases. Esta capacidad de adaptación se debe a la capacidad de la red para funcionar de manera efectiva con información de clase limitada.
  • El rendimiento de clasificación de la red no depende de proporcionar información específica del dominio, lo que contribuye a su versatilidad.
  • Las redes Siamesas pueden hacer predicciones incluso con una sola imagen por clase.

Aplicaciones de las Redes Siamesas

Las Redes Siamesas encuentran utilidad en diversas aplicaciones, algunas de las cuales se describen a continuación.

Reconocimiento Facial: Las redes Siamesas resultan ventajosas en tareas de reconocimiento facial de una sola toma. Utilizando la pérdida contrastiva, estas redes distinguen caras diferentes de las similares, lo que permite una identificación facial efectiva con muestras de datos mínimas.

Reconocimiento de Huellas Dactilares: Utilice las Redes Siamesas para el reconocimiento de huellas dactilares. Al proporcionar pares de huellas dactilares preprocesadas a la red, aprende a diferenciar entre impresiones válidas e inválidas, mejorando la precisión de la autenticación basada en huellas dactilares.

Verificación de Firmas: Este artículo se centró principalmente en la implementación de la Verificación de Firmas a través de redes Siamesas. Como se demostró, la red procesa pares de firmas para determinar la autenticidad de las firmas, distinguiendo entre las genuinas y las falsificadas.

Similitud de Texto: Las Redes Siamesas también son relevantes para evaluar la similitud de texto. A través de entradas emparejadas, la red puede discernir similitudes entre diferentes fragmentos de texto. Las aplicaciones prácticas incluyen identificar preguntas análogas dentro de un banco de preguntas o recuperar documentos similares de un repositorio de texto.

Conclusion

Una red neuronal siamesa, a menudo abreviada como SNN, se encuentra dentro de la categoría de diseños de redes neuronales que incorporan dos o más subredes que comparten una estructura idéntica. En este contexto, “idéntica” implica tener configuraciones, parámetros y pesos coincidentes. La sincronización de las actualizaciones de parámetros entre estas subredes determina las similitudes entre las entradas a través de la comparación de vectores de características.

Puntos clave

  • Las redes siamesas destacan en la clasificación de conjuntos de datos con ejemplos limitados por clase, lo que las hace valiosas para escenarios con datos de entrenamiento escasos.
  • A través de esta exploración, obtuvimos una comprensión de los principios fundamentales que sustentan las redes siamesas, que incluyen su arquitectura, las funciones de pérdida utilizadas y el proceso de entrenamiento de dichas redes.
  • Nuestro recorrido abarcó la aplicación práctica de las redes siamesas en el contexto de la verificación de firmas, utilizando el conjunto de datos ICDAR 2011. Esto implicó la creación de un modelo capaz de detectar firmas falsificadas.
  • El proceso de entrenamiento y prueba de las redes siamesas se aclaró, ofreciendo una comprensión completa de cómo operan estas redes. Nos adentramos en la representación de datos emparejados, un aspecto crucial de su eficacia.

Preguntas frecuentes

Los medios mostrados en este artículo no son propiedad de Analytics Vidhya y se utilizan a discreción del autor.

We will continue to update Zepes; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Inteligencia Artificial

6 Pasos para Proteger tu Privacidad al Usar Herramientas de IA Generativa

Introducción La aparición de herramientas de IA generativa ha despertado tanto entusiasmo como preocupación. Estas he...

Inteligencia Artificial

Esta investigación de IA comparte una visión general exhaustiva de los modelos de lenguaje grandes (LLM) en grafos.

Los conocidos Modelos de Lenguaje Grandes (LLMs, por sus siglas en inglés) como GPT, BERT, PaLM y LLaMA han logrado g...

Inteligencia Artificial

El nuevo modelo de IA de Phind supera a GPT-4 en codificación, con una velocidad similar a la de GPT-3.5 y un contexto de 16k.

En la codificación y resolución de problemas técnicos, un desafío ha sido el equilibrio entre la velocidad y la preci...