{"slug": "training-my-first-neural-network-on-windows-with-wsl-2-and-pytorch", "title": "Training My First Neural Network on Windows with WSL 2 and PyTorch", "summary": "A physics undergraduate documented a step-by-step workflow for training a first neural network on Windows using WSL 2, Ubuntu, a Python virtual environment, and PyTorch. The guide walks through installing Ubuntu via `wsl --install -d Ubuntu`, setting up the project in the Linux home directory, and building a small network for the XOR problem that ends with a saved model file. The author notes a GPU is unnecessary for the four-example experiment and that the focus is on getting the workflow running rather than the underlying mathematics.", "body_md": "As a physics undergraduate beginning to explore AI research, I wanted to understand the practical workflow behind a neural network experiment: where the code lives, how the environment works, how to run training, and what gets saved afterward.\n\nThis tutorial brings together my setup notes and first PyTorch experiment. We will build a small network for XOR, starting from a Windows computer and ending with a saved model file. The focus is on getting the workflow running; the mathematics can come later.\n\nYou need a supported Windows 10 or Windows 11 installation, permission to install WSL, and an internet connection. A GPU is unnecessary for this four-example experiment.\n\nThe workflow is **Windows terminal → WSL 2 → Ubuntu → project folder → Python virtual environment → PyTorch → training results**.\n\n| Tool | Role in this experiment | \n|---|---|\n| CMD / PowerShell | Launches WSL from Windows | \n| WSL 2 | Runs a Linux kernel using lightweight virtualization | \n| Ubuntu | Provides the Linux operating environment | \n| APT | Installs Ubuntu system packages | \n| Python | Executes our training script | \n| venv | Isolates the project's Python dependencies | \n| pip | Installs packages inside that environment | \n| PyTorch | Provides tensors, neural network layers, and automatic differentiation | \n\nDocker is an optional next step for packaging environments. Ordinary Ubuntu and PyTorch development works without Docker Desktop running.\n\nRun these commands in **Windows CMD or PowerShell**:\n\n```\nwsl -l -v\n```\n\nOn my machine, the only listed distribution was initially `docker-desktop`. That did not mean I already had an Ubuntu development environment.\n\nTo install Ubuntu, open **PowerShell as administrator** and run:\n\n```\nwsl --install -d Ubuntu\n```\n\nRestart Windows if prompted. On Ubuntu's first launch, create a Linux username and password. The password input displays no characters or asterisks.\n\nCheck the installation from Windows:\n\n```\nwsl -l -v\n```\n\nConfirm that Ubuntu is listed with `VERSION 2`. If it uses version 1, run:\n\n```\nwsl --set-version Ubuntu 2\n```\n\nOptionally make Ubuntu the default, then launch it:\n\n```\nwsl --set-default Ubuntu\nwsl -d Ubuntu\n```\n\nFor installation requirements and troubleshooting, see [Microsoft's WSL installation guide](https://learn.microsoft.com/en-us/windows/wsl/install).\n\nFrom this point onward, commands run **inside Ubuntu**, unless explicitly labeled otherwise.\n\nA terminal prompt might look like:\n\n```\nlawson@computer:~$\n```\n\n`lawson` is the Linux username, `computer` is the hostname, and `~` means the user's home directory. Do not copy the prompt itself when running commands.\n\nYour Linux home directory is typically `/home/<username>`. Windows drives are accessible through paths such as `/mnt/c/`. For this experiment, keep the project in your Linux home directory.\n\n```\ncd ~\npwd\nls\n```\n\n| Command | What it does | \n|---|---|\n| `pwd` | Prints the current working directory | \n| `ls` | Lists directory contents | \n| `cd` | Changes directories | \n| `mkdir` | Creates directories | \n| `touch` | Creates an empty file or updates its timestamps | \n| `cat` | Displays or combines file contents | \n| `sudo` | Runs a command as another user, usually root | \n\nAPT manages Ubuntu packages. Refresh its package information and install the tools we need:\n\n```\nsudo apt update\nsudo apt install -y git python3 python3-pip python3-venv nano\n```\n\nThen check:\n\n```\npython3 --version\ngit --version\n```\n\nAPT handles system software; pip handles Python packages. In the following steps, pip installs packages into our project environment.\n\n```\ncd ~\nmkdir -p research/first-neural-network\ncd research/first-neural-network\npwd\n```\n\nThe path should end with `research/first-neural-network`.\n\nThe diagram's version numbers are examples: each project can manage its own dependencies independently.\n\nCreate and activate the environment:\n\n```\npython3 -m venv .venv\nsource .venv/bin/activate\n```\n\nYour prompt should now begin with `(.venv)`. Closing the terminal leaves this directory on disk; you will reactivate it in the next session.\n\nWith `.venv` active, install a CPU build of PyTorch and NumPy:\n\n```\npython -m pip install --upgrade pip\npython -m pip install torch --index-url https://download.pytorch.org/whl/cpu\npython -m pip install numpy\n```\n\nCheck [PyTorch's official installation selector](https://pytorch.org/get-started/locally/) for supported Python versions or a GPU-specific installation command.\n\nVerify the installation:\n\n``` python\npython -c \"import torch, numpy; print('PyTorch:', torch.__version__); print('NumPy:', numpy.__version__)\"\npython -c \"import torch; print(torch.rand(2, 2))\"\n```\n\nThe second command should print a random 2 × 2 tensor. In my original setup, tensor creation worked but PyTorch warned that NumPy was missing. Installing NumPy resolved that missing dependency.\n\nOur task is XOR: output `1` when the two inputs differ and `0` when they match.\n\n| Input | Target | \n|---|---|\n| `[0, 0]` | `0` | \n| `[0, 1]` | `1` | \n| `[1, 0]` | `1` | \n| `[1, 1]` | `0` | \n\nOpen a new file:\n\n```\nnano train.py\n```\n\nPaste this code:\n\n``` python\nimport torch\nimport torch.nn as nn\n\ntorch.manual_seed(42)\n\n# 1. Training data\nX = torch.tensor([\n    [0., 0.],\n    [0., 1.],\n    [1., 0.],\n    [1., 1.]\n])\ny = torch.tensor([[0.], [1.], [1.], [0.]])\n\n# 2. A small network: two inputs, four hidden units, one output\nmodel = nn.Sequential(\n    nn.Linear(2, 4),\n    nn.Tanh(),\n    nn.Linear(4, 1)\n)\n\n# 3. Loss and optimizer\ncriterion = nn.BCEWithLogitsLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=0.05)\n\n# 4. Training\nmodel.train()\nfor epoch in range(2001):\n    optimizer.zero_grad()\n    logits = model(X)\n    loss = criterion(logits, y)\n    loss.backward()\n    optimizer.step()\n\n    if epoch % 200 == 0:\n        print(f\"Epoch {epoch}, Loss: {loss.item():.6f}\")\n\n# 5. Inspect predictions on the four training examples\nmodel.eval()\nwith torch.no_grad():\n    probabilities = torch.sigmoid(model(X))\n    predicted_labels = (probabilities >= 0.5).int()\n    print(\"\\nProbabilities:\")\n    print(probabilities)\n    print(\"\\nPredicted labels:\")\n    print(predicted_labels)\n\n# 6. Save learned parameters\ntorch.save(model.state_dict(), \"xor_model.pth\")\nprint(\"\\nSaved weights to xor_model.pth\")\n```\n\nSave with **Ctrl + O**, press **Enter**, and exit with **Ctrl + X**.\n\nThe loop computes predictions, measures the error, computes gradients, and updates parameters. `BCEWithLogitsLoss` takes the network's raw output, so the sigmoid is applied when inspecting probabilities afterward.\n\nThis is a small network with one hidden layer. It is a first neural network training exercise, rather than a large-scale deep learning experiment.\n\n```\npython train.py\n```\n\nOne mistake I made was trying `torch train.py`. PyTorch is a Python library; Python executes the file.\n\nYou should see periodic loss reports, followed by probabilities and labels. Check that the loss trends downward and the predicted labels are:\n\n```\ntensor([[0],\n        [1],\n        [1],\n        [0]], dtype=torch.int32)\n```\n\nExact probabilities and loss values can vary with software versions. These predictions use the same four examples used for training, so they check that the network learned the XOR truth table; they do not measure generalization to a separate dataset.\n\nCheck the files:\n\n```\nls -lh train.py xor_model.pth\n```\n\n`xor_model.pth` contains the model's parameter state dictionary. It does not contain the training script or a complete experiment checkpoint. To restore these weights later, recreate the same architecture and load the state dictionary; see [PyTorch's saving and loading tutorial](https://docs.pytorch.org/tutorials/beginner/basics/saveloadrun_tutorial.html).\n\nIn **Windows CMD or PowerShell**:\n\n```\nwsl -d Ubuntu\n```\n\nInside **Ubuntu**:\n\n```\ncd ~/research/first-neural-network\nsource .venv/bin/activate\npython train.py\n```\n\nThis runs training again from newly initialized weights. It does not resume the previously saved model automatically.\n\nTo leave the environment, run `deactivate`. To leave Ubuntu, run `exit`. An active foreground process may terminate if its terminal closes, but files already saved remain on disk.\n\n| Problem | Fix | \n|---|---|\n| `torch: command not found` | Run `python train.py` | \n| `No module named 'torch'` | Activate `.venv` , then install PyTorch with that environment's Python | \n| `No module named 'numpy'` | Run `python -m pip install numpy` in`.venv` | \n| `train.py` prints nothing | Check that the file contains and saves the code | \n| `wsl -l -v` fails inside Ubuntu | Run it from Windows, or use `wsl.exe -l -v` inside Ubuntu | \n| Docker Desktop is stopped | Docker is optional for this experiment | \n| The terminal was closed | Reopen Ubuntu, return to the folder, and reactivate `.venv` | \n\nThis diagram from my notes shows a possible later setup with Docker and GPU acceleration. Those components are optional extensions beyond the CPU workflow used here.\n\nFor larger experiments, I want to connect local development and version control with remote compute, then keep model weights, metrics, figures, and logs together. Access to university computing platforms depends on their own eligibility and allocation rules.\n\nThe useful milestone here is modest but concrete: a project directory, isolated dependencies, an executable training script, inspectable predictions, and saved parameters.\n\nMy notes and projects: [GitHub](https://github.com/Lawson-Dong) · [Personal website](https://lawson-dong.vercel.app/)", "url": "https://wpnews.pro/news/training-my-first-neural-network-on-windows-with-wsl-2-and-pytorch", "canonical_source": "https://dev.to/lawson_dong/training-my-first-neural-network-on-windows-with-wsl-2-and-pytorch-3him", "published_at": "2026-10-11 05:13:48+00:00", "updated_at": "2026-10-11 05:19:53.869154+00:00", "lang": "en", "topics": ["neural-networks", "machine-learning", "developer-tools"], "entities": ["PyTorch", "WSL 2", "Ubuntu", "Microsoft", "Windows", "Python"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/training-my-first-neural-network-on-windows-with-wsl-2-and-pytorch", "markdown": "https://wpnews.pro/news/training-my-first-neural-network-on-windows-with-wsl-2-and-pytorch.md", "text": "https://wpnews.pro/news/training-my-first-neural-network-on-windows-with-wsl-2-and-pytorch.txt", "jsonld": "https://wpnews.pro/news/training-my-first-neural-network-on-windows-with-wsl-2-and-pytorch.jsonld"}}