Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
435a3e4
Update intro.md
madeline-underwood Dec 28, 2024
529c71b
Editorial Review.
madeline-underwood Dec 28, 2024
af6d65e
Improvements to the phrasing of the language.
madeline-underwood Dec 29, 2024
1dfabd6
Update inference.md
madeline-underwood Dec 29, 2024
2e720fd
Update inference.md
madeline-underwood Dec 29, 2024
63d9a89
Update inference.md
madeline-underwood Dec 29, 2024
2d25027
Update inference.md
madeline-underwood Dec 29, 2024
57c9295
Merge branch 'ArmDeveloperEcosystem:main' into MNIST-digit-classifica…
madeline-underwood Dec 30, 2024
9a86468
Update inference.md
madeline-underwood Dec 30, 2024
1a609ab
Update _index.md
madeline-underwood Dec 30, 2024
0eb090e
Update _next-steps.md
madeline-underwood Dec 30, 2024
5b3025d
Restructured PyTorch model training process outline.
madeline-underwood Dec 30, 2024
b551f10
Update intro2.md
madeline-underwood Dec 30, 2024
eca6ff5
Update intro2.md
madeline-underwood Dec 30, 2024
cb687ac
Update intro-opt.md
madeline-underwood Dec 30, 2024
d347329
Tweaked audience statement.
madeline-underwood Dec 30, 2024
bc9f1aa
Added UI formatting and corrected spelling error.
madeline-underwood Dec 30, 2024
80197b9
Adjusted title
madeline-underwood Dec 31, 2024
1a32dd6
Reviewed questions.
madeline-underwood Dec 31, 2024
72a88b7
Review.
madeline-underwood Dec 31, 2024
3f8738a
Update intro-android.md
madeline-underwood Dec 31, 2024
d4ef2b8
Review.
madeline-underwood Dec 31, 2024
31d91c0
Review.
madeline-underwood Dec 31, 2024
32c7028
Restructuring long-list content into bullets.
madeline-underwood Dec 31, 2024
8dc7d58
Final editorial.
madeline-underwood Dec 31, 2024
6b76a1c
Final editorial.
madeline-underwood Dec 31, 2024
08e548c
Final editorial.
madeline-underwood Dec 31, 2024
ea412c7
Final editorial.
madeline-underwood Dec 31, 2024
01f73f9
Final editorial.
madeline-underwood Dec 31, 2024
817e03d
Editorial Final.
madeline-underwood Dec 31, 2024
adbcd08
Final editorial.
madeline-underwood Dec 31, 2024
70d6345
Final editorial.
madeline-underwood Dec 31, 2024
8fefed2
Final editorial.
madeline-underwood Dec 31, 2024
20ba43a
Final editorial.
madeline-underwood Dec 31, 2024
4db0127
Final editorial.
madeline-underwood Dec 31, 2024
ca69adb
Final editorial.
madeline-underwood Dec 31, 2024
4a3e7cc
Update model.md
madeline-underwood Dec 31, 2024
7e434f5
Update datasets-and-training.md
madeline-underwood Dec 31, 2024
8d619f1
Update inference.md
madeline-underwood Dec 31, 2024
80aba52
Update inference.md
madeline-underwood Dec 31, 2024
ae7122f
Update app.md
madeline-underwood Dec 31, 2024
68847e5
Update mobile-app.md
madeline-underwood Dec 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
---
title: Create and train a PyTorch model for digit classification
title: Create and train a PyTorch model for digit classification using the MNIST dataset

minutes_to_complete: 160

who_is_this_for: This is an advanced topic for software developers interested in learning how to use PyTorch to create and train a feedforward neural network for digit classification. You will also learn how to use the trained model in an Android application. Finally, you will apply model optimizations.
who_is_this_for: This is an advanced topic for software developers interested in learning how to use PyTorch to create and train a feedforward neural network for digit classification, and also software developers interested in learning how to use and apply optimizations to the trained model in an Android application.

