<jupyter_start><jupyter_text>Inferencia teniendo un modelo entrenado<jupyter_code>import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
import ast
import os
import pathlib

import neptune
import numpy as np
import torch
from torch.utils.data import DataLoader
from torchvision.models.detection.transform import GeneralizedRCNNTransform

from datasets import ObjectDetectionDatasetSingle, ObjectDetectionDataSet
from faster_RCNN import get_fasterRCNN_resnet
from transformations import ComposeDouble, ComposeSingle, FunctionWrapperDouble, FunctionWrapperSingle, apply_nms, apply_score_threshold, normalize_01
from utils import get_filenames_of_path, collate_single, save_json
from visual import DatasetViewer, DatasetViewerSingle
params = {'EXPERIMENT': 'DIS-12',  # Nombre del experimento
          'OWNER': 'Username',  # Nombre de Usuario en Neptune.ai
          'INPUT_DIR': '../data/ChestXRay8/TestImgs',  # Imagenes para predicción
          'PREDICTIONS_PATH': '../data/ChestXRay8/Predictions',  # Directorio para guardar predicciones
          'MODEL_DIR': 'Experiments/chests/DIR-112/checkpoints/epoch=86-step=521.ckpt',  # Cargar el modelo del ultimo checkpoint guardado
          'DOWNLOAD': False,  # Activar descarga desde Neptune.ai
          'DOWNLOAD_PATH': '../data/ChestXRay8/prediction', # Directorio para guardar el modelo
          'PROJECT': 'Disease Detection',  # Nombre del Proyecto
          }
inputs = get_filenames_of_path(pathlib.Path(params['INPUT_DIR'])) # Cargar las imágenes
inputs.sort()
# Realizar la trasnformación de formato y normalización a media 0 y std 1
transforms = ComposeSingle([
    FunctionWrapperSingle(np.moveaxis, source=-1, destination=0),
    FunctionWrapperSingle(normalize_01)
])
# Crear el objeto del Conjunto de datos con solo imagenes y transformaciones
dataset = ObjectDetectionDatasetSingle(inputs=inputs,
                                       transform=transforms,
                                       use_cache=False,
                                       )
# Crear el cargador de los datos por lote
dataloader_prediction = DataLoader(dataset=dataset,
                                   batch_size=1,
                                   shuffle=False,
                                   num_workers=0,
                                   collate_fn=collate_single)
# Crear conexión con Neptune.ai y obtener el modelo
api_key = os.getenv("NEPTUNE") # cuando ya se tiene configurada la llave como variable de entorno # esto podria dar un error por no configurar la variable de entorno de lo contrario puede poner directamente la llave de la cuenta personalen neptune
project_name = f'{params["OWNER"]}/{params["PROJECT"]}' # Nombre del proyecto
project = neptune.init(project_qualified_name=project_name, api_token=api_key)  # Inicializar la conexión
experiment_id = params['EXPERIMENT']  # Seleccionar el número de experimento (entrenamiento)
experiment = project.get_experiments(id=experiment_id)[0] # cargar el experimento
parameters = experiment.get_parameters() # Obtener parámetros
properties = experiment.get_properties() # Obtener propiedades (clases, arquitecture, tamaño y relación de aspecto de cajas ancla, tamaños mínimo y máximo)
# Transformaciones específicas para Faster R-CNN
transform = GeneralizedRCNNTransform(min_size=int(parameters['MIN_SIZE']),
                                     max_size=int(parameters['MAX_SIZE']),
                                     image_mean=ast.literal_eval(parameters['IMG_MEAN']),
                                     image_std=ast.literal_eval(parameters['IMG_STD']))
# Verificación visual del conjunto del dato
datasetviewer = DatasetViewerSingle(dataset, rccn_transform=None)
datasetviewer.napari()
# Verificar si se descarga el modelo o se obtiene de el checkpoint
if params['DOWNLOAD']:
    download_path = pathlib.Path(os.getcwd()) / params['DOWNLOAD_PATH']
    download_path.mkdir(parents=True, exist_ok=True)
    model_name = 'best_model.pt'  # nombre asignado al modelo
    # model_name = properties['checkpoint_name']  # Se carga cuando se guardo el checkpoint en Neptune
    if not (download_path / model_name).is_file():
        experiment.download_artifact(path=model_name, destination_dir=download_path)  # Descarga del modelo

    model_state_dict = torch.load(download_path / model_name)
else:
    checkpoint = torch.load(params['MODEL_DIR']) # cargar el checkpoint guardado en local
    model_state_dict = checkpoint['hyper_parameters']['model'].state_dict()
