0% found this document useful (0 votes)
13 views15 pages

notMNIST Image Classification Lab

This document is a Jupyter notebook that introduces a TensorFlow neural network lab to label images of English letters. It provides example images of letters A through J in different fonts as the data to be trained on. The goal is to train a neural network on this data to make predictions against a test set with at least 80% accuracy. It discusses downloading and preprocessing the training and test data, which includes normalizing the grayscale image pixel values and one-hot encoding the labels. It also includes code cells to implement these preprocessing steps.

Uploaded by

Daniel Petrov
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views15 pages

notMNIST Image Classification Lab

This document is a Jupyter notebook that introduces a TensorFlow neural network lab to label images of English letters. It provides example images of letters A through J in different fonts as the data to be trained on. The goal is to train a neural network on this data to make predictions against a test set with at least 80% accuracy. It discusses downloading and preprocessing the training and test data, which includes normalizing the grayscale image pixel values and one-hot encoding the labels. It also includes code cells to implement these preprocessing steps.

Uploaded by

Daniel Petrov
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

10/26/21, 9:45 AM machine-learning/intro_to_tensorflow.

ipynb at master · vnikov/machine-learning

TensorFlow Neural Network Lab

In this lab, you'll use all the tools you learned from Introduction to TensorFlow  to label images of English
letters! The data you are using, notMNIST, consists of images of a letter from A to J in different fonts.

The above images are a few examples of the data you'll be training on. After training the network, you will
compare your prediction model against test data. Your goal, by the end of this lab, is to make predictions
against that test set with at least an 80% accuracy. Let's jump in!

To start this lab, you first need to import all the necessary modules. Run the code below. If it runs
successfully, it will print "All modules imported".

In [ ]: import hashlib

import os

import pickle

from [Link] import urlretrieve

import numpy as np

from PIL import Image

from sklearn.model_selection import train_test_split

from [Link] import LabelBinarizer

from [Link] import resample

from tqdm import tqdm

from zipfile import ZipFile

print('All modules imported.')

The notMNIST dataset is too large for many computers to handle. It contains 500,000 images for just
training. You'll be using a subset of this data, 15,000 images for each label (A-J).

[Link] 1/15
10/26/21, 9:45 AM machine-learning/intro_to_tensorflow.ipynb at master · vnikov/machine-learning

In [ ]: def download(url, file):

"""

Download file from <url>

:param url: URL to file

:param file: Local file path

"""

if not [Link](file):

print('Downloading ' + file + '...')

urlretrieve(url, file)

print('Download Finished')

# Download the training and test dataset.

download('[Link]
'notMNIST_train.zip')

download('[Link]
'notMNIST_test.zip')

# Make sure the files aren't corrupted

assert hashlib.md5(open('notMNIST_train.zip', 'rb').read()).hexdiges


t() == 'c8673b3f28f489e9cdf3a3d74e2ac8fa',\

'notMNIST_train.zip file is corrupted. Remove the file and


try again.'

assert hashlib.md5(open('notMNIST_test.zip', 'rb').read()).hexdigest


() == '5d3c7e653e63471c88df796156a9dfa9',\

'notMNIST_test.zip file is corrupted. Remove the file and t


ry again.'

# Wait until you see that all files have been downloaded.

print('All files downloaded.')

[Link] 2/15
10/26/21, 9:45 AM machine-learning/intro_to_tensorflow.ipynb at master · vnikov/machine-learning

In [ ]: def uncompress_features_labels(file):

"""

Uncompress features and labels from a zip file

:param file: The zip file to extract the data from

"""

features = []

labels = []

with ZipFile(file) as zipf:

# Progress Bar

filenames_pbar = tqdm([Link](), unit='files')

# Get features and labels from all files

for filename in filenames_pbar:

# Check if the file is a directory

if not [Link]('/'):

with [Link](filename) as image_file:

image = [Link](image_file)

[Link]()

# Load image data as 1 dimensional array

# We're using float32 to save on memory space

feature = [Link](image, dtype=np.float32).flat


ten()

# Get the the letter from the filename. This is the


letter of the image.

label = [Link](filename)[1][0]

[Link](feature)

[Link](label)

return [Link](features), [Link](labels)

# Get the features and labels from the zip files

