C3_W1 Assignment UNQ_C1 Make sure order is maintained

An assert statement says
# Make sure that the order is maintained assert torch.abs(test_combination - test_reals).sum() < 1e-4
I’d like to know how this unit test wants order to be maintained.
I understand that the purpose of this is to not shuffle the labels, however I’m not quite sure how to do this. Say p_real is 30% like in the example. It seems that sampling 30% from the reals and 70% from the fakes and just concatenating them in axis 0 such that 30% reals are followed by 70% fakes doesn’t work.

  • I tried getting the first 30% reals at first and getting the first 70% fakes, it didn’t work and I was getting a sample isn't biased assertion.

  • I tried permuting the indices, then getting the first 30% indices and then sorting them to use them as an index filter for reals and fakes. It also didn’t work and I get a maintain order assertion.

  • I tried bernoulli sampling and masking such that I get 30% random reals and 70% random fakes, it also didn’t work and I get the maintain order assertion

  • I’ve also tried concatenating them in the opposite order, 70% fakes first then 30% reals but to no avail.

Here’s my best attempt

    filt = torch.bernoulli(real,  p_real)    
    reals = real[filt == 1]
    fakes = fake[filt == 0]  
    target_images = torch.cat((fakes , reals), 0).reshape(real.shape)

Hence I’d like to ask what order is required? or what could I be missing here?
Thank you in advance for the responses

@jamescasia, sorry for the delay, and kudos for your tenacity trying all those variations. This one can be tricky.

I notice a couple things in your example:

First, the way torch.bernoulli works is you should pass as input one tensor where each value in the tensor is the probability you want for that value to be 1 (vs 0). So, we want to pass it a tensor with one value for each image, where that value is the probability that image should be real. In other words, each value should be p_real. One way, for example, that you can create a tensor like this is:

torch.full(real.shape[:1], p_real)

That should get you a good filter, but the next thing you need to be careful about is to keep the images in the same order to maintain their alignment with the labels. In your example, you concatentated two lists so that you had a bunch of fakes followed by a bunch of reals. Instead, try using the hint suggested in the Optional Hints of making a clone. You can start by making target_images = a clone of either reals or fakes. Then, you can use your filter to substitute in from the other one, maintaining the position. For example, if you started with target_images as a clone of the reals, then you could substitute in fakes in the right positions using:

target_images[filt == 0] = fake[filt == 0]

So the order the problem speaks of is the index of each element based on its original array! Thank you for this @Wendy!