Skip to content

fix hw3#9

Merged
akshayka merged 1 commit into
mainfrom
aka/fix-hw3
Jul 17, 2026
Merged

fix hw3#9
akshayka merged 1 commit into
mainfrom
aka/fix-hw3

Conversation

@akshayka

Copy link
Copy Markdown
Contributor

This PR brings the content in hw3 in line with the original course notebook. Fixes #7

Copilot AI review requested due to automatic review settings July 17, 2026 17:26
@akshayka
akshayka merged commit e5bca50 into main Jul 17, 2026
@akshayka
akshayka deleted the aka/fix-hw3 branch July 17, 2026 17:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Homework 3’s marimo/PyTorch training notebook content to better match the original course notebook (Fixes #7), mainly by expanding and revising the instructional markdown and refreshing the saved marimo session metadata.

Changes:

  • Expanded/rewrote HW3 narrative instructions for linear models, SGD, DataLoader iteration, and NN extensions.
  • Added a requires-python header constraint to the HW3 script.
  • Updated the marimo session JSON (including a marimo_version bump and clearing prior stored outputs).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 9 comments.

File Description
homework/hw3/hw3.py Updates the HW3 written instructions and adds a Python version requirement line.
homework/hw3/__marimo__/session/hw3.py.json Refreshes marimo session metadata, including a marimo version bump and output clearing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread homework/hw3/hw3.py
Comment on lines +65 to +67
In this homework, we'll start to build and train machine learning models (both a linear model a neural network) using PyTorch. While a lot of the code you will develop here corresponds to existing implementations in the PyTorch `nn` module, you will implement almost everything from scratch in these assignments, rather than use pre-built layers. Specifically you will use only the `Module`, and `Parameter` classes from PyTorch (later assignments will also use `ModuleList` and `Buffer`), and everything else should be implemented just with the calls included in the base `torch` library.

1. A `Linear` layer as a `Module` subclass
2. A `CrossEntropyLoss` module
3. A `SGD` optimizer
4. A `DataLoader` class
5. An `epoch` function that runs one pass over the data
***Important:*** **To be very explicit, you solutions in this, and all later problem sets, should _not_ use any classes or functions from within the `torch.nn` module, nor function calls from the `torch.nn.functional` module. You should only use calls available in the base `torch.` module.**
Comment thread homework/hw3/hw3.py
Comment on lines +98 to +99
- All PyTorch layers are implemented as a subclasses of the `Module` class. This class implements a few things: 1) it lets you instatiate layers as class instances, and apply these layers to inputs or intermediate units in the network; 2) it encapsulates the parameters of that layer (e.g., the weights that you will be training), and recursively tracks parameters of any module included in the class.
- The `Parameter` class is a simple wrapper you can provide apply to a tensor within that class, such that the layer will track these parameters (in any layer that includes it), and compute gradients of the parameters by default.
Comment thread homework/hw3/hw3.py
For the linear layer in particular:

The forward pass should compute the matrix multiplication $X W^T$ where $X$ is the input and $W$ is the weight matrix. Note that this should work for inputs of arbitrary batch dimensions (e.g., both 2D inputs of shape `(batch, in_dim)` and 3D inputs of shape `(batch1, batch2, in_dim)` should be supported). You can use the `@` operator for matrix multiplication, which handles broadcasting automatically.
- You should store the weights is a `.weight` Parameter in the class, which should be an `out_dim x in_dim` dimensional tensor. You should initialize with the $\sqrt{2/\text{in\_dim}}$ scaling of random Gaussian weights that we discussed in class.
Comment thread homework/hw3/hw3.py
- In `zero_grad()`, you should set each parameter's `.grad` to `None`.
### Stochastic Gradient Descent

Next, you'll implement stochastic gradient descent as a class similar to the analogous class in the PyTorch. This is not at `Module` class, and in fact rather than subclass the analogous `Optimizer` class in PyTorch, we'll just define the class directly, and use a similar interface to what PyTorch uses in its optimizers.
Comment thread homework/hw3/hw3.py
Implement these operations in the class below. There are a few pitfalls to keep in mind:

- In your `__init__` function, you should explicitly call `list()` on the `parameters` input to store it in your class. This is because the `model.parameters()` function returns a Python generator, an object that can be iterated over _one_ time to return all its elements. So if you only store the passed `parameters` variable and then try to iterate over it during your `zero_grad` or `step` functions, you will only iterate over the parameters one time, and thereafter there won't be any elements to iterate over.
- You need to compute the updates to the parameters within a `torch.no_grad()` block, as shown below. The reason for this is that otherwise, the gradient update will happen _within a automatic differentiation loop itself_, i.e., you will be computing the gradient of the entire chain of parameter updates you perform with gradient descent. There are actually some very cool reasons why it's often useful to differentiate through an entire parameter update, but that is definitely not what we want here.
Comment thread homework/hw3/hw3.py
Comment on lines +300 to +303
### to iterate over the dataset
for X,y in loader:
### X,y contain each sequential sequential from X_full,y_full
```
Comment thread homework/hw3/hw3.py
Comment on lines +376 to +379
Finally, let's implement a routine that actually runs an epoch of optimization on a given dataset. It's convenient (though we'll change this a bit when we do LLM training, since that it typically run single-epoch) to implement an `epoch()` function that carries out a single pass over the data, because this can be used both perform one epoch of optimization on the training set _and_ to compute test loss/error on a held out test set (making sure we don't actually run the optimization then).

Implement the function below. This function takes three arguments a model, a loader, a loss, and an (optional) optimizer. An example usage would be:
```python
Comment thread homework/hw3/hw3.py
Comment on lines +388 to +391
- Iterate over all minibatches in the data loader
- For each minibatch, compute the model's predicted outputs and the loss between the predicted and desired outputs.
- If `opt` is not none, update the model parameters using the optimization
- Over the entire data loader, capture a running total of the total loss and total error over all samples, then return the average loss and average error.
Comment on lines 3 to 6
"metadata": {
"marimo_version": "0.20.4",
"marimo_version": "0.23.14",
"script_metadata_hash": "845cb5ce3dcb38df36e3eb032b046444"
},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HW 3 is Missing Content

2 participants