# **PyTorch Masterclass: Part 1 – Foundations of Deep Learning with PyTorch**
**Duration: ~120 minutes**
**Hashtags:** #PyTorch #DeepLearning #MachineLearning #AI #NeuralNetworks #DataScience #Python #Tensors #Autograd #Backpropagation #GradientDescent #AIForBeginners #PyTorchTutorial #MachineLearningEngineer
---
## **Table of Contents**
1. [Introduction to Deep Learning and PyTorch](#introduction-to-deep-learning-and-pytorch)
2. [Why PyTorch? A Comparison with TensorFlow and Other Frameworks](#why-pytorch-a-comparison-with-tensorflow-and-other-frameworks)
3. [Installing and Setting Up PyTorch](#installing-and-setting-up-pytorch)
4. [Understanding Tensors: The Building Blocks of PyTorch](#understanding-tensors-the-building-blocks-of-pytorch)
5. [Tensor Operations: Arithmetic, Indexing, Slicing, and Broadcasting](#tensor-operations-arithmetic-indexing-slicing-and-broadcasting)
6. [GPU Acceleration with CUDA in PyTorch](#gpu-acceleration-with-cuda-in-pytorch)
7. [Automatic Differentiation and the Autograd System](#automatic-differentiation-and-the-autograd-system)
8. [Building Your First Neural Network from Scratch](#building-your-first-neural-network-from-scratch)
9. [Loss Functions and Optimizers in PyTorch](#loss-functions-and-optimizers-in-pytorch)
10. [Training Loop: Forward Pass, Backward Pass, and Gradient Descent](#training-loop-forward-pass-backward-pass-and-gradient-descent)
11. [Debugging and Monitoring Training with TensorBoard](#debugging-and-monitoring-training-with-tensorboard)
12. [Quiz 1: Test Your Understanding of PyTorch Basics](#quiz-1-test-your-understanding-of-pytorch-basics)
13. [Summary and What’s Next in Part 2](#summary-and-whats-next-in-part-2)
---
## **Introduction to Deep Learning and PyTorch**
Welcome to **Part 1** of the most comprehensive PyTorch masterclass ever created. This is not just a tutorial—it's a deep dive into the world of deep learning, computational graphs, automatic differentiation, and neural network design using one of the most powerful frameworks in modern AI: **PyTorch**.
By the end of this 6-part series, you will be able to build, train, and deploy complex deep learning models—from simple regression networks to convolutional neural networks (CNNs), recurrent networks (RNNs), transformers, and even generative models like GANs and diffusion networks. But we must start at the foundation.
### **What is Deep Learning?**
Deep learning is a subfield of machine learning that focuses on **neural networks** with multiple layers—hence "deep." These models learn hierarchical representations of data, automatically extracting features from raw inputs like images, text, or audio.
For example:
- A **convolutional neural network (CNN)** learns to detect edges, shapes, and objects in images.
- A **recurrent neural network (RNN)** learns temporal patterns in sequences like sentences or stock prices.
- A **transformer** learns contextual relationships in language, enabling models like BERT and GPT.
Deep learning has revolutionized AI. It powers:
- Self-driving cars
- Voice assistants (Siri, Alexa)
- Medical image diagnosis
- Real-time language translation
- Recommendation systems (Netflix, YouTube)
But to build these systems, we need tools. That’s where **PyTorch** comes in.
### **What is PyTorch?**
**PyTorch** is an open-source machine learning framework developed by **Facebook's AI Research lab (FAIR)**. It is built on the **Torch library**, but uses Python as its primary interface, making it highly accessible, flexible, and intuitive.
PyTorch is known for:
- **Dynamic computation graphs** (define-by-run)
- **Pythonic syntax** (feels like native Python)
- **Excellent GPU support** via CUDA
- **Strong integration with NumPy**
- **Seamless deployment** with TorchScript and ONNX
- **Vibrant ecosystem** (TorchVision, TorchText, TorchAudio, etc.)
PyTorch is the **preferred framework** in research and is rapidly gaining traction in industry due to its flexibility and ease of debugging.
> 💡 **Fun Fact**: The name "PyTorch" combines "Python" and "Torch", reflecting its origins as a Python wrapper for the Torch library.
### **Who Uses PyTorch?**
PyTorch is used by:
- **Google DeepMind** (AlphaFold, robotics)
- **OpenAI** (early versions of GPT)
- **Meta (Facebook)** (all AI research)
- **Microsoft** (Azure AI, integration with Cognitive Services)
- **Tesla** (Autopilot vision models)
- **Academia** (most published AI papers use PyTorch)
In fact, according to a 2023 survey by Papers With Code, **over 70% of new deep learning papers** use PyTorch as their implementation framework.
---
## **Why PyTorch? A Comparison with TensorFlow and Other Frameworks**
Before diving into code, let’s understand **why PyTorch** has become the dominant framework in deep learning.
### **PyTorch vs. TensorFlow: The Great Framework War**
For years, **TensorFlow** (developed by Google) was the king of deep learning frameworks. But PyTorch has overtaken it in research and is closing the gap in production.
| Feature | PyTorch | TensorFlow |
|--------|--------|-----------|
| **Computation Graph** | Dynamic (define-by-run) | Static (define-and-run) in v1, dynamic in v2 |
| **Ease of Debugging** | Excellent (uses Python debugger) | Harder (graph execution) |
| **Python Integration** | Native, feels like Python | Requires session management (v1), improved in v2 |
| **Research Adoption** | >70% of papers | ~20% |
| **Production Deployment** | Good (TorchScript, ONNX) | Excellent (TF Serving, Lite) |
| **Community & Ecosystem** | Fast-growing, strong in research | Mature, strong in enterprise |
| **Learning Curve** | Gentle, intuitive | Steeper (especially v1) |
### **Key Advantages of PyTorch**
#### 1. **Dynamic Computation Graphs**
PyTorch uses a **define-by-run** approach. The computation graph is built **on-the-fly** as operations are executed. This means:
- You can use standard Python control flow (`if`, `for`, `while`).
- Easy to debug with `print()` and `pdb`.
- Flexible for variable-length inputs (e.g., NLP sequences).
```python
# PyTorch: Dynamic graph - you can use loops and conditionals
for i in range(x.size(0)):
if x[i] > 0:
y = y + x[i] * w
```
In contrast, TensorFlow 1.x used **static graphs**, where you had to define the entire graph before running it—making debugging painful.
#### 2. **Pythonic Design**
PyTorch feels like **native Python**. No sessions, no placeholders, no graph definitions. Just tensors, functions, and modules.
```python
import torch
x = torch.tensor([1.0, 2.0])
w = torch.tensor([0.5, 0.5], requires_grad=True)
y = x * w
y.backward()
print(w.grad) # Works like regular Python
```
#### 3. **Seamless NumPy Integration**
PyTorch tensors can be converted to and from NumPy arrays with zero copy overhead.
```python
import numpy as np
import torch
np_array = np.random.rand(3, 4)
torch_tensor = torch.from_numpy(np_array) # Zero-copy conversion
back_to_numpy = torch_tensor.numpy() # Zero-copy back
```
This makes it easy to integrate with the broader scientific Python stack (Pandas, Matplotlib, Scikit-learn).
#### 4. **Superior Debugging Experience**
Because PyTorch runs operations immediately, you can:
- Use `print()` to inspect values.
- Use `pdb` or IDE debuggers.
- Set breakpoints anywhere.
This is a **huge advantage** during model development.
#### 5. **Strong Research Ecosystem**
PyTorch is the **framework of choice** in academia. Libraries like:
- **TorchVision** (vision models and datasets)
- **TorchText** (NLP tools)
- **TorchAudio** (audio processing)
- **Hugging Face Transformers** (pretrained models)
- **PyTorch Lightning** (high-level training loop)
...make it easy to build state-of-the-art models quickly.
---
## **Installing and Setting Up PyTorch**
Before we begin coding, let’s ensure you have PyTorch installed correctly.
### **Step 1: Choose Your Environment**
You can install PyTorch in:
- **Local machine** (Windows, macOS, Linux)
- **Google Colab** (free GPU)
- **Jupyter Notebook**
- **VS Code / PyCharm**
For beginners, **Google Colab** is recommended because it:
- Requires no setup
- Provides free GPU/TPU
- Has PyTorch pre-installed
👉 [Open Google Colab](https://colab.research.google.com)
### **Step 2: Install PyTorch**
Go to [https://pytorch.org/get-started/locally/](https://pytorch.org/get-started/locally/) and select your OS, package manager, and compute platform.
#### **Option A: Using pip (Recommended)**
```bash
# CPU-only version
pip install torch torchvision torchaudio
# GPU version (CUDA 11.8)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
# GPU version (CUDA 12.1)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
```
#### **Option B: Using Conda**
```bash
# GPU version
conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia
# CPU version
conda install pytorch torchvision torchaudio cpuonly -c pytorch
```
### **Step 3: Verify Installation**
Run this Python script:
```python
import torch
print("PyTorch version:", torch.__version__)
print("CUDA available:", torch.cuda.is_available())
print("CUDA version:", torch.version.cuda)
print("Number of GPUs:", torch.cuda.device_count())
if torch.cuda.is_available():
print("Current GPU:", torch.cuda.get_device_name(0))
```
Expected output:
```
PyTorch version: 2.1.0
CUDA available: True
CUDA version: 11.8
Number of GPUs: 1
Current GPU: NVIDIA GeForce RTX 3080
```
> ⚠️ **Note**: If `CUDA available` is `False`, your GPU is not detected. You can still run PyTorch on CPU, but training will be slower.
---
## **Understanding Tensors: The Building Blocks of PyTorch**
Tensors are the **core data structure** in PyTorch. They are **multi-dimensional arrays** that can run on CPU or GPU and support automatic differentiation.
Think of tensors as **generalized matrices**:
- 0D: Scalar (single number)
- 1D: Vector
- 2D: Matrix
- 3D: Tensor (e.g., RGB image)
- 4D: Batch of images (N x C x H x W)
### **Creating Tensors**
Let’s create some tensors.
```python
import torch
# From Python list
t1 = torch.tensor([1, 2, 3])
print(t1) # tensor([1, 2, 3])
# From NumPy array
import numpy as np
np_array = np.array([4, 5, 6])
t2 = torch.from_numpy(np_array)
print(t2) # tensor([4, 5, 6])
# Random tensor
t3 = torch.rand(3, 4) # 3x4 uniform [0,1)
print(t3)
# Zeros and ones
t4 = torch.zeros(2, 3)
t5 = torch.ones(2, 3)
# With specific data type
t6 = torch.tensor([1.0, 2.0], dtype=torch.float64)
```
### **Tensor Properties**
Every tensor has:
- **Shape**: dimensions
- **Data type (dtype)**: e.g., float32, int64
- **Device**: CPU or CUDA
- **Requires gradient**: for autograd
```python
t = torch.rand(3, 4, 5)
print("Shape:", t.shape) # torch.Size([3, 4, 5])
print("Size:", t.size()) # Same as shape
print("Data type:", t.dtype) # torch.float32
print("Device:", t.device) # cpu
print("Requires grad:", t.requires_grad) # False
```
> 💡 **Pro Tip**: Use `.shape` instead of `.size()`—it’s more consistent with NumPy.
### **Common Tensor Creation Methods**
| Method | Description |
|-------|-------------|
| `torch.tensor(data)` | From Python data |
| `torch.zeros(size)` | All zeros |
| `torch.ones(size)` | All ones |
| `torch.rand(size)` | Uniform [0,1) |
| `torch.randn(size)` | Normal (0,1) |
| `torch.arange(start, end)` | Range of integers |
| `torch.linspace(start, end, steps)` | Linearly spaced |
| `torch.eye(n)` | Identity matrix |
```python
# Examples
a = torch.zeros(2, 3) # 2x3 zeros
b = torch.randn(3, 3) # 3x3 normal
c = torch.arange(0, 10) # [0,1,...,9]
d = torch.linspace(0, 1, 5) # [0.0, 0.25, 0.5, 0.75, 1.0]
e = torch.eye(3) # 3x3 identity
```
### **Tensor Data Types**
PyTorch supports many dtypes:
| Dtype | Description | Common Use |
|------|-------------|------------|
| `torch.float32` | 32-bit float | Most models |
| `torch.float64` | 64-bit float | High precision |
| `torch.float16` | 16-bit float | GPU training (mixed precision) |
| `torch.int32` | 32-bit int | Indices |
| `torch.int64` | 64-bit int | Long indices |
| `torch.bool` | Boolean | Masks |
```python
t = torch.tensor([1, 2, 3], dtype=torch.int64)
print(t.dtype) # torch.int64
```
> ⚠️ **Warning**: Always be explicit about dtypes. Default is `float32` for floats, `int64` for integers.
---
## **Tensor Operations: Arithmetic, Indexing, Slicing, and Broadcasting**
Now that we can create tensors, let’s learn how to **manipulate** them.
### **Arithmetic Operations**
PyTorch supports all standard arithmetic operations:
```python
a = torch.tensor([1.0, 2.0, 3.0])
b = torch.tensor([4.0, 5.0, 6.0])
print(a + b) # tensor([5., 7., 9.])
print(a - b) # tensor([-3., -3., -3.])
print(a * b) # tensor([4., 10., 18.])
print(a / b) # tensor([0.25, 0.40, 0.50])
print(a ** 2) # tensor([1., 4., 9.])
print(torch.sqrt(a)) # tensor([1.0000, 1.4142, 1.7321])
```
All operations are **element-wise**.
### **In-Place Operations**
Use `_` suffix for in-place operations (modifies tensor):
```python
a.add_(b) # a = a + b
print(a) # tensor([5., 7., 9.])
```
> ⚠️ **Caution**: In-place operations can **break the computation graph** in autograd. Avoid them when `requires_grad=True`.
### **Indexing and Slicing**
Same as NumPy:
```python
t = torch.tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(t[0]) # First row: tensor([1, 2, 3])
print(t[:, 1]) # Second column: tensor([2, 5, 8])
print(t[1:3, :2]) # Rows 1-2, cols 0-1
# tensor([[4, 5],
# [7, 8]])
```
### **Fancy Indexing**
```python
indices = torch.tensor([0, 2])
print(t[indices]) # Rows 0 and 2
# tensor([[1, 2, 3],
# [7, 8, 9]])
```
### **Boolean Indexing**
```python
mask = t > 5
print(mask)
# tensor([[False, False, False],
# [False, False, True ],
# [True, True, True]])
print(t[mask]) # tensor([6, 7, 8, 9])
```
### **Reshaping Tensors**
Use `.view()`, `.reshape()`, or `.resize_()`.
```python
x = torch.arange(12) # [0,1,...,11]
# Reshape to 3x4
y = x.view(3, 4)
print(y)
# Or use reshape
z = x.reshape(2, 6)
# Flatten
flat = y.view(-1) # -1 means "infer size"
print(flat.shape) # torch.Size([12])
```
> 💡 **Note**: `.view()` shares memory. Use `.clone()` if you need a copy.
### **Transpose and Permute**
```python
# 2D transpose
t = torch.rand(3, 4)
t_t = t.t() # or t.transpose(0,1)
# Multi-dimensional permute
t3d = torch.rand(2, 3, 4)
t_perm = t3d.permute(2, 0, 1) # Rearrange dims
```
### **Broadcasting**
PyTorch supports **broadcasting**—operations between tensors of different shapes.
Rules:
1. Dimensions are aligned from right to left.
2. Two dims are compatible if equal or one is 1.
3. Result shape takes the max size.
```python
a = torch.rand(3, 1) # 3x1
b = torch.rand(1, 4) # 1x4
c = a + b # 3x4 (broadcasted)
print(c.shape) # torch.Size([3, 4])
```
Example: Add bias to batch of features.
```python
features = torch.rand(32, 10) # 32 samples, 10 features
bias = torch.rand(10) # 10 biases
output = features + bias # Broadcasts bias to 32x10
```
---
## **GPU Acceleration with CUDA in PyTorch**
One of PyTorch’s greatest strengths is **seamless GPU support**.
### **Why GPU?**
- **Parallel processing**: GPUs have thousands of cores.
- **Matrix operations**: Deep learning is mostly linear algebra.
- **Speedup**: 10x–100x faster than CPU for large models.
### **Checking GPU Availability**
```python
if torch.cuda.is_available():
device = torch.device('cuda')
else:
device = torch.device('cpu')
print(f"Using device: {device}")
```
### **Moving Tensors to GPU**
```python
x = torch.rand(3, 4)
x_gpu = x.to(device) # or x.cuda()
# Or create directly on GPU
x_gpu = torch.rand(3, 4, device=device)
```
### **Moving Models to GPU**
```python
model = MyNeuralNetwork()
model.to(device) # Moves all parameters to GPU
```
### **Best Practices for GPU Usage**
1. **Move data and model to same device**
2. **Use `.to(device)` for portability**
3. **Avoid frequent CPU-GPU transfers**
4. **Use mixed precision (`float16`) for speed**
```python
# Good practice
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = MyModel().to(device)
data = data.to(device)
output = model(data) # All on GPU
```
### **Mixed Precision Training**
Use `torch.cuda.amp` for automatic mixed precision:
```python
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
with autocast():
output = model(data)
loss = criterion(output, target)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
```
This can **double training speed** on modern GPUs.
---
## **Automatic Differentiation and the Autograd System**
This is where PyTorch **shines**: **automatic differentiation**.
### **What is Autograd?**
Autograd is PyTorch’s **automatic differentiation engine**. It records all operations on tensors and computes gradients via the **chain rule**.
Every tensor has a `.grad_fn` attribute that references the function that created it.
```python
x = torch.tensor(2.0, requires_grad=True)
y = x ** 2 # y = x^2
z = y * 3 # z = 3x^2
print(z.grad_fn) # <MulBackward0 object>
print(y.grad_fn) # <PowBackward0 object>
```
### **Computing Gradients**
Call `.backward()` to compute gradients.
```python
z.backward() # dz/dx
print(x.grad) # tensor(12.0) because dz/dx = 6x = 6*2 = 12
```
> ⚠️ **Note**: `.backward()` can only be called on **scalar** tensors. For vectors, use `gradient` argument.
### **Gradient Accumulation**
Gradients are **accumulated** by default.
```python
x = torch.tensor(2.0, requires_grad=True)
y = x ** 2
y.backward()
print(x.grad) # tensor(4.0)
y.backward() # Again!
print(x.grad) # tensor(8.0) — accumulated!
```
To reset, use `optimizer.zero_grad()` or `x.grad.zero_()`.
### **Stopping Gradient Tracking**
Use `torch.no_grad()` to disable autograd.
```python
with torch.no_grad():
y = x ** 2 # No gradient tracking
```
Or use `.detach()`:
```python
y_detached = y.detach() # New tensor without grad history
```
### **Practical Example: Linear Regression Gradient**
Let’s compute gradients for a simple model.
```python
# Data
x = torch.tensor([1.0, 2.0, 3.0])
y_true = torch.tensor([2.0, 4.0, 6.0])
# Parameters
w = torch.tensor(1.0, requires_grad=True)
b = torch.tensor(0.0, requires_grad=True)
# Forward pass
y_pred = w * x + b
loss = ((y_pred - y_true) ** 2).mean()
# Backward pass
loss.backward()
print(f"w.grad: {w.grad}") # Should be around -6.0
print(f"b.grad: {b.grad}") # Should be around -4.0
```
We’ll use this in our neural network soon.
---
## **Building Your First Neural Network from Scratch**
Let’s build a **fully connected neural network** for regression.
### **Step 1: Define the Model**
We’ll create a simple 2-layer network.
```python
import torch
import torch.nn as nn
class SimpleNet(nn.Module):
def __init__(self, input_size=1, hidden_size=10, output_size=1):
super(SimpleNet, self).__init__()
self.hidden = nn.Linear(input_size, hidden_size)
self.relu = nn.ReLU()
self.output = nn.Linear(hidden_size, output_size)
def forward(self, x):
x = self.hidden(x)
x = self.relu(x)
x = self.output(x)
return x
# Instantiate
model = SimpleNet()
```
### **Step 2: Define Loss and Optimizer**
```python
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
```
### **Step 3: Generate Dummy Data**
```python
# y = 3x + 2 + noise
X = torch.linspace(-1, 1, 100).reshape(-1, 1)
y = 3 * X + 2 + torch.randn(X.shape) * 0.1
```
### **Step 4: Training Loop**
```python
epochs = 1000
for epoch in range(epochs):
# Forward pass
y_pred = model(X)
loss = criterion(y_pred, y)
# Backward pass
optimizer.zero_grad()
loss.backward()
# Update weights
optimizer.step()
if epoch % 100 == 0:
print(f"Epoch {epoch}, Loss: {loss.item():.4f}")
```
### **Step 5: Evaluate**
```python
model.eval()
with torch.no_grad():
y_test = model(X)
test_loss = criterion(y_test, y)
print(f"Test Loss: {test_loss:.4f}")
```
Congratulations! You’ve built and trained your first neural network in PyTorch.
---
## **Loss Functions and Optimizers in PyTorch**
### **Common Loss Functions**
| Loss | Use Case |
|------|---------|
| `nn.MSELoss()` | Regression |
| `nn.L1Loss()` | Robust regression |
| `nn.CrossEntropyLoss()` | Classification |
| `nn.BCELoss()` | Binary classification |
| `nn.BCEWithLogitsLoss()` | Binary with sigmoid |
```python
# CrossEntropyLoss: input = raw logits, target = class indices
criterion = nn.CrossEntropyLoss()
logits = torch.randn(3, 5) # 3 samples, 5 classes
target = torch.tensor([1, 0, 4])
loss = criterion(logits, target)
```
### **Common Optimizers**
| Optimizer | Description |
|---------|-------------|
| `SGD` | Stochastic Gradient Descent |
| `Adam` | Adaptive learning rates |
| `RMSprop` | RMS normalization |
| `Adagrad` | Per-parameter learning rates |
```python
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
```
> 💡 **Tip**: Use `Adam` as default. It’s robust and fast.
---
## **Training Loop: Forward Pass, Backward Pass, and Gradient Descent**
Let’s break down the training loop.
### **The 5-Step Training Loop**
1. **Forward Pass**: Compute predictions
2. **Compute Loss**: Compare predictions to targets
3. **Zero Gradients**: Reset gradients
4. **Backward Pass**: Compute gradients
5. **Update Weights**: Step optimizer
```python
for data, target in dataloader:
# 1. Forward
output = model(data)
# 2. Loss
loss = criterion(output, target)
# 3. Zero gradients
optimizer.zero_grad()
# 4. Backward
loss.backward()
# 5. Update
optimizer.step()
```
### **Validation Loop**
```python
model.eval()
val_loss = 0
with torch.no_grad():
for data, target in val_loader:
output = model(data)
val_loss += criterion(output, target).item()
val_loss /= len(val_loader)
```
---
## **Debugging and Monitoring Training with TensorBoard**
Use **TensorBoard** to visualize training.
```python
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter('runs/simple_net')
for epoch in range(100):
# Training
...
writer.add_scalar('Loss/train', loss, epoch)
# Validation
...
writer.add_scalar('Loss/val', val_loss, epoch)
writer.close()
```
Run:
```bash
tensorboard --logdir=runs
```
---
## **Quiz 1: Test Your Understanding of PyTorch Basics**
**1. What is the output of the following code?**
```python
x = torch.tensor([1.0, 2.0], requires_grad=True)
y = x.sum()
y.backward()
print(x.grad)
```
A) `tensor([1., 1.])`
B) `tensor([2., 2.])`
C) `tensor([1., 2.])`
D) `None`
**2. Which method creates a tensor of zeros with shape (2,3)?**
A) `torch.zeros(2,3)`
B) `torch.tensor([[0,0,0],[0,0,0]])`
C) `torch.empty(2,3).zero_()`
D) All of the above
**3. How do you move a tensor to GPU if available?**
A) `tensor.cuda()`
B) `tensor.to('cuda')`
C) `tensor.to(device)` where `device = torch.device('cuda')`
D) All of the above
**4. What does `requires_grad=True` do?**
A) Enables gradient computation
B) Makes tensor trainable
C) Adds tensor to computation graph
D) All of the above
**5. Which optimizer is most commonly used in practice?**
A) SGD
B) Adam
C) RMSprop
D) Adagrad
**6. What is broadcasting in PyTorch?**
A) Sending tensors over network
B) Element-wise operations on tensors of different shapes
C) Converting tensors to NumPy
D) Parallel processing on GPU
**7. How do you disable gradient computation?**
A) `torch.no_grad()`
B) `.detach()`
C) `requires_grad=False`
D) All of the above
**8. What is the shape of the output of `torch.randn(2,3).t()`?**
A) `(2,3)`
B) `(3,2)`
C) `(2,2)`
D) Error
**9. Which loss function is used for multi-class classification?**
A) `BCELoss`
B) `MSELoss`
C) `CrossEntropyLoss`
D) `L1Loss`
**10. What does `optimizer.zero_grad()` do?**
A) Resets gradients to zero
B) Deletes gradients
C) Stops training
D) Updates weights
---
**Answers:**
1. A
2. D
3. D
4. D
5. B
6. B
7. D
8. B
9. C
10. A
---
## **Summary and What’s Next in Part 2**
In this lesson, we covered:
- Introduction to PyTorch and deep learning
- Installation and setup
- Tensors: creation, operations, GPU
- Autograd and automatic differentiation
- Building and training a neural network
- Loss functions and optimizers
- Training loops and TensorBoard
- Quiz to test your knowledge
You now have a **solid foundation** in PyTorch.
### **What’s Coming in Part 2?**
In **Part 2**, we’ll dive into:
- **Dataset and DataLoader**: Efficient data loading
- **Transforms**: Image and text preprocessing
- **Convolutional Neural Networks (CNNs)**: Vision models
- **Transfer Learning**: Using pretrained models
- **Training CNNs on CIFAR-10**
- **Advanced debugging and profiling**
We’ll build a **real image classifier** and explore **state-of-the-art architectures** like ResNet and EfficientNet.
👉 **Stay tuned for Part 2: Deep Learning for Computer Vision with PyTorch**
---
**Hashtags:** #PyTorch #DeepLearning #MachineLearning #AI #NeuralNetworks #Tensors #Autograd #GradientDescent #Backpropagation #DataScience #Python #AIForBeginners #PyTorchTutorial #MachineLearningEngineer #TensorBoard #CUDA #GPU #NeuralNetworks #LossFunctions #Optimizers #Adam #SGD #CrossEntropyLoss #MSELoss
Thank you for completing **Part 1** of the PyTorch Masterclass. Take a break, review the quiz, and practice the code. Mastery comes with repetition.
See you in **Part 2**! 🚀