In the previous blog, we discussed how to perform data augmentation using ImageDataGenerator. In that, we saw that some transformations require statistics of the entire dataset. These transformations include featurewise_center, featurewise_std_normalization and zca_whitening.
To calculate these statistics, first of all, one may need to load the entire dataset into the memory. Then calculate the mean, standard deviation, principal components or any other statistics from that data. Fortunately, Keras has a built-in fit method for doing this. Let’s discuss it in detail.
Keras API
1 |
fit(x, augment=False, rounds=1, seed=None) |
Here, x is the data from which to calculate the statistics. Should have rank 4. Note that the channel axis of x should have value either 1, 3, or 4 depending upon whether the data is greyscale, RGB, or RGBA.
This also provides an option of whether to use the augmented data for calculating statistics or not. This is done using the “augment” argument. If True, then augmented examples are also used for calculating statistics. The number of augmented examples depends upon the “rounds” parameter. For instance, if “rounds=2” and x.shape[0] or data size is 64, then 128 augmented examples are used.
Below code shows its implementation (taken from Keras). First of all, create an array of zeros to handle the augmented examples. Then generate the augmented examples using the random_transform method and append to this array.
1 2 3 4 5 6 7 8 |
if augment: ax = np.zeros( tuple([rounds * x.shape[0]] + list(x.shape)[1:]), dtype=self.dtype) for r in range(rounds): for i in range(x.shape[0]): ax[i + r * x.shape[0]] = self.random_transform(x[i]) x = ax |
Here, x is the training data or the data whose statistics we want to calculate. Once we have the data, we can easily calculate the statistics such as mean, standard deviation and principal components using Numpy and Scipy libraries.
Note: Statistics are calculated across all channels in an image. So, don’t calculate the mean separately for each channel.
Now, when we generate batches of augmented data using any method (like flow) these statistics are used to normalize the data as shown below
1 2 3 |
if self.featurewise_center: if self.mean is not None: x -= self.mean |
How to use this?
Let’s take the MNIST digit classification example. Suppose we want to center the distribution i.e. mean equal to 0. For this, we will use the ImageDataGenerator “featurewise_center” transformation. Firstly, load the data and preprocess it.
1 2 3 4 5 6 7 8 9 10 11 |
from keras.datasets import mnist import numpy as np from keras.preprocessing.image import ImageDataGenerator (x_train, y_train),(x_test, y_test) = mnist.load_data() train_x = x_train.astype('float32') test_x = x_test.astype('float32') train_x = np.expand_dims(train_x, axis=-1) test_x = np.expand_dims(test_x, axis=-1) |
After loading the data, firstly, create an ImageDataGenerator instance. Then fit the training data as shown below
1 2 |
datagen = ImageDataGenerator(featurewise_center=True) datagen.fit(train_x) |
Let’s calculate the mean of the training data manually and using “datagen” mean attribute.
1 2 |
print(train_x.mean()) print(datagen.mean) |
As expected these should be the same i.e 33.318447. Now, let’s see what happens to the mean of the distribution after normalization.
1 2 3 4 |
datagenerator = datagen.flow(train_x,y_train,batch_size=len(train_x)) for x,y in datagenerator: print(x.mean()) # -2.752179e-05 break |
Clearly, this centers the distribution. Similarly, we can perform other types of normalizations also.
Hope you enjoy reading.
If you have any doubt/suggestion please feel free to ask and I will do my best to help or improve myself. Good-bye until next time.