I have a set of images, which are quite large in size (1000x1000), and as such do not easily fit into memory. I'd like to compress these images, such that little information is missing. I am looking to use a CNN for a reinforcement learning task which involves a lot of very small objects which may disappear when downsampling. What is the best approach to handle this without downscaling/downsampling the image and losing information for CNNs?
Your input image size and memory are not directly related. While using CNN's, there are multiple hyperparameters that effect the video memory(if you are using GPU) or physical memory(if you are using CPU). All the frameworks these days uses a simplified data-loaders, for instance in Tensorflow or PyTorch, you are required to write a data-loader that takes in multiple hyper-parameters that are mentioned below and fit the data into VRAM/RAM, and this is strictly dependent upon you batch size - memory occupied on VRAM has direct relation to the batch size.
Whatever may be your image size, while you are writing the data-loader you have to mention the transformation parameters to your data-loader, during the training phase the data-loader will automatically load required images into your memory according to the batch size you have mentioned. As you have mentioned about image compression, this is an irrelevant parameter at-least for most of the generic use-cases, the most relevant hyperparameters are
- Random flip
- Normalization of the RGB values
And many more.
PyTorch provides really good transformers in data-loader, please do check https://pytorch.org/docs/stable/torchvision/transforms.html.
For Tensorflow, have a look at https://keras.io/preprocessing/image/.
Tensorflow-Keras provides an effective data transformer and loader. Documentation is at https://keras.io/preprocessing/image/. The ImageDataGenerator provides for many types of possible transforms and also enables use of a user defined pre-process function. Use of the ImageDataGenerator.flow_from_directory provides a means of retrieving images in batches from a directory containing sub directories (classes) of images. and resizing the images. Image size can impact the results. Generally the larger the image the better the result but this is subject to the law of diminishing returns (at some point the impact on accuracy becomes minuscule) while the training time can become absorbent. When you have large images like 1000 X 1000 where the subject of interest in the image is small say 50 X 50 the best but most painful approach is the crop the image to the subject of interest. Unfortunately this is usually a time consuming drudgery unless you can find some program that can crop the image automatically. For example there are good programs that can crop images of people automatically where the resultant cropped image is primarily the persons face. Alternatively modules like cv2 can be adapted to provide this capability for certain images. The batch_size you select along with the image size directly effect memory usage. If your images are large and your batch_size is too large you will encounter a "resource exhaust" error. You can reduce the batch size but this will extend training time. Other techniques for dealing with large images include methods like sliding windows etc. Again these will increase training time because you are taking a large image and breaking it into a series of smaller images that you feed into the network. A general though probably risky rule I follow is that if I can visibly see the subject of interest in a resized image then I assume the network will be able to detect it as well. Will probably be less accurate than using the full image but should be as we engineers say "good enough"