XP: 0
⚙️ Part 1 · Module 1

The Environment: PyTorch & Tensors

In the fundamentals course you understood how models work — and even built one in a simulator. Now we make it real, in code. Module 1 sets up your workshop: where to run code, how to install PyTorch, and the one object everything is built from — the tensor.
Before we start

How this course works (hybrid)

Every module shows you real, copyable code alongside simulated animations that make it click. You can copy any code block and run it yourself — in Google Colab (free, in your browser) or on your own machine.

Important — you run the code

The animations here are illustrations, not a live Python engine — real PyTorch can't run inside a web page. When you want to actually execute something, copy the code and run it in Colab or locally. That's how you'll learn it for real.

The workshop

What you need to train models

Three things, and that's it:

🐍 Python
  • The language all AI runs on
  • You likely have it already
  • Colab has it built-in
🔥 PyTorch
  • The library that builds & trains models
  • Handles tensors, autograd, GPUs
  • What Meta, OpenAI, most research use
⚡ A GPU (optional to start)
  • Makes training 10–100× faster
  • Not needed for Module 1–5
  • Colab gives you one free
Why PyTorch (and not "just Python")?

Plain Python is too slow for the millions of number-crunching operations training needs. PyTorch gives you (1) tensors — fast multi-dimensional arrays, (2) autograd — automatic backpropagation (Module 3 of fundamentals, done for you!), and (3) GPU support — one line to make it all run on a graphics card. It's the toolbox that turns "I understand backprop" into "I can train a model."

The key decision

Where should your code run?

You have three options. For starting out, Google Colab is the clear winner — zero install, a free GPU, works on any laptop (even a Chromebook). Here's the honest comparison:

Google Colab START HERE
  • Zero install — runs in your browser
  • Free GPU (with limits)
  • Works on any machine
  • Sessions time out / reset
  • Not for huge/long jobs (free tier)
💻 Local machine
  • You own it — no time limits
  • Full control, private data stays home
  • Install & CUDA setup can be fiddly
  • Need a decent GPU for big models
☁️ Cloud GPU
  • Rent big GPUs by the hour
  • Scales to real training
  • Costs money
  • Overkill until later modules
Analogy — renting vs. owning a workshop

Colab = a free shared workshop you walk into and use (but they close it at night). Local = your own garage — always there, but you buy and maintain the tools. Cloud GPU = renting an industrial factory by the hour. Start in the free shared workshop; build your garage later.

Getting set up

Installing PyTorch — both paths

Path A — Google Colab (recommended, zero install)

Go to colab.research.google.com → New Notebook. PyTorch is already installed. Just verify it — paste this into a cell and press ▶ (Shift+Enter):

python · colab
import torch
print("PyTorch version:", torch.__version__)
print("GPU available:", torch.cuda.is_available())

To turn on the free GPU in Colab: menu → Runtime → Change runtime type → Hardware accelerator → GPU → Save. Then re-run — GPU available: becomes True.

