```python
 #this code snippet was used to import our custom dataset
from google.colab import drive
drive.mount('/content/drive')
```

    Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).

```python
# import all necessary modules
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import librosa, librosa.display
import numpy as np
import sympy as sp
sp.init_printing(use_latex=True)
from IPython.display import display
import matplotlib.pyplot as plt
%matplotlib inline
```

```python
# set the variables to work with throughout model
img_height = 256
img_width= 256
rgb = 3
batch_size = 10
epochs = 50
```

```python
# set-up training data from the original dataset only
ods_train = tf.keras.preprocessing.image_dataset_from_directory(
    '/content/drive/MyDrive/original_data_set', # need local path to directory
    labels = 'inferred',
    label_mode = 'categorical',
    batch_size = batch_size,
    image_size = (img_height, img_height),
    shuffle = True,
    seed = 123,
    validation_split = 0.3,
    subset = 'training',
)
```

    Found 3000 files belonging to 10 classes.
    Using 2100 files for training.

```python
# set-up training data using original plus the augmented data as well
plusAugmented_train = tf.keras.preprocessing.image_dataset_from_directory(
    '/content/drive/MyDrive/plusAugmented', # need local path to directory
    labels = 'inferred',
    label_mode = 'categorical',
    batch_size = batch_size,
    image_size = (img_height, img_height),
    shuffle = True,
    seed = 123,
    validation_split = 0.3,
    subset = 'training',
)
```

    Found 32898 files belonging to 10 classes.
    Using 23029 files for training.

```python
# now create a batch to test with from original dataset
ods_test = tf.keras.preprocessing.image_dataset_from_directory(
    '/content/drive/MyDrive/original_data_set', # need local path to directory
    labels = 'inferred',
    label_mode = 'categorical',
    batch_size = batch_size,
    image_size = (img_height, img_height),
    shuffle = True,
    seed = 456,
    validation_split = 0.3,
    subset = "validation",
)
```

    Found 3000 files belonging to 10 classes.
    Using 900 files for validation.

```python
# also need a batch to test with from the original plus augmented datase
plusAugmented_test = tf.keras.preprocessing.image_dataset_from_directory(
    '/content/drive/MyDrive/plusAugmented', # need local path to directory
    labels = 'inferred',
    label_mode = 'categorical',
    batch_size = batch_size,
    image_size = (img_height, img_height),
    shuffle = True,
    seed = 456,
    validation_split = 0.3,
    subset = "validation",
)
```

    Found 32898 files belonging to 10 classes.
    Using 9869 files for validation.

```python
# the real test....
# NOW, a batch of unseen originals the plusAugmented model has not seen
unseen_test= tf.keras.preprocessing.image_dataset_from_directory(
    '/content/drive/MyDrive/unseen_originals', # need local path to directory
    labels = 'inferred',
    label_mode = 'categorical',
    batch_size = batch_size,
    image_size = (img_height, img_height),
    shuffle = True,
    seed = 456,
)
```

    Found 102 files belonging to 10 classes.

```python
#  build up model
model = keras.models.Sequential()
model.add(keras.layers.Convolution2D(32, kernel_size = (5, 5), input_shape=(img_height, img_width, rgb ), activation='relu'))
model.add(keras.layers.Convolution2D(16, kernel_size = (3, 3), activation='relu'))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(keras.layers.Dropout(0.2))
model.add(keras.layers.Reshape((125, -1)))
model.add(keras.layers.TimeDistributed(layers.Dense(100)))
model.add(keras.layers.LSTM(100, return_sequences=False))
model.add(keras.layers.Dense(10,activation = 'softmax'))
```

```python
# display model layers w/ input and output
tf.keras.utils.plot_model(model, show_shapes=True, expand_nested=True)
```

```python
#  compile model
model.compile(optimizer = keras.optimizers.Adam(),
             loss = [ keras.losses.CategoricalCrossentropy(from_logits=True)],
             metrics = [ keras.metrics.CategoricalAccuracy()])
```

