Basic DL on MNIST

import tensorflow as tf

# stop the training with condition
class myCallback(tf.keras.callbacks.Callback):
    def on_epoch_end(self, epoch, logs={}): # compare at the end of each epoch
        if(logs.get('accuracy') > 0.99):
            self.model.stop_training = True

mnist = tf.keras.datasets.mnist
(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0 # normalize

callbacks = myCallback() # define the callback

model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)), # Takes that square and
                                                   # turns it into a 1 dim
    tf.keras.layers.Dense(512, activation=tf.nn.relu),
    tf.keras.layers.Dense(10, activation=tf.nn.softmax) # 10 outputs
])

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

model.fit(x_train, y_train, epochs=10, callbacks=[callbacks])

Comments (notebook):

  1. Adding more Neurons we have to do more calculations, slowing down the process, but get more accurate.
  2. The first layer in your network should be the same shape as your data.
  3. The number of neurons in the last layer should match the number of classes you are classifying for.
  4. Extra layers are often necessary.
  5. Flatten as the name implies, converts your multidimensional matrices (Batch.Size x Img.W x Img.H x Kernel.Size) to a nice single 2-dimensional matrix: (Batch.Size x (Img.W x Img.H x Kernel.Size)). During backpropagation it also converts back your delta of size (Batch.Size x (Img.W x Img.H x Kernel.Size)) to the original (Batch.Size x Img.W x Img.H x Kernel.Size).
  6. Dense layer is of course the standard fully connected layer.

CNN layers, cource of image.

CNN layers, cource of image.

Basic DL on Fashion-MNIST

# the same as in MINST
# different at below line of loading data
mnist = tf.keras.datasets.fashion_mnist

Basic CNN on Fashion-MNIST

import tensorflow as tf
mnist = tf.keras.datasets.fashion_mnist

class myCallback(tf.keras.callbacks.Callback):
    def on_epoch_end(self, epochs, logs={}) :
        if(logs.get('accuracy') is not None and logs.get('accuracy') >= 0.998) :
            print('\\\\nReached 99.8% accuracy so cancelling training!')
            self.model.stop_training = True

(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
# Why reshape?
# The first convolution expects a single tensor containing everything,
# so instead of 60000 28x28x1 items in a list, we have a single 4D list
# that is 60000x28x28x1
#
# training_images' shape (before reshape): (60000, 28, 28)
# training_images' shape (after reshape): (60000, 28, 28, 1)
# trainaing_labels' shape: (60000,)
training_images=training_images.reshape(60000, 28, 28, 1)
training_images=training_images / 255.0
test_images = test_images.reshape(10000, 28, 28, 1)
test_images=test_images/255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(28, 28, 1)),
  tf.keras.layers.MaxPooling2D(2, 2),
  tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
  tf.keras.layers.MaxPooling2D(2,2),
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(10, activation='softmax')
])

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

callbacks = myCallback()

model.fit(training_images, training_labels, epochs=5, callbacks=[callbacks])
test_loss = model.evaluate(test_images, test_labels)
model.summary() # model detail
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param
=================================================================
conv2d (Conv2D)              (None, 26, 26, 64)        640
                             # for every image, 64 convolution has been tried
                             # 26 (=28-2) because we use 3x3 filter and we can't
                             # count on edges, so the picture is 2 smaller on x and y.
                             # if 5x5 filter => 4 smaller on x and y.
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 13, 13, 64)        0
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 11, 11, 64)        36928
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 5, 5, 64)          0
_________________________________________________________________
flatten_1 (Flatten)          (None, 1600)              0
_________________________________________________________________
dense_2 (Dense)              (None, 128)               204928
_________________________________________________________________
dense_3 (Dense)              (None, 10)                1290
=================================================================
Total params: 243,786
Trainable params: 243,786
Non-trainable params: 0

Refs:

  1. Kernel in image processing: examples with images.