train_features, train_labels = uncompress_features_labels('notMNIST_


[Link]')

test_features, test_labels = uncompress_features_labels('notMNIST_te


[Link]')

# Limit the amount of data to work with a docker container

docker_size_limit = 150000

train_features, train_labels = resample(train_features, train_labels


, n_samples=docker_size_limit)

# Set flags for feature engineering. This will prevent you from ski
pping an important step.

is_features_normal = False

is_labels_encod = False

# Wait until you see that all features and labels have been uncompre
ssed.

print('All features and labels uncompressed.')

[Link] 3/15
10/26/21, 9:45 AM machine-learning/intro_to_tensorflow.ipynb at master · vnikov/machine-learning

Problem 1
The first problem involves normalizing the features for your training and test data.

Implement Min-Max scaling in the  normalize_grayscale()  function to a range of  a=0.1  and  b=0.9.
After scaling, the values of the pixels in the input data should range from 0.1 to 0.9.

Since the raw notMNIST image data is in grayscale, the current values range from a min of 0 to a max of
255.

Min-Max Scaling: 

If you're having trouble solving problem 1, you can view the solution here.

[Link] 4/15
10/26/21, 9:45 AM machine-learning/intro_to_tensorflow.ipynb at master · vnikov/machine-learning

In [ ]: # Problem 1 - Implement Min-Max scaling for grayscale image data

def normalize_grayscale(image_data):

"""

Normalize the image data with Min-Max scaling to a range of [0.


1, 0.9]

:param image_data: The image data to be normalized

:return: Normalized image data

"""

# TODO: Implement Min-Max scaling for grayscale image data


### DON'T MODIFY ANYTHING BELOW ###

# Test Cases

[Link].assert_array_almost_equal(

normalize_grayscale([Link]([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
255])),

[0.1, 0.103137254902, 0.106274509804, 0.109411764706, 0.11254901


9608, 0.11568627451, 0.118823529412, 0.121960784314,

0.125098039216, 0.128235294118, 0.13137254902, 0.9],

decimal=3)

[Link].assert_array_almost_equal(

normalize_grayscale([Link]([0, 1, 10, 20, 30, 40, 233, 244, 25


4,255])),

[0.1, 0.103137254902, 0.13137254902, 0.162745098039, 0.194117647


059, 0.225490196078, 0.830980392157, 0.865490196078,

0.896862745098, 0.9])

if not is_features_normal:

train_features = normalize_grayscale(train_features)

test_features = normalize_grayscale(test_features)

is_features_normal = True

print('Tests Passed!')

In [ ]: if not is_labels_encod:

# Turn labels into numbers and apply One-Hot Encoding


encoder = LabelBinarizer()

[Link](train_labels)

train_labels = [Link](train_labels)

test_labels = [Link](test_labels)

# Change to float32, so it can be multiplied against the feature


s in TensorFlow, which are float32

train_labels = train_labels.astype(np.float32)

test_labels = test_labels.astype(np.float32)

is_labels_encod = True

print('Labels One-Hot Encoded')

[Link] 5/15
10/26/21, 9:45 AM machine-learning/intro_to_tensorflow.ipynb at master · vnikov/machine-learning

In [ ]: assert is_features_normal, 'You skipped the step to normalize the fe


atures'

assert is_labels_encod, 'You skipped the step to One-Hot Encode the


labels'

# Get randomized datasets for training and validation

train_features, valid_features, train_labels, valid_labels = train_t


est_split(

train_features,

train_labels,

test_size=0.05,

random_state=832289)

print('Training features and labels randomized and split.')

In [ ]: # Save the data for easy access

pickle_file = '[Link]'

if not [Link](pickle_file):

print('Saving data to pickle file...')

try:

with open('[Link]', 'wb') as pfile:

[Link](

'train_dataset': train_features,

'train_labels': train_labels,

'valid_dataset': valid_features,

'valid_labels': valid_labels,

'test_dataset': test_features,

'test_labels': test_labels,

},

pfile, pickle.HIGHEST_PROTOCOL)

except Exception as e:

print('Unable to save data to', pickle_file, ':', e)

raise

print('Data cached in pickle file.')

Checkpoint
All your progress is now saved to the pickle file. If you need to leave and comeback to this lab, you no longer
have to start from the beginning. Just run the code block below and it will load all the data and modules
required to proceed.

[Link] 6/15
10/26/21, 9:45 AM machine-learning/intro_to_tensorflow.ipynb at master · vnikov/machine-learning

In [ ]: %matplotlib inline

# Load the modules

import pickle

import math

import numpy as np

import tensorflow as tf

from tqdm import tqdm

import [Link] as plt

# Reload the data

pickle_file = '[Link]'

with open(pickle_file, 'rb') as f:

pickle_data = [Link](f)

train_features = pickle_data['train_dataset']

train_labels = pickle_data['train_labels']

valid_features = pickle_data['valid_dataset']

valid_labels = pickle_data['valid_labels']

test_features = pickle_data['test_dataset']

test_labels = pickle_data['test_labels']

del pickle_data # Free up memory

print('Data and modules loaded.')

[Link] 7/15
10/26/21, 9:45 AM machine-learning/intro_to_tensorflow.ipynb at master · vnikov/machine-learning

Problem 2
Now it's time to build a simple neural network using TensorFlow. Here, your network will be just an input layer
and an output layer.

For the input here the images have been flattened into a vector of    features. Then, we're
trying to predict the image digit so there are 10 output units, one for each label. Of course, feel free to add
hidden layers if you want, but this notebook is built to guide you through a single layer network.

For the neural network to train on your data, you need the following float32 tensors:

features
Placeholder tensor for feature data
(train_features/valid_features/test_features)
labels
Placeholder tensor for label data (train_labels/valid_labels/test_labels)
weights
Variable Tensor with random numbers from a truncated normal distribution.
See `tf.truncated_normal()` documentationfor help.
biases
Variable Tensor with all zeros.
See `[Link]()` documentation for help.

[Link] 8/15
10/26/21, 9:45 AM machine-learning/intro_to_tensorflow.ipynb at master · vnikov/machine-learning

If you're having trouble solving problem 2, review "TensorFlow Linear Function" section of the class. If that
doesn't help, the solution for this problem is available here.

[Link] 9/15
10/26/21, 9:45 AM machine-learning/intro_to_tensorflow.ipynb at master · vnikov/machine-learning

In [ ]: # All the pixels in the image (28 * 28 = 784)

features_count = 784

# All the labels

labels_count = 10

# TODO: Set the features and labels tensors

# features =

# labels =

# TODO: Set the weights and biases tensors

# weights =

# biases =

### DON'T MODIFY ANYTHING BELOW ###

#Test Cases

from [Link] import Variable

assert features._op.[Link]('Placeholder'), 'features must b


e a placeholder'

assert labels._op.[Link]('Placeholder'), 'labels must be a


placeholder'

assert isinstance(weights, Variable), 'weights must be a TensorFlow


variable'

assert isinstance(biases, Variable), 'biases must be a TensorFlow va


riable'

assert features._shape == None or (\

features._shape.dims[0].value is None and\

features._shape.dims[1].value in [None, 784]), 'The shape of fea


tures is incorrect'

assert labels._shape == None or (\

labels._shape.dims[0].value is None and\

labels._shape.dims[1].value in [None, 10]), 'The shape of labels


is incorrect'

assert weights._variable._shape == (784, 10), 'The shape of weights


is incorrect'

assert biases._variable._shape == (10), 'The shape of biases is inco


rrect'

assert features._dtype == tf.float32, 'features must be type float3


2'

assert labels._dtype == tf.float32, 'labels must be type float32'

# Feed dicts for training, validation, and test session

train_feed_dict = {features: train_features, labels: train_labels}

valid_feed_dict = {features: valid_features, labels: valid_labels}

test_feed_dict = {features: test_features, labels: test_labels}

# Linear Function WX + b

logits = [Link](features, weights) + biases

prediction = [Link](logits)

[Link] 10/15
10/26/21, 9:45 AM machine-learning/intro_to_tensorflow.ipynb at master · vnikov/machine-learning

# Cross entropy

cross_entropy = -tf.reduce_sum(labels * [Link](prediction), reductio


n_indices=1)

# Training loss

loss = tf.reduce_mean(cross_entropy)

# Create an operation that initializes all variables


init = tf.global_variables_initializer()

# Test Cases

with [Link]() as session:

[Link](init)

[Link](loss, feed_dict=train_feed_dict)

[Link](loss, feed_dict=valid_feed_dict)

[Link](loss, feed_dict=test_feed_dict)

biases_data = [Link](biases)

assert not np.count_nonzero(biases_data), 'biases must be zeros'

print('Tests Passed!')

In [ ]: # Determine if the predictions are correct

is_correct_prediction = [Link]([Link](prediction, 1), [Link]


(labels, 1))

# Calculate the accuracy of the predictions

accuracy = tf.reduce_mean([Link](is_correct_prediction, tf.float32


))

print('Accuracy function created.')

[Link] 11/15
10/26/21, 9:45 AM machine-learning/intro_to_tensorflow.ipynb at master · vnikov/machine-learning

Problem 3
Below are 2 parameter configurations for training the neural network. In each configuration, one of the
parameters has multiple options. For each configuration, choose the option that gives the best acccuracy.

Parameter configurations:

Configuration 1

Epochs: 1
Learning Rate:
0.8
0.5
0.1
0.05
0.01

Configuration 2

Epochs:
1
2
3
4
5
Learning Rate: 0.2

The code will print out a Loss and Accuracy graph, so you can see how well the neural network performed.

If you're having trouble solving problem 3, you can view the solution here.

[Link] 12/15
10/26/21, 9:45 AM machine-learning/intro_to_tensorflow.ipynb at master · vnikov/machine-learning

In [ ]: # Change if you have memory restrictions

batch_size = 128

# TODO: Find the best parameters for each configuration

# epochs =

# learning_rate =

### DON'T MODIFY ANYTHING BELOW ###

# Gradient Descent

optimizer = [Link](learning_rate).minimiz
e(loss)

# The accuracy measured against the validation set

validation_accuracy = 0.0

# Measurements use for graphing loss and accuracy

log_batch_step = 50

batches = []

loss_batch = []

train_acc_batch = []

valid_acc_batch = []

with [Link]() as session:

[Link](init)

batch_count = int([Link](len(train_features)/batch_size))

for epoch_i in range(epochs):

# Progress bar

batches_pbar = tqdm(range(batch_count), desc='Epoch {:>2}/{}


'.format(epoch_i+1, epochs), unit='batches')

# The training cycle

for batch_i in batches_pbar:

# Get a batch of training features and labels


batch_start = batch_i*batch_size

batch_features = train_features[batch_start:batch_start
+ batch_size]

batch_labels = train_labels[batch_start:batch_start + ba
tch_size]

# Run optimizer and get loss

_, l = [Link](

[optimizer, loss],

feed_dict={features: batch_features, labels: batch_l


abels})

# Log every 50 batches

if not batch_i % log_batch_step:

# Calculate Training and Validation accuracy

training_accuracy = [Link](accuracy, feed_dict=


train_feed_dict)

validation_accuracy = [Link](accuracy, feed_dic


t=valid_feed_dict)

[Link] 13/15
10/26/21, 9:45 AM machine-learning/intro_to_tensorflow.ipynb at master · vnikov/machine-learning

# Log batches

previous_batch = batches[-1] if batches else 0

[Link](log_batch_step + previous_batch)

loss_batch.append(l)

train_acc_batch.append(training_accuracy)

valid_acc_batch.append(validation_accuracy)

# Check accuracy against Validation data

validation_accuracy = [Link](accuracy, feed_dict=valid_


feed_dict)

loss_plot = [Link](211)

loss_plot.set_title('Loss')

loss_plot.plot(batches, loss_batch, 'g')

loss_plot.set_xlim([batches[0], batches[-1]])

acc_plot = [Link](212)

acc_plot.set_title('Accuracy')

acc_plot.plot(batches, train_acc_batch, 'r', label='Training Accurac


y')

acc_plot.plot(batches, valid_acc_batch, 'x', label='Validation Accur


acy')

acc_plot.set_ylim([0, 1.0])

acc_plot.set_xlim([batches[0], batches[-1]])

acc_plot.legend(loc=4)

plt.tight_layout()

[Link]()

print('Validation accuracy at {}'.format(validation_accuracy))

Test
You're going to test your model against your hold out dataset/testing data. This will give you a good indicator
of how well the model will do in the real world. You should have a test accuracy of at least 80%.

[Link] 14/15
10/26/21, 9:45 AM machine-learning/intro_to_tensorflow.ipynb at master · vnikov/machine-learning

In [ ]: ### DON'T MODIFY ANYTHING BELOW ###

# The accuracy measured against the test set

test_accuracy = 0.0

with [Link]() as session:

[Link](init)

batch_count = int([Link](len(train_features)/batch_size))

for epoch_i in range(epochs):

# Progress bar

batches_pbar = tqdm(range(batch_count), desc='Epoch {:>2}/{}


'.format(epoch_i+1, epochs), unit='batches')

# The training cycle

for batch_i in batches_pbar:

# Get a batch of training features and labels


batch_start = batch_i*batch_size

batch_features = train_features[batch_start:batch_start
+ batch_size]

batch_labels = train_labels[batch_start:batch_start + ba
tch_size]

# Run optimizer

_ = [Link](optimizer, feed_dict={features: batch_fe


atures, labels: batch_labels})

# Check accuracy against Test data

test_accuracy = [Link](accuracy, feed_dict=test_feed_di


ct)

assert test_accuracy >= 0.80, 'Test accuracy at {}, should be equal


to or greater than 0.80'.format(test_accuracy)

print('Nice Job! Test Accuracy is {}'.format(test_accuracy))

Multiple layers
Good job! You built a one layer TensorFlow network! However, you might want to build more than one layer.
This is deep learning after all! In the next section, you will start to satisfy your need for more layers.

[Link] 15/15

Common questions

Powered by AI

Preparing the notMNIST dataset involves several steps: First, downloading the training and test datasets from a specified URL. Then, uncompressing the features and labels from these zip files, converting images into feature arrays and extracting labels from filenames. Next, normalizing the image data to a range of [0.1, 0.9] using Min-Max scaling. Following this, labels are encoded using One-Hot Encoding. Afterwards, the dataset is split into training and validation sets while storing them in a pickle file for reproducibility. Finally, datasets are loaded back from the pickle file into TensorFlow variables to proceed with building the neural network .

The neural network is structured with an input layer and an output layer, where features (flattened image vectors) are fed into a placeholder tensor, and weights and biases tensors are initialized with shapes matching the input and output dimensions (784 input features and 10 output labels). The network's computation involves calculating logits as WX + b and applying a softmax function to obtain prediction probabilities. Training operations involve defining loss using cross-entropy and optimizing weights through gradient descent .

LabelBinarizer is used to convert string labels into one-hot encoded vectors. This transformation is necessary because the neural network requires numerical input rather than categorical strings to compute gradients and optimize weights. This encoding enables handling multi-class outputs (i.e., letters A-J) properly during training .

Caching data using pickle allows for saving the processed datasets (train, validation, test splits with labels) in a serialized format for easy retrieval. This avoids redundant preprocessing steps each time the notebook is run, saving significant time and computational resources. Data can simply be reloaded from the pickle file to continue from the last checkpoint, enhancing workflow efficiency .

To ensure data integrity, checksums are used to verify the downloaded files' integrity using MD5 hashing. If the checksum doesn't match the expected value, the file is considered corrupted, prompting a re-download. This process prevents using faulty data, which could lead to training errors or incorrect model performance .

The tutorial explores two parameter configurations. In Configuration 1, different learning rates are tested (0.8, 0.5, 0.1, 0.05, 0.01), while in Configuration 2, different epoch numbers are evaluated (1 through 5) with a constant learning rate of 0.2. The variation in parameters affects the network's convergence and, thereby, its accuracy. Optimal parameter selection is crucial for achieving high accuracy, as demonstrated by plotting loss and accuracy during training .

The model evaluates accuracy by comparing predicted labels to true labels using the tf.equal function, which outputs a boolean tensor indicating correct predictions. Accuracy is calculated by taking the mean of the correct predictions cast to float. This process is performed for training, validation, and test datasets. Validation accuracy is measured during training cycles, and test accuracy is assessed after training to ensure a minimum of 80% accuracy, verifying the model’s effectiveness on hold-out data .

Validation methods include several assertions to check: placeholders for features and labels, variable types for weights and biases, correct tensor shapes for input features and labels, and data types as tf.float32 for both features and labels. Initial biases must be zero, and weights need to be initialized from a truncated normal distribution. The training process output, such as loss reduction and improved validation accuracy, also serves as indicators of implementation correctness .

The learning rate significantly influences the speed and stability of the training process. A higher learning rate may lead to faster convergence but risks overshooting the minimum loss, causing instability or divergence. Conversely, a too-small learning rate results in slow convergence, increasing computation time and possibly leading to sub-optimal minima. This tutorial tests different rates to find a balance, optimizing for the best accuracy with efficient training. Each configuration plot helps visualize how rates affect loss reduction over epochs .

Min-Max scaling for grayscale image data requires transforming the pixel values from their current range of [0, 255] to a new range of [0.1, 0.9]. This is achieved using the formula X' = a + ((X - min) * (b - a) / (max - min)), where X is the original pixel value, X' is the scaled value, min and max are the minimum and maximum of the original range (0 and 255), and a and b are the new scaling bounds (0.1 and 0.9).

You might also like