Skip to content

Classification Example - Demo 3

Getting started

Logging into Open OnDemand

As discussed, through ondemand you're able to access our Bose cluster through a user interface. This significantly eases the processes of navigating to important applications that users need to run. Accessing ondemand is as simple as...

  1. Navigate to https://ondemand.hpc.uwec.edu/ (Required to be on the UWEC wifi or connected through a VPN).
  2. Entering your login information.
  3. If prompted, accept the OKTA login.

Stuck?

If you're having trouble logging in, don't be afraid to ask for help!

Starting a Jupyter session

  • Accounting Group: ub_workshop_2025
  • Slurm Partition: Week (7 days) - Default
  • CPU Cores: 8
  • Memory: 15G
  • #GPU Cards: No GPUs- Default
  • Number of Hours: 2
  • Working Directory: (Leave this blank)
  • Email Notifications: None - No Email

Code Example

Step 1 -

Python is a very flexible programming language, and one of the biggest reasons for it's popularity is the ability to use libraries.

A library is a colletion of pre-written code that you can import into your own program. Instead of writing everything from scratch, you can use the libraries to handle common tasks, like reading files, greating graphs or even building AI models.

Libraries are especially important in fields like data science and machine learning, where what used to take thousands of lines of code can now just be done in a few hundred. This makes complex projects faster, easier and more accessible.

##  Step 1  ##


#Main library used to train our model
import tensorflow as tf   

#Display the version
print(tf.__version__)     

#Other important libraries
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.layers import Input, Conv2D, Dense, Flatten, Dropout
from tensorflow.keras.layers import GlobalMaxPooling2D, MaxPooling2D
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.models import Model

Step 2 -

Once we've imported our libraries that we'll be using, another crutial step in being able to train our AI model is loading in the data that we'll need to use to be able to train it

##  Step 2  ##


#Load in the dataset
cifar10 = tf.keras.datasets.cifar10

#Split the dataset into train and test sets
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
print(x_train.shape, y_train.shape, x_test.shape, y_test.shape)

Step 3 -

Before feeding our images and labels into the AI model, we need to prepare the data in a way that makes it easier for the computer to learn from.

Why do we do this? Each pixel in a color image has a value between 0 and 255, where 0 is black and 255 is the brightest color in that channel (Red, Green, or Blue).​

But computers learn better when numbers are small and consistent, typically between 0 and 1.

##  Step 3  ##

# Reduce pixel values
x_train, x_test = x_train / 255.0, x_test / 255.0

# flatten the label values
y_train, y_test = y_train.flatten(), y_test.flatten()

Step 4 -

Before we start training our model, it’s a good idea to look at the data and make sure we know what images the model will be reading.​

##  Step 4  ##


# visualize data by plotting images
fig, ax = plt.subplots(5, 5)
k = 0

for i in range(5):
    for j in range(5):
        ax[i][j].imshow(x_train[k], aspect='auto')
        k += 1

plt.show()

Step 5 -

Now that we’ve loaded and prepared our data, it’s time to build the model that will actually learn from the images.​ You can think of this as designing the neural network or in other terms: the computer's brain.​ We’ll build the model using TensorFlow's library, which allows us to stack layers like building blocks.

##  Step 5  ##


# number of classes
K = len(set(y_train))

# calculate total number of classes 
# for output layer
print("number of classes:", K)

# Build the model using the functional API
# input layer
i = Input(shape=x_train[0].shape)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(i)
x = BatchNormalization()(x)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2))(x)

x = Conv2D(64, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = Conv2D(64, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2))(x)

x = Conv2D(128, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = Conv2D(128, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2))(x)

x = Flatten()(x)
x = Dropout(0.2)(x)

# Hidden layer
x = Dense(1024, activation='relu')(x)
x = Dropout(0.2)(x)

# last hidden layer i.e.. output layer
x = Dense(K, activation='softmax')(x)

model = Model(i, x)

# model description
model.summary()

Step 6 -

