Quantum GAN for RGB images

Hi @Eleonora_Panini,

Unfortunately your problem seems just too complicated for a normal laptop. My recommendation would be to work together with someone who has access to HPC resources, like you have worked together with @mass_of_15. This is not a guarantee that you will get a successful result but it can help you avoid memory issues.

On the PennyLane side we keep working on our software to allow you to run larger simulations. You will still reach a limit at some point but I hope we can help you run more complicated problems in the future.

I can’t have access to an HPC and i don’t know other people who has it. Anyway, when you (and pennylane team) made improvements to the quantum simulator, tell me, so I can try again the training.
Thank you for your help

can you guys please share the entire code with me im trying to work on similar problem and want to redo this . Also will convert rgb images with higher resolution inot format that currently demo supports work ?? how does the quantum circuit change in that case

Hey @sana_falak_jakati, welcome to the forum!

@Eleonora_Panini and @mass_of_15 had some other forum posts / discussions about this (e.g., How to scale the QGAN example to more qubits). I think if you search around you might be able to find it. If not, we’ll have to wait for them to respond :sweat_smile:

Hello @isaacdevlugt thanks for the response i was trying out some stuff and images generated arent great so far will post results :slight_smile: Meanwhile just wanted to check if there are any papers or any leads if someone has tried Pgans using quantum ?

I’m not sure that I’ve ever heard of a PGAN :thinking: and when I google it not a whole lot comes up. Can you attach some references for that?

You may have already come across these, but we have some demos on GANs in PennyLane:

Let me know if that helps!

Hello Issacdevlugt,

Here is some details of PGANS " https://machinelearningmastery.com/introduction-to-progressive-growing-generative-adversarial-networks/ " i was looking for progressive GANS which caters to generating high resolution and big scale images .

Is there any similar work done in quantum gans space yet

Thank you for responding :slight_smile:

Hey @sana_falak_jakati, to my knowledge, I’m not sure there has been any quantum applied to this. Might be a good thing for you to try out!

1 Like

HI @sana_falak_jakati did you reach some results with the progressive GAN adapted for quantum circuits and RGB images?

Hello @isaacdevlugt, I am want to use default.qutrit, instead of lightning.qubit. Just a quick question, can I use same Parametrized circuit used in Patch Quantum GAN, using qutrit? Is all the rotation gates and controlled gates, supported in qubit be applied to qutrit? Also I know that from https://discuss.pennylane.ai/t/how-to-scale-the-qgan-example-to-more-qubits/2958/11?u=mass_of_15

So If I use qutrit, will each wires give three probability values. What would be the equation then?

Last question, will the the runtime speedup?

Hi @mass_of_15 ! Thank you for your question.

Since this thread is already very long and your question is related more to qutrits than to GANs, would you be ok with opening a new thread with your question? This way we can ask our qutrits expert and it will be easier for them to help you. If you could post the link to the new thread here that would be great.

And just in case you haven’t seen it, we have a demo on qutrits which might be interesting for you!

I have created new thread for qutrits as requested.

Thank you @mass_of_15 ! I’ll continue the conversation there.

@mass_of_15
Hello, I am trying to do this same example on an HPC but with a different dataset. Could you send me your code, I would like to see it, or maybe you have it in a github repo?

Hi @thewill-i-am , welcome to the Forum!

Have you tried out our demos on QGANs?

@CatalinaAlbornoz

@CatalinaAlbornoz , Hello greetings from Costa Rica

Yes, of course I already saw that result, I programmed the version for colors, in fact I already have it ready, I am running it Google COLAB with few iterations and using a GPU

# Define the quantum circuit and auxiliary functions
@qml.qnode(dev, interface='torch', diff_method='parameter-shift')
def quantum_circuit(noise, weights):
    weights = weights.reshape(q_depth, n_qubits)

    # Initialize the qubits with the latent vector
    for i in range(n_qubits):
        qml.RY(noise[i], wires=i)

    # Apply parameterized layers
    for i in range(q_depth):
        for y in range(n_qubits):
            qml.RY(weights[i][y], wires=y)
        # CZ Gates
        for y in range(n_qubits - 1):
            qml.CZ(wires=[y, y + 1])

    return qml.probs(wires=list(range(n_qubits)))


def partial_measure(x, weights):
    """
    Applies the quantum circuit to each element in the batch.

    Args:
        x (torch.Tensor): Tensor of shape (batch_size, n_qubits)
        weights (torch.Tensor): Tensor of parameters of shape (q_depth * n_qubits)

    Returns:
        torch.Tensor: Post-processed probabilities of shape (batch_size, 2**(n_qubits - n_a_qubits))
    """
    batch_size = x.size(0)
    probs_list = []

    for i in range(batch_size):
        noise = x[i].float().to(device)  # Ensure noise is float32 and on the correct device
        weights_tensor = weights.float().to(device)  # Ensure weights is float32 and on the correct device
        probs = quantum_circuit(noise, weights_tensor)  # Shape: (2**n_qubits,)
        probsgiven0 = probs[: (2 ** (n_qubits - n_a_qubits))]
        probsgiven0 /= torch.sum(probs)
        probsgiven = probsgiven0 / torch.max(probsgiven0)
        probs_list.append(probsgiven)

    probs_tensor = torch.stack(probs_list, dim=0)  # (batch_size, 2**(n_qubits - n_a_qubits))
    return probs_tensor