```python
# show a summary of layers and the parameters
model.summary()
```

    Model: "sequential"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #
    =================================================================
    conv2d (Conv2D)              (None, 252, 252, 32)      2432
    _________________________________________________________________
    conv2d_1 (Conv2D)            (None, 250, 250, 16)      4624
    _________________________________________________________________
    batch_normalization (BatchNo (None, 250, 250, 16)      64
    _________________________________________________________________
    max_pooling2d (MaxPooling2D) (None, 125, 125, 16)      0
    _________________________________________________________________
    dropout (Dropout)            (None, 125, 125, 16)      0
    _________________________________________________________________
    reshape (Reshape)            (None, 125, 2000)         0
    _________________________________________________________________
    time_distributed (TimeDistri (None, 125, 100)          200100
    _________________________________________________________________
    lstm (LSTM)                  (None, 100)               80400
    _________________________________________________________________
    dense_1 (Dense)              (None, 10)                1010
    =================================================================
    Total params: 288,630
    Trainable params: 288,598
    Non-trainable params: 32
    _________________________________________________________________

```python
# training the original dataset
ods_history = model.fit(ods_train,
                    batch_size = batch_size,
                    epochs = epochs,
                    verbose = 1)
```

    Epoch 1/50
    210/210 [==============================] - 16s 60ms/step - loss: 2.1985 - categorical_accuracy: 0.1994
    Epoch 2/50
    210/210 [==============================] - 13s 61ms/step - loss: 1.8076 - categorical_accuracy: 0.3596
    Epoch 3/50
    210/210 [==============================] - 13s 61ms/step - loss: 1.5699 - categorical_accuracy: 0.4344
    Epoch 4/50
    210/210 [==============================] - 13s 63ms/step - loss: 1.3776 - categorical_accuracy: 0.5302
    Epoch 5/50
    210/210 [==============================] - 14s 63ms/step - loss: 1.2153 - categorical_accuracy: 0.5917
    Epoch 6/50
    210/210 [==============================] - 13s 63ms/step - loss: 1.2228 - categorical_accuracy: 0.6000
    Epoch 7/50
    210/210 [==============================] - 14s 64ms/step - loss: 1.2050 - categorical_accuracy: 0.6108
    Epoch 8/50
    210/210 [==============================] - 13s 63ms/step - loss: 1.1002 - categorical_accuracy: 0.6396
    Epoch 9/50
    210/210 [==============================] - 13s 62ms/step - loss: 1.0108 - categorical_accuracy: 0.6576
    Epoch 10/50
    210/210 [==============================] - 13s 61ms/step - loss: 0.9910 - categorical_accuracy: 0.6684
    Epoch 11/50
    210/210 [==============================] - 13s 60ms/step - loss: 0.8780 - categorical_accuracy: 0.7239
    Epoch 12/50
    210/210 [==============================] - 13s 60ms/step - loss: 0.8507 - categorical_accuracy: 0.7324
    Epoch 13/50
    210/210 [==============================] - 13s 61ms/step - loss: 0.8468 - categorical_accuracy: 0.7428
    Epoch 14/50
    210/210 [==============================] - 13s 61ms/step - loss: 0.8723 - categorical_accuracy: 0.7078
    Epoch 15/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.9129 - categorical_accuracy: 0.6928
    Epoch 16/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.7908 - categorical_accuracy: 0.7449
    Epoch 17/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.8310 - categorical_accuracy: 0.7211
    Epoch 18/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.7568 - categorical_accuracy: 0.7535
    Epoch 19/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.7254 - categorical_accuracy: 0.7633
    Epoch 20/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.6462 - categorical_accuracy: 0.7766
    Epoch 21/50
    210/210 [==============================] - 13s 60ms/step - loss: 0.6637 - categorical_accuracy: 0.7763
    Epoch 22/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.6727 - categorical_accuracy: 0.7800
    Epoch 23/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.6600 - categorical_accuracy: 0.7813
    Epoch 24/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.6160 - categorical_accuracy: 0.8011
    Epoch 25/50
    210/210 [==============================] - 13s 60ms/step - loss: 0.6095 - categorical_accuracy: 0.8071
    Epoch 26/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.5478 - categorical_accuracy: 0.8356
    Epoch 27/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.5455 - categorical_accuracy: 0.8211
    Epoch 28/50
    210/210 [==============================] - 13s 60ms/step - loss: 0.4764 - categorical_accuracy: 0.8603
    Epoch 29/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.5469 - categorical_accuracy: 0.8191
    Epoch 30/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.5579 - categorical_accuracy: 0.8189
    Epoch 31/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.5841 - categorical_accuracy: 0.8078
    Epoch 32/50
    210/210 [==============================] - 13s 60ms/step - loss: 0.5836 - categorical_accuracy: 0.8092
    Epoch 33/50
    210/210 [==============================] - 13s 58ms/step - loss: 0.5312 - categorical_accuracy: 0.8281
    Epoch 34/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.5205 - categorical_accuracy: 0.8249
    Epoch 35/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.4781 - categorical_accuracy: 0.8520
    Epoch 36/50
    210/210 [==============================] - 13s 60ms/step - loss: 0.4859 - categorical_accuracy: 0.8465
    Epoch 37/50
    210/210 [==============================] - 13s 58ms/step - loss: 0.4388 - categorical_accuracy: 0.8530
    Epoch 38/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.4737 - categorical_accuracy: 0.8484
    Epoch 39/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.4537 - categorical_accuracy: 0.8574
    Epoch 40/50
    210/210 [==============================] - 13s 58ms/step - loss: 0.3783 - categorical_accuracy: 0.8761
    Epoch 41/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.3696 - categorical_accuracy: 0.8820
    Epoch 42/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.5071 - categorical_accuracy: 0.8319
    Epoch 43/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.4509 - categorical_accuracy: 0.8564
    Epoch 44/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.4206 - categorical_accuracy: 0.8599
    Epoch 45/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.4481 - categorical_accuracy: 0.8515
    Epoch 46/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.3741 - categorical_accuracy: 0.8804
    Epoch 47/50
    210/210 [==============================] - 13s 60ms/step - loss: 0.3598 - categorical_accuracy: 0.8770
    Epoch 48/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.3476 - categorical_accuracy: 0.8827
    Epoch 49/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.3824 - categorical_accuracy: 0.8696
    Epoch 50/50
    210/210 [==============================] - 13s 59ms/step - loss: 0.3798 - categorical_accuracy: 0.8693

```python
# how did we do?
# graphically display results of training and testing
plt.figure()
plt.subplot(211)
plt.plot(ods_history.history['categorical_accuracy'])
plt.title('Using Only Original Data: Model Accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['training'], loc = 'upper left')

plt.subplot(212)
plt.plot(ods_history.history['loss'])
plt.title('Using Only Origianl Data: Model Loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['training'], loc = 'upper right')

plt.tight_layout()
plt.show()
```

```python
# go ahead and save the model here
model.save("ods_32_d.h5")
```

```python
# now test the model against the reserved unseen images from the original dataset
ods_t = model.evaluate(ods_test, verbose = 1)
print("Using only original unseen samples:")
print("Accuracy: ", ods_t[1] * 100)
print("Loss: ", ods_t[0])
```

    90/90 [==============================] - 5s 43ms/step - loss: 0.5985 - categorical_accuracy: 0.8011
    Using only original unseen samples:
    Accuracy:  80.1111102104187
    Loss:  0.5984845161437988

```python
# next, we need to train with the original plus the augmented data on the exact same architecture
plusAugmented_history = model.fit(plusAugmented_train,
                    batch_size = batch_size,
                    epochs = epochs,
                    verbose = 1)
```

    Epoch 1/50
    2303/2303 [==============================] - 141s 61ms/step - loss: 1.2448 - categorical_accuracy: 0.6015
    Epoch 2/50
    2303/2303 [==============================] - 142s 62ms/step - loss: 1.0001 - categorical_accuracy: 0.6659
    Epoch 3/50
    2303/2303 [==============================] - 147s 64ms/step - loss: 0.9219 - categorical_accuracy: 0.6958
    Epoch 4/50
    2303/2303 [==============================] - 146s 63ms/step - loss: 0.8544 - categorical_accuracy: 0.7167
    Epoch 5/50
    2303/2303 [==============================] - 147s 64ms/step - loss: 0.8145 - categorical_accuracy: 0.7293
    Epoch 6/50
    2303/2303 [==============================] - 147s 64ms/step - loss: 0.7268 - categorical_accuracy: 0.7588
    Epoch 7/50
    2303/2303 [==============================] - 147s 64ms/step - loss: 0.7168 - categorical_accuracy: 0.7646
    Epoch 8/50
    2303/2303 [==============================] - 148s 64ms/step - loss: 0.6706 - categorical_accuracy: 0.7776
    Epoch 9/50
    2303/2303 [==============================] - 147s 64ms/step - loss: 0.6285 - categorical_accuracy: 0.7934
    Epoch 10/50
    2303/2303 [==============================] - 148s 64ms/step - loss: 0.5881 - categorical_accuracy: 0.8061
    Epoch 11/50
    2303/2303 [==============================] - 148s 64ms/step - loss: 0.5617 - categorical_accuracy: 0.8121
    Epoch 12/50
    2303/2303 [==============================] - 142s 61ms/step - loss: 0.6013 - categorical_accuracy: 0.7988
    Epoch 13/50
    2303/2303 [==============================] - 142s 62ms/step - loss: 0.5037 - categorical_accuracy: 0.8329
    Epoch 14/50
    2303/2303 [==============================] - 145s 63ms/step - loss: 0.7385 - categorical_accuracy: 0.7595
    Epoch 15/50
    2303/2303 [==============================] - 146s 63ms/step - loss: 0.5494 - categorical_accuracy: 0.8176
    Epoch 16/50
    2303/2303 [==============================] - 147s 64ms/step - loss: 0.5320 - categorical_accuracy: 0.8244
    Epoch 17/50
    2303/2303 [==============================] - 145s 63ms/step - loss: 0.5033 - categorical_accuracy: 0.8343
    Epoch 18/50
    2303/2303 [==============================] - 146s 63ms/step - loss: 0.4641 - categorical_accuracy: 0.8478
    Epoch 19/50
    2303/2303 [==============================] - 146s 63ms/step - loss: 0.4581 - categorical_accuracy: 0.8483
    Epoch 20/50
    2303/2303 [==============================] - 150s 65ms/step - loss: 0.4353 - categorical_accuracy: 0.8567
    Epoch 21/50
    2303/2303 [==============================] - 151s 66ms/step - loss: 0.4247 - categorical_accuracy: 0.8572
    Epoch 22/50
    2303/2303 [==============================] - 147s 64ms/step - loss: 0.4126 - categorical_accuracy: 0.8633
    Epoch 23/50
    2303/2303 [==============================] - 144s 62ms/step - loss: 0.3769 - categorical_accuracy: 0.8766
    Epoch 24/50
    2303/2303 [==============================] - 142s 61ms/step - loss: 0.3848 - categorical_accuracy: 0.8731
    Epoch 25/50
    2303/2303 [==============================] - 143s 62ms/step - loss: 0.3756 - categorical_accuracy: 0.8765
    Epoch 26/50
    2303/2303 [==============================] - 143s 62ms/step - loss: 0.3608 - categorical_accuracy: 0.8793
    Epoch 27/50
    2303/2303 [==============================] - 143s 62ms/step - loss: 0.3639 - categorical_accuracy: 0.8790
    Epoch 28/50
    2303/2303 [==============================] - 143s 62ms/step - loss: 0.3475 - categorical_accuracy: 0.8858
    Epoch 29/50
    2303/2303 [==============================] - 142s 61ms/step - loss: 0.3382 - categorical_accuracy: 0.8885
    Epoch 30/50
    2303/2303 [==============================] - 141s 61ms/step - loss: 0.3393 - categorical_accuracy: 0.8868
    Epoch 31/50
    2303/2303 [==============================] - 142s 61ms/step - loss: 0.3247 - categorical_accuracy: 0.8931
    Epoch 32/50
    2303/2303 [==============================] - 140s 61ms/step - loss: 0.3300 - categorical_accuracy: 0.8893
    Epoch 33/50
    2303/2303 [==============================] - 143s 62ms/step - loss: 0.3284 - categorical_accuracy: 0.8902
    Epoch 34/50
    2303/2303 [==============================] - 144s 63ms/step - loss: 0.3189 - categorical_accuracy: 0.8966
    Epoch 35/50
    2303/2303 [==============================] - 143s 62ms/step - loss: 0.3142 - categorical_accuracy: 0.8968
    Epoch 36/50
    2303/2303 [==============================] - 141s 61ms/step - loss: 0.3026 - categorical_accuracy: 0.9006
    Epoch 37/50
    2303/2303 [==============================] - 145s 63ms/step - loss: 0.3047 - categorical_accuracy: 0.9011
    Epoch 38/50
    2303/2303 [==============================] - 145s 63ms/step - loss: 0.3159 - categorical_accuracy: 0.8966
    Epoch 39/50
    2303/2303 [==============================] - 146s 63ms/step - loss: 0.3408 - categorical_accuracy: 0.8895
    Epoch 40/50
    2303/2303 [==============================] - 146s 63ms/step - loss: 0.2838 - categorical_accuracy: 0.9063
    Epoch 41/50
    2303/2303 [==============================] - 147s 64ms/step - loss: 0.2766 - categorical_accuracy: 0.9082
    Epoch 42/50
    2303/2303 [==============================] - 148s 64ms/step - loss: 0.2979 - categorical_accuracy: 0.9014
    Epoch 43/50
    2303/2303 [==============================] - 146s 63ms/step - loss: 0.3041 - categorical_accuracy: 0.8980
    Epoch 44/50
    2303/2303 [==============================] - 147s 64ms/step - loss: 0.2905 - categorical_accuracy: 0.9026
    Epoch 45/50
    2303/2303 [==============================] - 146s 63ms/step - loss: 0.2979 - categorical_accuracy: 0.9025
    Epoch 46/50
    2303/2303 [==============================] - 149s 64ms/step - loss: 0.3049 - categorical_accuracy: 0.9015
    Epoch 47/50
    2303/2303 [==============================] - 147s 64ms/step - loss: 0.2848 - categorical_accuracy: 0.9062
    Epoch 48/50
    2303/2303 [==============================] - 149s 64ms/step - loss: 0.2928 - categorical_accuracy: 0.9023
    Epoch 49/50
    2303/2303 [==============================] - 148s 64ms/step - loss: 0.3199 - categorical_accuracy: 0.8925
    Epoch 50/50
    2303/2303 [==============================] - 151s 65ms/step - loss: 0.2840 - categorical_accuracy: 0.9084

```python
# save one last time
model.save("pA_32_c.h5")
```

```python
# how did we do?
# graphically display results of training
plt.figure()
plt.subplot(211)
plt.plot(plusAugmented_history.history['categorical_accuracy'])
plt.title('Using Augmented Plus Origianl Data: Model Accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['training'], loc = 'upper left')

plt.subplot(212)
plt.plot(plusAugmented_history.history['loss'])
plt.title('Using Augmented Plus Original Data: Model Loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['training'], loc = 'upper right')

plt.tight_layout()
plt.show()
plt.show()
```

```python
# now let's test with unseen images from the augmented plus original dataset
plusAugment_history_test = model.evaluate(plusAugmented_test, verbose = 1)
print("Using the augmented plus original samples:")
print("Accuracy: ", plusAugment_history_test[1] * 100)
print("Loss: ", plusAugment_history_test[0])
```

    987/987 [==============================] - 50s 51ms/step - loss: 0.2230 - categorical_accuracy: 0.9245
    Using the augmented plus original samples:
    Accuracy:  92.45110750198364
    Loss:  0.22302104532718658

```python
# NOW, let's test the plusAugmented model with 100 super secret unseen original images
unseen_test_history = model.evaluate(unseen_test, verbose = 1)
print("Using unseen originals only:")
print("Accuracy: ", unseen_test_history[1] * 100)
print("Loss: ", unseen_test_history[0])
```

    11/11 [==============================] - 1s 20ms/step - loss: 0.1813 - categorical_accuracy: 0.9510
    Using unseen originals only:
    Accuracy:  95.09803652763367
    Loss:  0.1812841147184372