Deterministic data augmentation - Keras 2.2.0
In a previous post, I showed how to use Keras-Transform, a library I created to perform data augmentation on segmentation datasets. After discussion with Francois Chollet, I think that his idea is much better and it’s been recently merged on Keras. I was excited to try it out!
The code is available in this gist.
High-level
Instead of building a pipeline of Sequences (like in Keras-Transform), the data augmentation will be done inside one. So we should get something like this :
class MySequence(keras.utils.Sequence):
def __init__(self):
...
def __getitem__(self, idx):
X, y = ... # Get the inputs
for i in len(X):
rotation = get_random_rotation()
# Apply the same transformation to X and y
X[i] = rotate_image(X[i], rotation)
y[i] = rotate_image(y[i]. rotation)
return X, y
In Keras 2.1.7
Thanks to vkk800, this API has made it into Keras and is now released. Here’s a simple example.
We first import OpenCV and the updated ImageDataGenerator
import cv2
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
We only need to inherit a Sequence. Since this is an example, this will only return a batch of cats.
class MySequence(Sequence):
def __init__(self):
self.path = '~Images/cat.jpg'
self.imgaug = ImageDataGenerator(rotation_range=20,
rescale=1/255.,
width_shift_range=10)
def __len__(self):
return 10
def __getitem__(self, idx):
X = np.array([cv2.resize(cv2.imread(self.path), (100, 100))
for _ in range(10)]).astype(np.float32) # Fake batch of cats
y = np.copy(X)
for i in range(len(X)):
# This creates a dictionary with the params
params = self.imgaug.get_random_transform(X[i].shape)
# We can now deterministicly augment all the images
X[i] = self.imgaug.apply_transform(self.imgaug.standardize(X[i]), params)
y[i] = self.imgaug.apply_transform(self.imgaug.standardize(y[i]), params)
return X, y
Results
Using this Sequence
, we can get the following results. (X
is on the top row and y
on the second)
Making this work for a real-life application is really easy!
For example, we can use the params
variable in other situations like bounding boxes augmentation.
The code is available in this gist.
Thank you for reading and I’m always available on Keras’ Slack (@Dref360) if you have any question!
Cheers, Frédéric Branchaud-Charron