Path B — Local machine (when you're ready to own it)

First make an isolated environment (so PyTorch doesn't clash with other projects), then install:

bash · terminal
# 1. create & activate a virtual environment
python -m venv ai-env
# Windows:
ai-env\Scripts\activate
# Mac/Linux:
source ai-env/bin/activate

# 2. install PyTorch (CPU version — works everywhere)
pip install torch

# 3. verify
python -c "import torch; print(torch.__version__)"
CPU vs. GPU (CUDA) install

pip install torch gives the CPU version — perfect for Modules 1–5 here. To use an NVIDIA GPU locally, you need the CUDA build — get the exact command for your system from the official selector at pytorch.org/get-started/locally. Don't guess the CUDA version; use their picker.

🎮 Game 1

"Is my setup ready?" — the verification walkthrough

This simulates what you'll see when you run the checks. Step through it to know exactly what a healthy setup looks like — then run the real code above yourself.

Setup verification (simulated)
What you'd see in a Colab cell after running the checks.
press "Run checks" to simulate…
The star concept

Tensors — the one thing everything is made of

A tensor is just a container of numbers with a shape. You already met them without the name: in fundamentals, a flattened image was a vector (Module 1), and a word embedding was a vector (Module 4). A tensor generalizes that to any number of dimensions.

The ladder of shapes:

python
import torch

# 0-D: a scalar (single number)
a = torch.tensor(7.0)                     # shape: ()

# 1-D: a vector (like an embedding)
b = torch.tensor([1.0, 2.0, 3.0])         # shape: (3,)

# 2-D: a matrix (like a batch of vectors, or a grayscale image)
c = torch.tensor([[1, 2, 3],
                  [4, 5, 6]])          # shape: (2, 3)

# 3-D: e.g. a color image (height x width x RGB)
d = torch.randn(4, 4, 3)                 # shape: (4, 4, 3)

print(b.shape)      # torch.Size([3])
print(c.shape)      # torch.Size([2, 3])
The only jargon you need: shape

A tensor's shape is the list of its dimensions. (2, 3) means 2 rows × 3 columns. 99% of PyTorch bugs are shape mismatches — "expected (32, 128) but got (128, 32)". Get comfortable reading .shape now and you'll save yourself hours later.

🎮 Game 2

Tensor playground — see the shapes

Click each dimension to see the tensor and its shape. The real code that builds it is shown too — copy and try it.

Scalar → Vector → Matrix → 3D
Click a shape on the right.
python
import torch
t = torch.tensor(7.0)   # scalar, shape ()
Actually using tensors

Tensor operations — the moves you'll use constantly

Knowing what a tensor is isn't enough — you need to manipulate them. These four operations show up in almost every model you'll ever write. They're also where beginners hit their first real wall, so it's worth getting comfortable now.

1. Element-wise math & matrix multiply

Math on tensors happens on every element at once (no loops). And @ is matrix multiply — the single most important operation in neural networks (every layer is basically x @ W).

python
a = torch.tensor([1., 2., 3.])
b = torch.tensor([10., 20., 30.])

a + b          # tensor([11., 22., 33.])  — element-wise, no loop
a * 2          # tensor([2., 4., 6.])     — scalar applies to all

M = torch.randn(2, 3)
x = torch.randn(3, 4)
M @ x          # shape (2, 4)  — matrix multiply (this is a neural net layer!)

2. Indexing & slicing

Grab parts of a tensor just like Python lists — but across multiple dimensions.

python
t = torch.tensor([[1,2,3],
                  [4,5,6]])   # shape (2, 3)

t[0]        # tensor([1, 2, 3])  — first row
t[:, 1]     # tensor([2, 5])     — second column (: means "all rows")
t[0, 2]     # tensor(3)          — row 0, col 2

3. Reshaping with .view() / .reshape()

Rearrange the same numbers into a different shape — used constantly to make tensors fit the next layer. The total number of elements must stay the same.

python
t = torch.arange(6)        # tensor([0,1,2,3,4,5]), shape (6,)

t.view(2, 3)          # [[0,1,2],[3,4,5]]  — same data, shape (2, 3)
t.view(3, 2)          # [[0,1],[2,3],[4,5]] — shape (3, 2)
t.view(-1, 2)         # -1 means "figure it out" → shape (3, 2)

4. Broadcasting

PyTorch auto-stretches smaller tensors to match bigger ones so shapes line up — no manual copying. It feels like magic until it bites you, so know it exists.

python
M = torch.ones(3, 3)      # shape (3, 3)
row = torch.tensor([1., 2., 3.])  # shape (3,)

M + row        # row is auto-"broadcast" to every row of M
               # [[2,3,4],[2,3,4],[2,3,4]]  — no loop needed
The golden rule: watch your shapes

Most PyTorch errors are shape mismatches — e.g. trying @ on tensors whose inner dimensions don't match. When something breaks, your first move is always print(x.shape) on every tensor involved. Reshaping and broadcasting exist precisely to make shapes line up. Master these four moves and you can read (and debug) almost any model code.

Speed

CPU vs GPU — the one-line superpower

A CPU does a few things very fast, one after another. A GPU does thousands of things at once — and training is thousands of identical number-crunches, so it's a perfect fit. The magic is that switching is one line:

python
# pick GPU if available, else CPU — the standard pattern
device = "cuda" if torch.cuda.is_available() else "cpu"

x = torch.randn(1000, 1000)
x = x.to(device)          # move the tensor to the GPU (or CPU)

print("running on:", device)
Analogy — 1 chef vs 1000 line cooks

A CPU is one brilliant chef making dishes one at a time. A GPU is 1000 line cooks each doing one simple step simultaneously. For a single fancy dish, the chef wins. For "chop 1000 onions" (i.e. training), the 1000 cooks demolish it. Training is millions of tiny identical operations — that's why GPUs win.

Watch the difference on a big matrix multiply (simulated):

Same job: CPU vs GPU (simulated)
Multiplying two big matrices.
🖥️ CPU
⚡ GPU
Reality check

Exact speedups depend on the task and hardware — small jobs may even be slower on GPU (moving data over has a cost). GPUs win big on large batches, which is exactly what training does. Don't worry about this yet; Modules 1–5 run fine on CPU.

🎯 Check your understanding

Quick challenge

1. What is a tensor?
2. Why is Colab recommended for starting out?
3. What does torch.cuda.is_available() tell you?
4. What's the shape of torch.tensor([[1,2,3],[4,5,6]])?
5. How do you move a tensor to the GPU?
Takeaway

What you set up

You need Python + PyTorch (and a GPU eventually). Start in Google Colab — zero install, free GPU, runs anywhere; go local when you want to own the environment. The core object is the tensor: a container of numbers with a shape (scalar → vector → matrix → n-D) — the same vectors you saw as flattened images and embeddings in the fundamentals. Move work to a GPU with one line: x.to("cuda"). Verify any setup with torch.__version__ and torch.cuda.is_available().

Next up → Module 2: Autograd — the engine that makes training possible. You'll build the "turning the knobs" from fundamentals Module 3 as real code: PyTorch computing gradients automatically so a network can learn.