title: Am I doing data augmentation correctly?
body: <p>I was told that using data augmentation would help me get more accurate predictions on handwritten digits I've extracted from a document (so it's not in the MNIST dataset I'm using), so I used it in my model. However, I'm curious if I did it correctly, as the size of the training set before using data augmentation is 60000, but after adding data augmentation it went down to 3750 per epoch? Am I doing this correctly?</p>
  
  <p>Following the data augmentation part of <a href="https://www.kaggle.com/moghazy/guide-to-cnns-with-data-augmentation-keras" rel="nofollow noreferrer">this tutorial</a>, I've adjusted it such that it will work on how I create and train my model. I've also left out optional parameters in the functions that I don't really understand as of the moment.</p>
  
  <p>The current model I'm using is from one of the answers I got from <a href="https://stackoverflow.com/questions/55849555/how-would-i-improve-my-model-such-that-it-will-work-on-more-characters-not-in-th">my previous question</a> as it performs better than the second model I've cobbled together for the sake of trying. I think the only change I made is to make it use <code>sparse_categorical_crossentropy</code> instead for loss, as I'm categorizing digits and handwritten characters can't belong to two categories of digits, uh, right?</p>
  
  <pre class="lang-py prettyprint-override"><code>def createModel():
      model = keras.models.Sequential()
  
      # 1st conv &amp; maxpool
      model.add(keras.layers.Conv2D(40, (5, 5), padding="same", activation='relu', input_shape=(28, 28, 1)))
      model.add(keras.layers.MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
  
      # 2nd conv &amp; maxpool
      model.add(keras.layers.Conv2D(200, (3, 3), padding="same", activation='relu'))
      model.add(keras.layers.MaxPooling2D(pool_size=(3, 3), strides=(1,1)))
  
      # 3rd conv &amp; maxpool
      model.add(keras.layers.Conv2D(512, (3, 3), padding="valid", activation='relu'))
      model.add(keras.layers.MaxPooling2D(pool_size=(3, 3), strides=(1,1)))
  
      # reduces dims from 2d to 1d
      model.add(keras.layers.Flatten())
      model.add(keras.layers.Dense(units=100, activation='relu'))
  
      # dropout for preventing overfitting
      model.add(keras.layers.Dropout(0.5))
  
      # final fully-connected layer
      model.add(keras.layers.Dense(10, activation='softmax'))
  
      model.compile(optimizer='adam',
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])
  
      return model
  </code></pre>
  
  <p>Training is done by a separate function, and this is where I plugged in the data augmentation part:</p>
  
  <pre class="lang-py prettyprint-override"><code>def trainModel(file_model, epochs=5, create_new=False, show=False):
      model = createModel()
  
      (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
  
      x_train = x_train.reshape((60000, 28, 28, 1)) / 255.0
      x_test = x_test.reshape((10000, 28, 28, 1)) /255.0
  
      x_gen = np.array(x_train, copy=True)
      y_gen = np.array(y_train, copy=True)
  
      datagen = keras.preprocessing.image.ImageDataGenerator(featurewise_center=True, featurewise_std_normalization=True, rotation_range=20)
      datagen.fit(x_gen)
  
      x_train = np.concatenate((x_train, x_gen), axis=0)
      y_train = np.concatenate((y_train, y_gen), axis=0) 
  
      # if prev model exists and new model isn't needed..
      if (os.path.exists(file_model)==True and create_new==False):
          model = keras.models.load_model(file_model)
      else:
          history = model.fit_generator(datagen.flow(x_train, y_train), epochs=epochs, validation_data=(x_test, y_test))
          model.save(file_model)
  
      if (show==True):
          model.summary()
  
      return model
  </code></pre>
  
  <p>I would expect it will greatly help with correctly identifying the handwritten characters assuming it was used correctly. But I'm not even sure if I did it correctly such that it contributes a lot on the model's accuracy.</p>
  
  <p>EDIT: It did help a bit in identifying some of the extracted characters, but the model still didn't get the majority of the extracted characters right, leading me to doubt if I have implemented it properly..</p>