es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Crear una pila de imágenes en PyTorch

Tengo un tensor de imagen Bx3xHxW en PyTorch y deseo crear una pila de imagen Bx3FxHxW de esta imagen donde F=64.

La pila de imágenes se forma desplazando la imagen original hacia la derecha. Es decir, si la imagen original debe desplazarse 2 píxeles a la derecha, las dos columnas más a la izquierda en la nueva imagen serán 0 y la tercera columna desde la izquierda de la imagen original se convertirá en la última columna de la nueva imagen desplazada.

La pila de imágenes se forma desplazando hacia la derecha la imagen original f veces, donde f varía de 0 a F-1.

¿Cómo lograr esto en PyTorch de la manera más eficiente utilizando la menor cantidad posible de bucles for? Un código numpy también funcionará ya que los dos lenguajes son bastante compatibles.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para lograr esto en PyTorch, podemos utilizar la función torch.roll. Primero podemos crear un tensor de forma Bx3xFxHxW lleno de ceros y luego usar torch.roll para desplazar el tensor de imagen original f veces hacia la derecha e insertarlo en la posición correspondiente en el tensor de pila de imágenes.

    Aquí está el código para lograr esto:

    import torch
    
    # tensor de imagen original de forma Bx3xHxW
    original_image = torch.randn(B, 3, H, W)
    
    # forma del tensor de pila de imágenes
    F = 64
    image_stack_shape = (B, 3, F, H, W)
    
    # crear un tensor de pila de imágenes de forma Bx3xFxHxW lleno de ceros
    image_stack = torch.zeros(*image_stack_shape)
    
    # iterar sobre f de 0 a F-1
    for f in range(F):
        # desplazar el tensor de imagen original a la derecha f veces e insertarlo en el tensor de pila de imágenes
        image_stack[:, :, f] = torch.roll(original_image, shifts=f, dims=3)
    
    # image_stack ahora contiene las imágenes apiladas
    

    Alternativamente, se puede implementar el enfoque anterior de manera más eficiente sin bucles for de la siguiente manera:

    import torch
    
    # tensor de imagen original de forma Bx3xHxW
    original_image = torch.randn(B, 3, H, W)
    
    # forma del tensor de pila de imágenes
    F = 64
    image_stack_shape = (B, 3, F, H, W)
    
    # crear un tensor de pila de imágenes de forma Bx3xFxHxW lleno de ceros
    image_stack = torch.zeros(*image_stack_shape)
    
    # crear un tensor de forma Bx3xHxWx2F usando torch.cat
    catted = torch.cat([original_image, torch.zeros(B, 3, H, W, F-1)], axis=3)
    catted = torch.cat([torch.zeros(B, 3, H, W, F), catted], axis=3)
    
    # Desplazar el tensor anterior para obtener las imágenes
    image_stack = catted[:, :, :, :, -F:].roll(shifts=F, dims=4)
    
    # image_stack ahora contiene las imágenes apiladas
    

    Podemos usar de manera similar numpy.roll para lograr el mismo resultado eficientemente en numpy de la siguiente manera:

    import numpy as np
    
    # tensor de imagen original de forma Bx3xHxW
    original_image = np.random.randn(B, 3, H, W)
    
    # forma del tensor de pila de imágenes
    F = 64
    image_stack_shape = (B, 3, F, H, W)
    
    # crear un tensor de pila de imágenes de forma Bx3xFxHxW lleno de ceros
    image_stack = np.zeros(image_stack_shape)
    
    # crear un tensor de forma Bx3xHxWx2F usando np.concatenate
    catted = np.concatenate([original_image, np.zeros((B, 3, H, W, F-1))], axis=3)
    catted = np.concatenate([np.zeros((B, 3, H, W, F)), catted], axis=3)
    
    # desplazar el tensor anterior para obtener las imágenes
    for f in range(F):
        image_stack[:, :, f] = np.roll(catted, shift=f, axis=3)[:, :, -F:]
    
    # image_stack ahora contiene las imágenes apiladas
    

    Ambos ejemplos anteriores deberían funcionar sin la necesidad de bucles for, lo que hace que la operación sea más eficiente.

Comments are closed.