<jupyter_start><jupyter_text>Good ol' MNIST.<jupyter_code>%tensorflow_version 2.x
import tensorflow as tf
import tensorflow_datasets as tfds
import matplotlib.pyplot as plt
import numpy as np

train = tfds.load(name="mnist", split=tfds.Split.TRAIN)
test = tfds.load(name="mnist", split=tfds.Split.TEST)

train = train.shuffle(1024).batch(32)<jupyter_output>TensorFlow 2.x selected.<jupyter_text>Let's visualize the first batch.<jupyter_code>first_batch = tfds.as_numpy(train).__next__()
batch = first_batch['image']
labels = first_batch['label']
print(batch.shape)

fig=plt.figure(figsize=(28, 28))
columns = 8
rows = 4
for i in range(1, columns*rows + 1):
  img = batch[i-1].reshape(28,28)
  fig.add_subplot(rows, columns, i)
  plt.imshow(img)
plt.show()

# sample = image[0].numpy()
# sample = sample.reshape((28,28))

# plt.imshow(sample)
# plt.show()<jupyter_output>(32, 28, 28, 1)<jupyter_text>Creating a simple Convnet to classify the digits.<jupyter_code>model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv2D(
    32,
    (3, 3), 
    activation='relu',
    input_shape=(28,28,1)))
model.add(tf.keras.layers.MaxPooling2D((2,2)))
model.add(tf.keras.layers.Conv2D(64, (3, 3), activation='relu'))
model.add(tf.keras.layers.MaxPooling2D((2,2)))
model.add(tf.keras.layers.Conv2D(64, (3, 3), activation='relu'))

print(model.summary())<jupyter_output>Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 26, 26, 32)        320       
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 13, 13, 32)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 11, 11, 64)        18496     
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 5, 5, 64)          0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 3, 3, 64)          36928     
=================================================================
Total params: 55,744
Trainable params: 55,744
Non-trainable params: 0
____________________________________________________[...]<jupyter_text>Add fully connected layer to finish the classifier after feature extraction.<jupyter_code>model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(64, activation='relu'))
model.add(tf.keras.layers.Dense(10, activation='softmax'))

print(model.summary())<jupyter_output>Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 26, 26, 32)        320       
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 13, 13, 32)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 11, 11, 64)        18496     
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 5, 5, 64)          0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 3, 3, 64)          36928     
_________________________________________________________________
flatten (Flatten)            (None, 576)               0         
________________________________________________________[...]<jupyter_text>Let's prepare our input data pipeline.* Normalize the image data from [0, 255] to [0.0, 1.0]<jupyter_code>print("Max value on a image is:")
print(batch[0].max())

print("Type of label is.")
print(type(labels[0]))
def prepare_mnist(example):
  prepared_batch = example['image']
  prepared_label = example['label']
  
  prepared_batch = tf.dtypes.cast(prepared_batch, tf.float32)
  prepared_batch = prepared_batch / 255
  prepared_label = prepared_label
  prepared_label = tf.one_hot(prepared_label, 10)
  return prepared_batch, prepared_label<jupyter_output><empty_output><jupyter_text>Check that the preparation function formats the inputs and outputs in the expect format to work with our model. Let's learn the representation on the training data.<jupyter_code>train = train.map(map_func=prepare_mnist)
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
history = model.fit(train, epochs=5)
history_dict = history.history
print(history_dict.keys())

epochs = range(1, len(history_dict['accuracy']) + 1)
plt.plot(epochs, history_dict['accuracy'], 'bo', label='Accuracy')
plt.title('Accuracy')
plt.xlabel('Epochs')
plt.ylabel('%')
plt.legend()
plt.show()<jupyter_output>dict_keys(['loss', 'accuracy'])<jupyter_text>Evaluate the model on the test data.<jupyter_code>test = test.batch(32).take(10000).map(map_func=prepare_mnist)
test_loss, test_accuracy = model.evaluate(test)
print(test_accuracy)<jupyter_output>313/313 [==============================] - 3s 10ms/step - loss: 0.0355 - accuracy: 0.9901
0.9901<jupyter_text>Likely overfitting at this point. But the model is performing exceedingly well.Some considerations to explore in the future* Training data augmentation* More regulariztion* Hyperparameter searching* Add validation data set to determine when overfitting starts* Futher experiments Save the model so that we can use it to reevaluate without training.<jupyter_code>from google.colab import files
save_path = 'trained_weights.h5'
model.save(save_path)
files.download(save_path)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14434060228452752, 'fraction_numerical': 0.04119072343371409, 'mean_word_length': 5.174145299145299, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '554071', 'license': 'MIT', 'n_tokens_mistral': 1856, 'n_tokens_neox': 1662, 'n_words': 375, 'path': 'MNIST.ipynb', 'repo_name': 'elielamora/ml_playground', 'size': '5778'}