learning_objectives:
- Prepare a PyTorch development environment.
- Download and prepare the MNIST dataset.
- Create a neural network architecture using PyTorch.
- Train a neural network using PyTorch.
- Create an Android app and loading the pre-trained model.
- Create and train a neural network architecture using PyTorch.
- Create an Android app and load the pre-trained model.
- Prepare an input dataset.
- Measure the inference time.
- Optimize a neural network architecture using quantization and fusing.
- Use an optimized model in the Android application.
- Deploy an optimized model in an Android application.

prerequisites:
- A computer that can run Python3, Visual Studio Code, and Android Studio. The OS can be Windows, Linux, or macOS.
- A machine that can run Python3, Visual Studio Code, and Android Studio.
- For the OS, you can use Windows, Linux, or macOS.


author_primary: Dawid Borycki
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# ================================================================================

next_step_guidance: >
Proceed to Use Keras Core with TensorFlow, PyTorch, and JAX backends to continue exploring Machine Learning.
To continue exploring Maching Learning, you can now learn about using Keras Core with TensorFlow, PyTorch, and JAX backends.

# 1-3 sentence recommendation outlining how the reader can generally keep learning about these topics, and a specific explanation of why the next step is being recommended.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,31 @@ review:
question: >
Does the input layer of the model flatten the 28x28 pixel image into a 1D array of 784 elements?
answers:
- "Yes"
- "No"
- "Yes."
- "No."
correct_answer: 1
explanation: >
Yes, the model uses nn.Flatten() to reshape the 28x28 pixel image into a 1D array of 784 elements for processing by the fully connected layers.
- questions:
question: >
Will the model make random predictions if it’s run before training?
Will the model make random predictions if it is run before training?
answers:
- "Yes"
- "No"
- "Yes."
- "No."
correct_answer: 1
explanation: >
Yes, however in such the case the model will produce random outputs, as the network has not been trained to recognize any patterns from the data.
Yes, however in this scenario the model will produce random outputs, as the network has not been trained to recognize any patterns from the data.
- questions:
question: >
Which loss function was used to train the PyTorch model on the MNIST dataset?
Which loss function did you use to train the PyTorch model on the MNIST dataset in this Learning Path?
answers:
- Mean Squared Error Loss
- Cross Entropy Loss
- Hinge Loss
- Mean Squared Error Loss.
- Cross-Entropy Loss.
- Hinge Loss.
- Binary Cross-Entropy Loss
correct_answer: 2
explanation: >
Cross Entropy Loss was used to train the model because it is suitable for multi-class classification tasks like digit classification. It measures the difference between the predicted probabilities and the true class labels, helping the model learn to make accurate predictions.
Cross-Entropy Loss was used to train the model as it is suitable for multi-class classification such as digit classification. It measures the difference between the predicted probabilities and the true class labels, helping the model to learn to make accurate predictions.

# ================================================================================
# FIXED, DO NOT MODIFY
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,31 @@ weight: 10
layout: "learningpathall"
---

You are now ready to run the Android application. You can use an emulator or a physical device.

The screenshots below show an emulator.
You are now ready to run the Android application. The screenshots below show an emulator, but you can also use a physical device.

To run the app in Android Studio using an emulator, follow these steps:

1. Configure the Emulator:
* Go to Tools > Device Manager (or click the Device Manager icon on the toolbar).
* Click Create Device to set up a new virtual device (if you haven’t done so already).
* Choose a device model, such as Pixel 4, and click Next.
* Select a system image, such as Android 11, API level 30, and click Next.
* Review the settings and click Finish to create the emulator.

* Go to **Tools** > **Device Manager**, or click the Device Manager icon on the toolbar.
* Click **Create Device** to set up a new virtual device, if you haven’t done so already.
* Choose a device model, such as the Pixel 4, and click **Next**.
* Select a system image, such as Android 11, API level 30, and click **Next**.
* Review the settings, and click **Finish** to create the emulator.

2. Run the App:
* Make sure the emulator is selected in the device dropdown menu in the toolbar (next to the “Run” button).
* Click the Run button (a green triangle). Android Studio will build the app, install it on the emulator, and launch it.

3. View the App on the Emulator: Once the app is installed, it will automatically open on the emulator screen, allowing you to interact with it as if it were running on a real device.
* Make sure the emulator is selected in the device drop-down menu in the toolbar, next to the **Run** button.
* Click the **Run** button, which is a green triangle. Android Studio builds the app, installs it on the emulator, and then launches it.

