different data augmentation parameters every epoch

0

i'm using keras with a simple cnn model. i want to add gaussian noise to images in training. i want to change the noise parameters (mean and sigma) every epoch,based on some function. for example,

in epoch 1 i want to add noise with sigma=1
in epoch 2 i want to add noise with sigma=2
in epoch 3 i want to add noise with sigma=3
# note-mean is always zero

and so on...

inefficient way to solve it is with a for loop, save and load the mode after every epoch and call augmentation function. more efficient way will be with a custom callback or generator, which i didn't succeed to do

inefficient way:

total_num_of_epochs=100
def sigma_function(current_epoch):
     sigma_fun=current_epoch/total_num_of_epochs
     return sigma_fun

for i in range(total_num_of_epochs):
    x_train += np.random.normal(mean=0,sigma=sigma_fun(i),size=x_train shape) # augment x_train based on sigma_function and current epochs

    model.compile(...)
    model.fit(x_train ,y_train...initial_epoch=i,epochs=i+1) #load the model 
    # from previous loop
    save model
    load model for next loop

the desired result (i tried with ImageDataGenerator but maybe callback can do):

def sigma_function(current_epoch):
     sigma_fun=current_epoch/total_num_of_epochs
     return sigma_fun

datagen=ImageDataGenerator(preprocessing_function=sigma_function)
datagen.fit(x_train)


model.fit_generator(... don't know what to put here)

edit

according to the proposed solution by Daniel Möller,i tried this way and still got an error

sigmaParam = 1

def apply_sigma(x):
    return x + np.random.normal(mean=0,scale=sigmaParam,size=(3,32,32))

imgGen = ImageDataGenerator( preprocesing_function=apply_sigma)
generator = imgGen.flow_from_directory('data/train') # folder that contains 
# only x_train and y_train 


from keras.utils import Sequence

class SigmaGenerator(Sequence):

    def __init__(self, keras_generator):
        self.keras_generator = keras_generator

    def __len__(self):
        return len(self.keras_generator)

    def __getitem__(self,i):
        return self.keras_generator[i]

    def on_epoch_end(self):
        sigmaParam += 1
        self.keras_generator.on_epoch_end()

training_generator = SigmaGenerator(generator)

model.fit_generator(training_generator,validation_data=(x_test,y_test),
                steps_per_epoch=x_train.shape[0]//batch_size,epochs=100)

the error i get:

process finished with exit code -1073741819 (0xC0000005)
python
keras
asked on Stack Overflow Aug 23, 2019 by Dan • edited Aug 25, 2019 by Dan

1 Answer

1

You can try this:

sigmaParam = 1

def applySigma(x):
    return x + np.random.normal(mean=0,scale=sigmaParam,size=x.shape)

Create the original generator:

imgGen = ImageDataGenerator(..., preprocesing_function=apply_sigma)
generator = imgGen.flow_from_directory(....)

Create a custom generator to wrap the original one, replace its on_epoch_end method to update sigmaParam.

from keras.utils import Sequence

class SigmaGenerator(Sequence):

    def __init__(self, keras_generator):
        self.keras_generator = keras_generator

    def __len__(self):
        return len(self.keras_generator)

    def __getitem__(self,i):
        return self.keras_generator[i]

    def on_epoch_end(self):
        sigmaParam += 1
        self.keras_generator.on_epoch_end()

training_generator = SigmaGenerator(generator)
answered on Stack Overflow Aug 24, 2019 by Daniel Möller

User contributions licensed under CC BY-SA 3.0