# Define the quantum generator class
class PatchQuantumGenerator(nn.Module):
    """Quantum generator for the patch method, adapted for 16x16 RGB images"""

    def __init__(self, n_generators, q_delta=1):
        """
        Args:
            n_generators (int): Number of sub-generators per channel (should be 1 for 16x16 RGB images).
            q_delta (float, optional): Range of the random distribution for parameter initialization.
        """
        super().__init__()
        # Generators for each color channel
        self.red_params = nn.ParameterList([
            nn.Parameter(q_delta * torch.rand(q_depth * n_qubits, device=device, dtype=torch.float32), requires_grad=True)
            for _ in range(n_generators)
        ])
        self.green_params = nn.ParameterList([
            nn.Parameter(q_delta * torch.rand(q_depth * n_qubits, device=device, dtype=torch.float32), requires_grad=True)
            for _ in range(n_generators)
        ])
        self.blue_params = nn.ParameterList([
            nn.Parameter(q_delta * torch.rand(q_depth * n_qubits, device=device, dtype=torch.float32), requires_grad=True)
            for _ in range(n_generators)
        ])
        self.n_generators = n_generators

    def forward(self, x):
        """
        Args:
            x (torch.Tensor): Noise tensor of shape (batch_size, n_qubits)
        Returns:
            torch.Tensor: Generated images of shape (batch_size, 3, image_size, image_size)
        """
        x = x.float()  # Ensure x is float32
        patch_size = 2 ** (n_qubits - n_a_qubits)  # 256
        batch_size = x.size(0)

        # Lists for each channel
        red_patches = []
        green_patches = []
        blue_patches = []

        # Generate patches for each channel
        for params in self.red_params:
            patches = partial_measure(x, params)  # Shape: (batch_size, patch_size)
            red_patches.append(patches)
        red_patches = torch.cat(red_patches, dim=1)  # Shape: (batch_size, n_generators * patch_size)

        for params in self.green_params:
            patches = partial_measure(x, params)
            green_patches.append(patches)
        green_patches = torch.cat(green_patches, dim=1)

        for params in self.blue_params:
            patches = partial_measure(x, params)
            blue_patches.append(patches)
        blue_patches = torch.cat(blue_patches, dim=1)

        # Concatenate the three channels
        images = torch.cat([red_patches, green_patches, blue_patches], dim=1)  # (batch_size, 3 * n_generators * patch_size)

        # Reshape to (batch_size, 3, image_size, image_size)
        images = images.view(batch_size, 3, image_size, image_size)
        images = images.float()  # Ensure images are float32
        return images


# Define the classical Discriminator class
class Discriminator(nn.Module):
    def __init__(self):
        super(Discriminator, self).__init__()
        self.model = nn.Sequential(
            nn.Linear(image_size * image_size * 3, 2048),  # Reduced from 4096 to 2048
            nn.LeakyReLU(0.2, inplace=True),
            nn.Linear(2048, 512),  # Reduced from 1024 to 512
            nn.LeakyReLU(0.2, inplace=True),
            nn.Linear(512, 128),  # Reduced from 256 to 128
            nn.LeakyReLU(0.2, inplace=True),
            nn.Linear(128, 1),
            nn.Sigmoid()
        )

    def forward(self, x):
        x = x.view(x.size(0), -1)  # Flatten to (batch_size, 3*image_size*image_size)
        x = x.float()  # Ensure x is float32
        return self.model(x)

This is the configuration I am using for the qubits, etc:

n_qubits = 9  
n_a_qubits = 1  
q_depth = 2  
image_size = 16  
batch_size = 4  
n_generators = 1 
nz = n_qubits  # nz = 9
epochs = 10

@CatalinaAlbornoz I’m getting bad results, well like the one I sent above, I imagine it must be because I’m using few epocs, but I’m not sure

This is with 50 Epochs, I think is going to improve a little bit while the Epochs increase

Hi @thewill-i-am, nice progression!

These problems usually require LOTS of resources on real datasets. You may need more qubits than what you can actually run on Google Colab. One technique that can work is reducing the dimensionality of your dataset. You basically downgrade your data but this might allow you to have enough computational resources to simulate it. This pre-processing of the data is usually done classically.

Nevertheless, some problems are just not well suited for QGANs so there’s no actual guarantee that it will work for your specific dataset.

I hope this helps.

Hello, I want to ask a question. If I want to encode RGB images into quantum states as input to the quantum generator, how can I do it?
Another question, I am trying to use quantum generative adversarial networks to generate hyperspectral images. I saw this post. It is very difficult to generate RGB images at present. It seems to be even more difficult to generate hyperspectral images.Do you have any good suggestions? Thank you.