How to save .npy with the same name of the image source?

Hi,

I have a custom Dataset and Dataloader that work fine:
My image’s names are the labels, so I must extract them as targets.
train_dir contains train images:
train_dir = "./Train"
train_files = glob.glob(train_dir + '/*.jpg')

My dataset contains about 30,000 images.
I have a function (extract_single) that extracts features from every image. I want to save them as .npy and feed them to my CNN model (instead of the images). Because extracting features in every training makes the training time very long

1- How can I save the .npy file with the same name as the original input file? So the input file is called D01_nature.jpg and the output file should be called D01_nature.npy.

I know the following code is not correct:

train_files = glob.glob(train_dir + '/*.jpg')
transform = transforms.Lambda(extract_single)
for i in range(0, len(train_files)):
    x = Image.open(train_files[i])
    y = transform(x)
    np.save('./train_npy/'+ str(image_name.npy), x)

2- When I have .npy files instead .jpg, do these data need transforms.Normalize yet? If yes, How do I calculate mean and std? Images are 3 channels, but the .npy file is 1 channel)

3- I want to use the random crop for training inputs, do I have to use it for validation data as well? for example if my inputs are 256*256, can I use transforms.Resize
to have the size of 256 for validation data or should I use the same random crop for better accuracy?

1 Like
  1. The first step is to validate if your images are read correctly and the features are extracted properly (Try to validate this for a few images). Once it is verified that the code works fine, use np.save to save the features.
    For this, you need to extract the file name from each path train_files[i] and modify it. Here is one way to do it -
import os
train_files = glob.glob(train_dir + '/*.jpg')
transform = transforms.Lambda(extract_single)
for i in range(0, len(train_files)):
    x = Image.open(train_files[i])
    y = transform(x)
    file_name = os.path.basename(train_files[i])[:-4] # Get file name and remove extension
    ftr_file_name = file_name + ".npy" # Add new extension
    np.save(f'./train_npy/{ftr_file_name}', y) # Use f-string to specify file path
  1. Can you extract the features from the normalized images? That will help you to standardize the preprocessing step. Otherwise, you can still use transforms.Normalize and specify the mean and std for just one channel instead of 3 (provided the extracted features have shape H x W x 1, i.e. they represent an image).

  2. Usually, random crop is only applied to the training data since the validation and test data should not be augmented. The validation dataset contains unseen samples from the true data distribution, so it should not be modified using random crop. Instead, you can use random crop with padding for the training set so that you do not need to resize images in the validation set. Refer to the train and test transforms mentioned here for more details.

1 Like

Dear @tataganesh, thank you for your great explanations.

1- Thanks for your code to extract the names of the images. I’ll try it.

2- How can I extract features from normalized images? Because transformation is something like this:

my_transform = transforms.Compose([
    transforms.Lambda(extract_single),
    transforms.ToTensor(),
    transforms.Normalize([0.4786, 0.4728, 0.4528], [0.2425, 0.2327, 0.2564])
])

I mean, transforms.Normalize is the last step. So how can it affect transforms.Lambda(extract_single) step? It’s after feature extraction. Changing the order of the transforms is correct?

my_transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize([0.4786, 0.4728, 0.4528], [0.2425, 0.2327, 0.2564]),
    transforms.Lambda(extract_single)
])

How can I specify the mean and std for just one channel? There are 3 numbers for mean and std. Which number must be chosen for one channel?

3- My images are not the same size, so is padding applicable yet?

4- If I should extract features from the validation images? I mean extract_single function should be used for valid data?

  • Changing the order of transforms is fine as long as you are okay with extracting features from the normalized image. If you want to normalize the extracted features, you need to calculate the mean and stdev of the features after performing feature extraction for all images, then normalize them.

  • This is a good example of performing resize + crop if your images are not the same size.

  • Yes, you should use extract_single function to extract features from the validation dataset. You should ensure that no random augmentations are applied to the validation set, since the randomness is only required for the training set.

1 Like