# Cargar modelo
model = get_fasterRCNN_resnet(num_classes=int(parameters['CLASSES']),
                              backbone_name=parameters['BACKBONE'],
                              anchor_size=ast.literal_eval(parameters['ANCHOR_SIZE']),
                              aspect_ratios=ast.literal_eval(parameters['ASPECT_RATIOS']),
                              fpn=ast.literal_eval(parameters['FPN']),
                              min_size=int(parameters['MIN_SIZE']),
                              max_size=int(parameters['MAX_SIZE'])
                              )
# Cargar los pesos del modelo
model.load_state_dict(model_state_dict)
# Poner el modelo en modo inferencia, corre en CPU
model.eval()
for sample in dataloader_prediction: # iterar sobre las imagenes a predecir
    x, x_name = sample
    with torch.no_grad():
        pred = model(x)
        pred = {key: value.numpy() for key, value in pred[0].items()}
        name = pathlib.Path(x_name[0])
        save_dir = pathlib.Path(os.getcwd()) / params['PREDICTIONS_PATH'] # Directorio para guardar predicciones 
        save_dir.mkdir(parents=True, exist_ok=True)
        pred_list = {key: value.tolist() for key, value in pred.items()}  # se transforman a listas para serializar
        save_json(pred_list, path=save_dir / name.with_suffix('.json'))
# Cargar los archivos de las preddicciones realizadas
predictions = get_filenames_of_path(pathlib.Path(os.getcwd()) / params['PREDICTIONS_PATH'])
predictions.sort()
# Crear el Conjunto de datos de predicciones
iou_threshold = 0.25 # limite (umbral) de IoU para supresión de no máximos 
score_threshold = 0.6

# Transformaciones a las imagenes de de formato, normalizacion, suprecion de no máximos y umbral de puntuación
transforms_prediction = ComposeDouble([
    FunctionWrapperDouble(np.moveaxis, source=-1, destination=0),
    FunctionWrapperDouble(normalize_01),
    FunctionWrapperDouble(apply_nms, input=False, target=True, iou_threshold=iou_threshold),
    FunctionWrapperDouble(apply_score_threshold, input=False, target=True, score_threshold=score_threshold)
])

# Crear el conjunto de datos para visualizacion con predicciones
dataset_prediction = ObjectDetectionDataSet(inputs=inputs,
                                            targets=predictions,
                                            transform=transforms_prediction,
                                            use_cache=False)
# Mapeo de clases (padecimeintos) con colores
colors = ['red','blue','black','purple','yellow','green','#aaffff','orange']
color_mapping = {v:colors[i] for i,v in enumerate(mapping.values())}
# Visualizar predicciones (imagenes con cajas delimitadoras estimadas)
datasetviewer_prediction = DatasetViewer(dataset_prediction, color_mapping)
datasetviewer_prediction.napari()
# sobre poner el numero del padecimeinto en las cajas delimitadoras correspondientes
datasetviewer_prediction.gui_text_properties(datasetviewer_prediction.shape_layer)<jupyter_output><empty_output><jupyter_text>Experimentar añadiendo NMS y umbral de puntuación<jupyter_code># Transformaciones de formato sin NMS directo ni umbral de puntuacion directo en transformacioens
transforms_prediction = ComposeDouble([
    FunctionWrapperDouble(np.moveaxis, source=-1, destination=0),
    FunctionWrapperDouble(normalize_01)
])
# Creae el conjunto de datos con lsa predicciones realizadas
dataset_prediction = ObjectDetectionDataSet(inputs=inputs,
                                            targets=predictions,
                                            transform=transforms_prediction,
                                            use_cache=False)

# Mapeo de clases (padecimeintos) con colores
colors = ['red','blue','black','purple','yellow','green','#aaffff','orange']
color_mapping = {v:colors[i] for i,v in enumerate(mapping.values())}

# Visualizar imagenes con predicciones (estimaciones)
datasetviewer_prediction = DatasetViewer(dataset_prediction, color_mapping)
datasetviewer_prediction.napari()
# Aplicar el umbral de puntuacion
datasetviewer_prediction.gui_score_slider(datasetviewer_prediction.shape_layer)
# Aplicar la supresión de no máximos
datasetviewer_prediction.gui_nms_slider(datasetviewer_prediction.shape_layer)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08369590107625371, 'fraction_numerical': 0.004465307991756354, 'mean_word_length': 3.648749334752528, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '306337', 'license': 'MIT', 'n_tokens_mistral': 2597, 'n_tokens_neox': 2553, 'n_words': 603, 'path': 'Inference_Notebook.ipynb', 'repo_name': 'Mariuki/ChestX-rayDiseasesDetector', 'size': '8734'}