Learn practical skills, build real-world projects, and advance your career
# ATTENTION: Please do not alter any of the provided code in the exercise. Only add your own code where indicated
# ATTENTION: Please do not add or remove any cells in the exercise. The grader will check specific cells based on the cell position.
# ATTENTION: Please use the provided epoch values when training.

import csv
import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from os import getcwd
def get_data(filename):
  # You will need to write code that will read the file passed
  # into this function. The first line contains the column headers
  # so you should ignore it
  # Each successive line contians 785 comma separated values between 0 and 255
  # The first value is the label
  # The rest are the pixel values for that picture
  # The function will return 2 np.array types. One with all the labels
  # One with all the images
  #
  # Tips: 
  # If you read a full line (as 'row') then row[0] has the label
  # and row[1:785] has the 784 pixel values
  # Take a look at np.array_split to turn the 784 pixels into 28x28
  # You are reading in strings, but need the values to be floats
  # Check out np.array().astype for a conversion
    with open(filename) as training_file:
        reader = csv.reader(training_file, delimiter=',')    
        imgs = []
        labels = []

        next(reader, None)
        
        for row in reader:
            label = row[0]
            data = row[1:]
            img = np.array(data).reshape((28, 28))

            imgs.append(img)
            labels.append(label)

        images = np.array(imgs).astype(float)
        labels = np.array(labels).astype(float)
            
    return images, labels

path_sign_mnist_train = f"{getcwd()}/../tmp2/sign_mnist_train.csv"
path_sign_mnist_test = f"{getcwd()}/../tmp2/sign_mnist_test.csv"
training_images, training_labels = get_data(path_sign_mnist_train)
testing_images, testing_labels = get_data(path_sign_mnist_test)

# Keep these
print(training_images.shape)
print(training_labels.shape)
print(testing_images.shape)
print(testing_labels.shape)

# Their output should be:
# (27455, 28, 28)
# (27455,)
# (7172, 28, 28)
# (7172,)
(27455, 28, 28) (27455,) (7172, 28, 28) (7172,)
# In this section you will have to add another dimension to the data
# So, for example, if your array is (10000, 28, 28)
# You will need to make it (10000, 28, 28, 1)
# Hint: np.expand_dims

training_images = np.expand_dims(training_images, axis=3)
testing_images = np.expand_dims(testing_images, axis=3)
# Create an ImageDataGenerator and do Image Augmentation
train_datagen = ImageDataGenerator(
    # Your Code Here
    rescale=1. / 255,
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest'
    )

validation_datagen = ImageDataGenerator(
    # Your Code Here
    rescale=1 / 255)

# Keep These
print(training_images.shape)
print(testing_images.shape)
    
# Their output should be:
# (27455, 28, 28, 1)
# (7172, 28, 28, 1)
(27455, 28, 28, 1) (7172, 28, 28, 1)
# Define the model
# Use no more than 2 Conv2D and 2 MaxPooling2D
model = tf.keras.models.Sequential([
    # Your Code Here
    tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(2,2),
    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(512, activation='relu'),
    tf.keras.layers.Dense(26, activation='softmax')
])

train_generator = train_datagen.flow(
    training_images,
    training_labels,
    batch_size=64
)

validation_generator = validation_datagen.flow(
    testing_images,
    testing_labels,
    batch_size=64
)

# Compile Model. 
model.compile(optimizer='adam',
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy'])

# Train the Model
history = model.fit_generator(train_generator, epochs=15, steps_per_epoch=len(training_images) / 32, validation_data = validation_generator, verbose = 1, validation_steps=len(testing_images) / 32)

model.evaluate(testing_images, testing_labels, verbose=0)
Epoch 1/15 858/857 [==============================] - 86s 100ms/step - loss: 2.4702 - accuracy: 0.2386 - val_loss: 1.5848 - val_accuracy: 0.4684 Epoch 2/15 858/857 [==============================] - 88s 102ms/step - loss: 1.6553 - accuracy: 0.4654 - val_loss: 0.9561 - val_accuracy: 0.6425 Epoch 3/15 858/857 [==============================] - 83s 96ms/step - loss: 1.2524 - accuracy: 0.5906 - val_loss: 0.7302 - val_accuracy: 0.7380 Epoch 4/15 858/857 [==============================] - 85s 99ms/step - loss: 1.0167 - accuracy: 0.6658 - val_loss: 0.6487 - val_accuracy: 0.7592 Epoch 5/15 858/857 [==============================] - 85s 100ms/step - loss: 0.8620 - accuracy: 0.7151 - val_loss: 0.4804 - val_accuracy: 0.8294 Epoch 6/15 858/857 [==============================] - 86s 100ms/step - loss: 0.7514 - accuracy: 0.7516 - val_loss: 0.3934 - val_accuracy: 0.8545 Epoch 7/15 858/857 [==============================] - 86s 100ms/step - loss: 0.6563 - accuracy: 0.7813 - val_loss: 0.3426 - val_accuracy: 0.8681 Epoch 8/15 858/857 [==============================] - 85s 99ms/step - loss: 0.5885 - accuracy: 0.8058 - val_loss: 0.4114 - val_accuracy: 0.8567 Epoch 9/15 858/857 [==============================] - 85s 99ms/step - loss: 0.5313 - accuracy: 0.8211 - val_loss: 0.2891 - val_accuracy: 0.8927 Epoch 10/15 858/857 [==============================] - 87s 102ms/step - loss: 0.4931 - accuracy: 0.8372 - val_loss: 0.2916 - val_accuracy: 0.8998 Epoch 11/15 858/857 [==============================] - 89s 104ms/step - loss: 0.4535 - accuracy: 0.8490 - val_loss: 0.2854 - val_accuracy: 0.9054 Epoch 12/15 858/857 [==============================] - 88s 102ms/step - loss: 0.4255 - accuracy: 0.8605 - val_loss: 0.1837 - val_accuracy: 0.9357 Epoch 13/15 858/857 [==============================] - 87s 101ms/step - loss: 0.3976 - accuracy: 0.8673 - val_loss: 0.2250 - val_accuracy: 0.9268 Epoch 14/15 858/857 [==============================] - 86s 100ms/step - loss: 0.3761 - accuracy: 0.8752 - val_loss: 0.2505 - val_accuracy: 0.9180 Epoch 15/15 858/857 [==============================] - 86s 101ms/step - loss: 0.3514 - accuracy: 0.8828 - val_loss: 0.1480 - val_accuracy: 0.9493
[72.13029154039799, 0.81915784]
# Plot the chart for accuracy and loss on both training and validation
%matplotlib inline
import matplotlib.pyplot as plt
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(len(acc))


plt.plot(epochs, acc, 'r', label='Training accuracy')
plt.plot(epochs, val_acc, 'b', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()

plt.plot(epochs, loss, 'r', label='Training Loss')
plt.plot(epochs, val_loss, 'b', label='Validation Loss')
plt.title('Training and validation loss')
plt.legend()

plt.show()
Notebook Image
Notebook Image