If you haven't used a generator before, it works like an iterator. Every time you call the ImageDataGenerator .flow() method, it will produce a new training minibatch, with random transformations applied to the images it was fed.
The Keras Model class comes with a .fit_generator() method that allows us to fit with a generator rather than a given dataset:
model.fit_generator(data_generator.flow(data["train_X"], data["train_y"], batch_size=32), steps_per_epoch=len(data["train_X"]) // 32, epochs=200, validation_data=(data["val_X"], data["val_y"]), verbose=1, callbacks=callbacks)
Here, we've replaced the traditional x and y parameters with the generator. Most importantly, notice the steps_per_epoch parameter. You can ...