Before we can start training our model, we need to compile it. Think of compiling as “setting the learning rules” for the model, you're telling it how to learn, how to measure success, and what to optimize.​ The optimizer, saying how the model should update itself​, the loss function, how we measure the mistakes, and how to “punish” or reward the model depending on what they guessed and the metrics we want to track, such as accuracy.​

##  Step 6  ##


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

Step 7 -

Now it’s time for the model to learn from the training data. This process is called fitting/training the model. The model will:​

  • Look at the training images and their labels​

  • Try to predict the correct label​

  • Compare its prediction to the real label​

  • Use the loss function to measure its error​

  • Use the optimizer to improve based on the mistake​

  • Repeat this process over and over for multiple cycles (called epochs)​

##  Step 7  ##


# Fit
r = model.fit(
  x_train, y_train, validation_data=(x_test, y_test), epochs=10)

Step 8 -

After the training we can produce a per-epoch progression graph to be able to see how the model's ability to predict the labels changed over it's training life cycle. This is useful to see if the model continued to improve or if it began to plateau.

##  Step 8  ##


plt.plot(r.history['accuracy'], label='acc', color='red')
plt.plot(r.history['val_accuracy'], label='val_acc', color='green')
plt.legend()

Step 9 -

Additionally, we get to display some of the images of how well it was able to classify the animals!!

##  Step 9  ##


# label mapping

labels = '''airplane automobile bird cat deerdog frog horseship truck'''.split()

# select the image from our test dataset
image_number = 0

# display the image
plt.imshow(x_test[image_number])

# load the image in an array
n = np.array(x_test[image_number])

# reshape it
p = n.reshape(1, 32, 32, 3)

# pass in the network for prediction and 
# save the predicted label
predicted_label = labels[model.predict(p).argmax()]

# load the original label
original_label = labels[y_test[image_number]]

# display the result
print("Original label is {} and predicted label is {}".format(
    original_label, predicted_label))

Data Augmentation

Data augmentation is a way to make AI models smarter by creating more examples for it to learn from. Instead of collection a bunch of new data, we make the images we already have slightly different to create new unseen versions.

For example we might:

  • Zoom in on an image randomly
  • Shift it so it's moved a little to the side
  • Mirror the image, sort of like a reflection of what it already was.

These changes help the model learn patterns in the image, rather than learning to just memorize the images themselves. You can think of it like studying for a language exam. Instead of just memorizing a list of vocabulary words and their definitions, you're learning the words well enough that you can use them naturally in writing or speaking.

In the same way, data augmentation teaches the AI to understand what an object looks like, even if it's shown in a different way.

Try this on your own!

Run the following code on your own! You can even go back to previous code involving the model and try and improve the overall accuracy.

Step 10 -

Retrain the model.

##  Step 10  ##

batch_size = 32
data_generator = tf.keras.preprocessing.image.ImageDataGenerator(
  width_shift_range=0.1, height_shift_range=0.1, horizontal_flip=True)

train_generator = data_generator.flow(x_train, y_train, batch_size)
steps_per_epoch = x_train.shape[0] // batch_size

r = model.fit(train_generator, validation_data=(x_test, y_test),
              steps_per_epoch=steps_per_epoch, epochs=10)

Step 11 -

Plot the new accuracy graphs.

##  Step 11  ##


plt.plot(r.history['accuracy'], label='acc', color='red')
plt.plot(r.history['val_accuracy'], label='val_acc', color='green')
plt.legend()

Step 12 -

Visualize the new prediction results.

##  Step 12  ##


# label mapping

labels = '''airplane automobile bird cat deerdog frog horseship truck'''.split()

# select the image from our test dataset
image_number = 0

# display the image
plt.imshow(x_test[image_number])

# load the image in an array
n = np.array(x_test[image_number])

# reshape it
p = n.reshape(1, 32, 32, 3)

# pass in the network for prediction and 
# save the predicted label
predicted_label = labels[model.predict(p).argmax()]

# load the original label
original_label = labels[y_test[image_number]]

# display the result
print("Original label is {} and predicted label is {}".format(
    original_label, predicted_label))