A feedforward neural network (perceptron) built from scratch in Java to classify handwritten digits from the MNIST dataset.
| Metric | Value |
|---|---|
| Test Accuracy | 97.33% |
| Training Samples | 60,000 |
| Test Samples | 10,000 |
| Epochs | 5 |
| Learning Rate | 0.01 |
Confusion Matrix (row=actual, col=predicted):
0 1 2 3 4 5 6 7 8 9
0 971 1 0 1 1 1 2 0 2 1
1 0 1124 2 1 1 2 2 0 3 0
2 3 5 1002 2 5 0 4 2 8 1
3 1 0 6 979 0 16 0 2 2 4
4 0 0 3 0 971 0 3 0 0 5
5 3 0 0 2 2 879 2 1 2 1
6 5 3 1 1 5 14 927 0 2 0
7 2 7 17 5 7 1 1 956 2 30
8 4 0 3 2 4 9 1 2 942 7
9 0 3 0 2 12 6 1 2 1 982
Input Layer Hidden Layer Output Layer
(784 neurons) → (128 neurons) → (10 neurons)
28×28 pixels ReLU activation Softmax activation
Classes: 0–9
- Input Layer: 784 neurons (one per pixel of 28×28 grayscale image), normalized to [0, 1]
- Hidden Layer: 128 neurons with ReLU activation, Xavier weight initialization
- Output Layer: 10 neurons with Softmax activation (one per digit class)
- Loss Function: Cross-Entropy Loss
- Optimizer: Stochastic Gradient Descent (SGD)
mnist-perceptron/
├── src/
│ ├── main/
│ │ ├── java/com/mnist/
│ │ │ ├── NeuralNetwork.java # Core neural network (forward/backprop)
│ │ │ ├── MnistLoader.java # MNIST data loader (.gz files)
│ │ │ └── Main.java # Training + evaluation + confusion matrix
│ │ └── resources/
│ │ ├── train-images-idx3-ubyte.gz
│ │ ├── train-labels-idx1-ubyte.gz
│ │ ├── t10k-images-idx3-ubyte.gz
│ │ └── t10k-labels-idx1-ubyte.gz
│ └── test/
│ └── java/com/mnist/
│ └── NeuralNetworkTest.java # Unit tests (5 tests, all passing)
└── pom.xml
All 5 unit tests pass using java.util.Random for input generation:
| Test | Description | Status |
|---|---|---|
testOutputSize |
Output layer has exactly 10 neurons | ✅ |
testSoftmaxSumsToOne |
Softmax probabilities sum to 1.0 | ✅ |
testPredictInRange |
Predictions are always in range [0, 9] | ✅ |
testTrainingReducesLoss |
Loss decreases after 200 training steps | ✅ |
testWeightDimensions |
Weight matrices have correct dimensions | ✅ |
- Java 17+
- Maven 3.6+
- MNIST dataset files in
src/main/resources/
mvn testmvn compile exec:java -Dexec.mainClass="com.mnist.Main"MNIST dataset: 70,000 handwritten digit images (28×28 grayscale pixels)
- 60,000 training samples
- 10,000 test samples
- Source: http://yann.lecun.com/exdb/mnist/
- Java 17
- JUnit Jupiter 5.10.2 (unit testing)
- Maven Surefire Plugin 3.2.5