3. View the App on the Emulator:

* Once the app is installed, it automatically opens on the emulator screen, allowing you to interact with it as if it were running on a real device.

Once the application is started, click the Load Image button. It will load a randomly selected image. Then, click Run Inference to recognize the digit. The application will display the predicted label and the inference time as shown below:
Once the application starts, click the **Load Image** button. It loads a randomly-selected image. Then, click **Run Inference** to recognize the digit. The application displays the predicted label and the inference time as shown below:

![img](Figures/05.png)
![img alt-text#center](Figures/05.png "Figure 7. Digit Recognition 1")

![img](Figures/06.png)
![img alt-text#center](Figures/06.png "Figure 8. Digit Recognition 2")

In the next step you will learn how to further optimize the model.
In the next step of this Learning Path, you will learn how to further optimize the model.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
# User change
title: "Perform training and save the model"
title: "Perform Training and Save the Model"

weight: 5

Expand All @@ -9,9 +9,9 @@ layout: "learningpathall"

## Prepare the MNIST data

Start by downloading the MNIST dataset. Proceed as follows:
Start by downloading the MNIST dataset.

1. Open the pytorch-digits.ipynb you created earlier.
1. Open the `pytorch-digits.ipynb` you created earlier.

2. Add the following statements:

Expand Down Expand Up @@ -42,9 +42,15 @@ train_dataloader = DataLoader(training_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)
```

The above code snippet downloads the MNIST dataset, transforms the images into tensors, and sets up data loaders for training and testing. Specifically, the `datasets.MNIST` function is used to download the MNIST dataset, with `train=True` indicating training data and `train=False` indicating test data. The `transform=transforms.ToTensor()` argument converts each image in the dataset into a PyTorch tensor, which is necessary for model training and evaluation.
Using this code enables you to:

The DataLoader wraps the datasets and allows efficient loading of data in batches. It handles data shuffling, batching, and parallel loading. Here, the train_dataloader and test_dataloader are created with a batch_size of 32, meaning they will load 32 images per batch during training and testing.
* Download the MNIST dataset.
* Transform the images into tensors.
* Set up data loaders for training and testing.

Specifically, the `datasets.MNIST` function downloads the MNIST dataset, with `train=True` indicating training data and `train=False` indicating test data. The `transform=transforms.ToTensor()` argument converts each image in the dataset into a PyTorch tensor, which is necessary for model training and evaluation.

The DataLoader wraps the datasets and enables efficient loading of data in batches. It handles data shuffling, batching, and parallel loading. Here, the train_dataloader and test_dataloader are created with a batch_size of 32, meaning they will load 32 images per batch during training and testing.

This setup prepares the training and test datasets for use in a machine learning model, enabling efficient data handling and model training in PyTorch.

Expand All @@ -54,19 +60,21 @@ To run the above code, you will need to install certifi package:
pip install certifi
```

The certifi Python package provides the Mozilla root certificates, which are essential for ensuring the SSL connections are secure. If you’re using macOS, you may also need to install the certificates by running:
The certifi Python package provides the Mozilla root certificates, which are essential for ensuring the SSL connections are secure. If you’re using macOS, you might also need to install the certificates by running:

```console
/Applications/Python\ 3.x/Install\ Certificates.command
```

Make sure to replace `x` with the number of Python version you have installed.
{{% notice Note %}}
Make sure to replace 'x' with the version number of Python that you have installed.
{{% /notice %}}

After running the code you see output similar to the screenshot below:
After running the code, you will see output similar to Figure 5:

![image](Figures/01.png)
![image alt-text#center](Figures/01.png "Figure 5. Output".)

# Train the model
## Train the Model

To train the model, specify the loss function and the optimizer:

Expand All @@ -77,7 +85,7 @@ loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
```

Use CrossEntropyLoss as the loss function and the Adam optimizer for training. The learning rate is set to 1e-3.
Use `CrossEntropyLoss` as the loss function and the Adam optimizer for training. The learning rate is set to 1e-3.

Next, define the methods for training and evaluating the feedforward neural network:

Expand Down Expand Up @@ -111,7 +119,7 @@ def test_loop(dataloader, model, loss_fn):
print(f"Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")
```

The first method, `train_loop`, uses the backpropagation algorithm to optimize the trainable parameters and minimize the prediction error of the neural network. The second method, `test_loop`, calculates the neural network error using the test images and displays the accuracy and loss values.
The first method, `train_loop`, uses the backpropagation algorithm to optimize the trainable parameters and minimize the prediction error rate of the neural network. The second method, `test_loop`, calculates the neural network error rate using the test images, and displays the accuracy and loss values.

You can now invoke these methods to train and evaluate the model using 10 epochs.

Expand All @@ -124,9 +132,9 @@ for t in range(epochs):
test_loop(test_dataloader, model, loss_fn)
```

After running the code, you see the following output showing the training progress.
After running the code, you see the following output showing the training progress, as displayed in Figure 2.

![image](Figures/02.png)
![image alt-text#center](Figures/02.png "Figure 2. Output 2")

Once the training is complete, you see output similar to:

Expand All @@ -139,13 +147,13 @@ The output shows the model achieved around 95% accuracy.

# Save the model

Once the model is trained, you can save it. There are various approaches for this. In PyTorch, you can save both the model’s structure and its weights to the same file using the `torch.save()` function. Alternatively, you can save only the weights (parameters) of the model, not the model architecture itself. This requires you to have the model’s architecture defined separately when loading. To save the model weights, you can use the following command:
Once the model is trained, you can save it. There are various approaches for this. In PyTorch, you can save both the model’s structure and its weights to the same file using the `torch.save()` function. Alternatively, you can save only the weights of the model, not the model architecture itself. This requires you to have the model’s architecture defined separately when loading. To save the model weights, you can use the following command:

```Python
torch.save(model.state_dict(), "model_weights.pth").
```

However, PyTorch does not save the definition of the class itself. When you load the model using `torch.load()`, PyTorch needs to know the class definition to recreate the model object.
However, PyTorch does not save the definition of the class itself. When you load the model using `torch.load()`, PyTorch requires the class definition to recreate the model object.

Therefore, when you later want to use the saved model for inference, you will need to provide the definition of the model class.

Expand All @@ -164,16 +172,22 @@ traced_model = torch.jit.trace(model, torch.rand(1, 1, 28, 28))
traced_model.save("model.pth")
```

The above commands set the model to evaluation mode, trace the model, and save it. Tracing is useful for converting models with static computation graphs to TorchScript, making them portable and independent of the original class definition.
The above commands perform the following tasks:

* They set the model to evaluation mode.
* They trace the model.
* They save it.

Tracing is useful for converting models with static computation graphs to TorchScript, making them flexible and independent of the original class definition.

Setting the model to evaluation mode before tracing is important for several reasons:

1. Behavior of Layers like Dropout and BatchNorm:
* Dropout. During training, dropout randomly zeroes out some of the activations to prevent overfitting. During evaluation dropout is turned off, and all activations are used.
1. Behavior of Layers like Dropout and BatchNorm:
* Dropout. During training, dropout randomly zeroes out some of the activations to prevent overfitting. During evaluation, dropout is turned off, and all activations are used.
* BatchNorm. During training, Batch Normalization layers use batch statistics to normalize the input. During evaluation, they use running averages calculated during training.

2. Consistent Inference Behavior. By setting the model to eval mode, you ensure that the traced model will behave consistently during inference, as it will not use dropout or batch statistics that are inappropriate for inference.
2. Consistent Inference Behavior. By setting the model to eval mode, you ensure that the traced model behaves consistently during inference, as it does not use dropout or batch statistics that are inappropriate for inference.

3. Correct Tracing. Tracing captures the operations performed by the model using a given input. If the model is in training mode, the traced graph may include operations related to dropout and batch normalization updates. These operations can affect the correctness and performance of the model during inference.
3. Correct Tracing. Tracing captures the operations performed by the model using a given input. If the model is in training mode, the traced graph might include operations related to dropout and batch normalization updates. These operations can affect the correctness and performance of the model during inference.

In the next step, you will use the saved model for ML inference.
Loading