Added Deep CNN and ayugmentation

This commit is contained in:
KeshavAnandCode committed 2026-03-18 22:59:28 -05:00
1 parent 59f26a299c
commit 6f854a9d62
6 files changed
+1461 -151

No files matched your search

+33 -33
View File
@@ -2,7 +2,7 @@
"cells": [ "cells": [
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 17, "execution_count": 1,
"id": "7a37220a", "id": "7a37220a",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -20,7 +20,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 18, "execution_count": 2,
"id": "d318d1f0", "id": "d318d1f0",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -61,7 +61,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 19, "execution_count": 3,
"id": "5604ace3", "id": "5604ace3",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -110,7 +110,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 20, "execution_count": 4,
"id": "3cedd586", "id": "3cedd586",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -150,7 +150,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 21, "execution_count": 5,
"id": "8f556b22", "id": "8f556b22",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -184,7 +184,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 22, "execution_count": 6,
"id": "37793c77", "id": "37793c77",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -222,7 +222,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 23, "execution_count": 7,
"id": "f68c1a25", "id": "f68c1a25",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -257,7 +257,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 24, "execution_count": 8,
"id": "e1539eaa", "id": "e1539eaa",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -289,7 +289,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 25, "execution_count": 9,
"id": "d1b7d9ca", "id": "d1b7d9ca",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -347,7 +347,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 26, "execution_count": 10,
"id": "54d11a04", "id": "54d11a04",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
@@ -370,7 +370,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 27, "execution_count": 11,
"id": "374d0590", "id": "374d0590",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -378,16 +378,16 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Epoch 1: Loss=1.626, Accuracy=45.59%\n", "Epoch 1: Loss=1.480, Accuracy=50.95%\n",
"Epoch 2: Loss=1.137, Accuracy=60.53%\n", "Epoch 2: Loss=1.073, Accuracy=62.46%\n",
"Epoch 3: Loss=0.992, Accuracy=65.56%\n", "Epoch 3: Loss=0.974, Accuracy=66.04%\n",
"Epoch 4: Loss=0.911, Accuracy=68.28%\n", "Epoch 4: Loss=0.899, Accuracy=68.51%\n",
"Epoch 5: Loss=0.853, Accuracy=70.51%\n", "Epoch 5: Loss=0.834, Accuracy=70.87%\n",
"Epoch 6: Loss=0.806, Accuracy=72.12%\n", "Epoch 6: Loss=0.779, Accuracy=72.60%\n",
"Epoch 7: Loss=0.753, Accuracy=73.36%\n", "Epoch 7: Loss=0.730, Accuracy=74.29%\n",
"Epoch 8: Loss=0.708, Accuracy=75.08%\n", "Epoch 8: Loss=0.689, Accuracy=75.64%\n",
"Epoch 9: Loss=0.669, Accuracy=76.77%\n", "Epoch 9: Loss=0.649, Accuracy=77.14%\n",
"Epoch 10: Loss=0.637, Accuracy=77.62%\n", "Epoch 10: Loss=0.620, Accuracy=78.21%\n",
"Finished Training\n" "Finished Training\n"
] ]
} }
@@ -425,7 +425,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 28, "execution_count": 12,
"id": "2bf2b9a2", "id": "2bf2b9a2",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
@@ -444,7 +444,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 29, "execution_count": 13,
"id": "bc158602", "id": "bc158602",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -452,7 +452,7 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Test Accuracy: 73.82%\n" "Test Accuracy: 76.35%\n"
] ]
} }
], ],
@@ -474,7 +474,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 30, "execution_count": 14,
"id": "8cc7ed40", "id": "8cc7ed40",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -482,14 +482,14 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Accuracy for class: Bicycle is 60.3%\n", "Accuracy for class: Bicycle is 45.2%\n",
"Accuracy for class: Bus is 84.7%\n", "Accuracy for class: Bus is 71.3%\n",
"Accuracy for class: Car is 74.3%\n", "Accuracy for class: Car is 77.3%\n",
"Accuracy for class: Motorcycle is 59.7%\n", "Accuracy for class: Motorcycle is 81.2%\n",
"Accuracy for class: NonVehicles is 99.9%\n", "Accuracy for class: NonVehicles is 98.2%\n",
"Accuracy for class: Taxi is 35.9%\n", "Accuracy for class: Taxi is 37.0%\n",
"Accuracy for class: Truck is 16.4%\n", "Accuracy for class: Truck is 35.6%\n",
"Accuracy for class: Van is 27.3%\n" "Accuracy for class: Van is 35.5%\n"
] ]
} }
], ],
+39 -39
View File
@@ -378,36 +378,36 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Epoch 1: Loss=1.763, Accuracy=41.55%\n", "Epoch 1: Loss=1.732, Accuracy=43.80%\n",
"Epoch 2: Loss=1.320, Accuracy=55.89%\n", "Epoch 2: Loss=1.403, Accuracy=54.06%\n",
"Epoch 3: Loss=1.035, Accuracy=63.69%\n", "Epoch 3: Loss=1.137, Accuracy=60.66%\n",
"Epoch 4: Loss=0.915, Accuracy=68.51%\n", "Epoch 4: Loss=1.003, Accuracy=64.95%\n",
"Epoch 5: Loss=0.845, Accuracy=70.83%\n", "Epoch 5: Loss=0.917, Accuracy=67.92%\n",
"Epoch 6: Loss=0.807, Accuracy=72.21%\n", "Epoch 6: Loss=0.845, Accuracy=70.22%\n",
"Epoch 7: Loss=0.766, Accuracy=73.35%\n", "Epoch 7: Loss=0.796, Accuracy=72.06%\n",
"Epoch 8: Loss=0.752, Accuracy=73.76%\n", "Epoch 8: Loss=0.741, Accuracy=73.88%\n",
"Epoch 9: Loss=0.720, Accuracy=75.00%\n", "Epoch 9: Loss=0.711, Accuracy=75.05%\n",
"Epoch 10: Loss=0.688, Accuracy=76.09%\n", "Epoch 10: Loss=0.670, Accuracy=76.52%\n",
"Epoch 11: Loss=0.646, Accuracy=77.31%\n", "Epoch 11: Loss=0.636, Accuracy=77.59%\n",
"Epoch 12: Loss=0.623, Accuracy=78.31%\n", "Epoch 12: Loss=0.611, Accuracy=78.49%\n",
"Epoch 13: Loss=0.596, Accuracy=79.13%\n", "Epoch 13: Loss=0.580, Accuracy=79.42%\n",
"Epoch 14: Loss=0.567, Accuracy=80.19%\n", "Epoch 14: Loss=0.546, Accuracy=80.87%\n",
"Epoch 15: Loss=0.530, Accuracy=81.66%\n", "Epoch 15: Loss=0.519, Accuracy=81.77%\n",
"Epoch 16: Loss=0.502, Accuracy=82.52%\n", "Epoch 16: Loss=0.502, Accuracy=82.36%\n",
"Epoch 17: Loss=0.473, Accuracy=83.62%\n", "Epoch 17: Loss=0.474, Accuracy=83.28%\n",
"Epoch 18: Loss=0.447, Accuracy=84.63%\n", "Epoch 18: Loss=0.445, Accuracy=84.34%\n",
"Epoch 19: Loss=0.416, Accuracy=85.71%\n", "Epoch 19: Loss=0.424, Accuracy=85.12%\n",
"Epoch 20: Loss=0.401, Accuracy=86.22%\n", "Epoch 20: Loss=0.392, Accuracy=86.07%\n",
"Epoch 21: Loss=0.353, Accuracy=87.89%\n", "Epoch 21: Loss=0.366, Accuracy=86.99%\n",
"Epoch 22: Loss=0.321, Accuracy=89.02%\n", "Epoch 22: Loss=0.330, Accuracy=88.30%\n",
"Epoch 23: Loss=0.282, Accuracy=90.39%\n", "Epoch 23: Loss=0.304, Accuracy=89.51%\n",
"Epoch 24: Loss=0.260, Accuracy=91.10%\n", "Epoch 24: Loss=0.267, Accuracy=90.67%\n",
"Epoch 25: Loss=0.243, Accuracy=91.71%\n", "Epoch 25: Loss=0.227, Accuracy=92.35%\n",
"Epoch 26: Loss=0.203, Accuracy=93.18%\n", "Epoch 26: Loss=0.222, Accuracy=92.38%\n",
"Epoch 27: Loss=0.169, Accuracy=94.36%\n", "Epoch 27: Loss=0.176, Accuracy=94.24%\n",
"Epoch 28: Loss=0.139, Accuracy=95.55%\n", "Epoch 28: Loss=0.156, Accuracy=94.71%\n",
"Epoch 29: Loss=0.112, Accuracy=96.42%\n", "Epoch 29: Loss=0.143, Accuracy=94.92%\n",
"Epoch 30: Loss=0.106, Accuracy=96.63%\n", "Epoch 30: Loss=0.124, Accuracy=95.87%\n",
"Finished Training\n" "Finished Training\n"
] ]
} }
@@ -472,7 +472,7 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Test Accuracy: 77.52%\n" "Test Accuracy: 78.54%\n"
] ]
} }
], ],
@@ -502,14 +502,14 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Accuracy for class: Bicycle is 57.6%\n", "Accuracy for class: Bicycle is 52.4%\n",
"Accuracy for class: Bus is 76.4%\n", "Accuracy for class: Bus is 79.0%\n",
"Accuracy for class: Car is 82.3%\n", "Accuracy for class: Car is 74.9%\n",
"Accuracy for class: Motorcycle is 72.5%\n", "Accuracy for class: Motorcycle is 85.9%\n",
"Accuracy for class: NonVehicles is 99.1%\n", "Accuracy for class: NonVehicles is 98.7%\n",
"Accuracy for class: Taxi is 27.8%\n", "Accuracy for class: Taxi is 58.2%\n",
"Accuracy for class: Truck is 38.9%\n", "Accuracy for class: Truck is 44.9%\n",
"Accuracy for class: Van is 25.0%\n" "Accuracy for class: Van is 29.8%\n"
] ]
} }
], ],
+39 -39
View File
@@ -378,36 +378,36 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Epoch 1: Loss=1.379, Accuracy=54.06%\n", "Epoch 1: Loss=1.337, Accuracy=56.65%\n",
"Epoch 2: Loss=0.980, Accuracy=66.04%\n", "Epoch 2: Loss=0.965, Accuracy=66.88%\n",
"Epoch 3: Loss=0.878, Accuracy=69.10%\n", "Epoch 3: Loss=0.870, Accuracy=69.80%\n",
"Epoch 4: Loss=0.793, Accuracy=71.95%\n", "Epoch 4: Loss=0.789, Accuracy=72.31%\n",
"Epoch 5: Loss=0.734, Accuracy=74.29%\n", "Epoch 5: Loss=0.746, Accuracy=73.78%\n",
"Epoch 6: Loss=0.692, Accuracy=75.72%\n", "Epoch 6: Loss=0.692, Accuracy=75.63%\n",
"Epoch 7: Loss=0.651, Accuracy=76.99%\n", "Epoch 7: Loss=0.659, Accuracy=76.80%\n",
"Epoch 8: Loss=0.616, Accuracy=78.33%\n", "Epoch 8: Loss=0.624, Accuracy=77.99%\n",
"Epoch 9: Loss=0.583, Accuracy=79.80%\n", "Epoch 9: Loss=0.608, Accuracy=78.58%\n",
"Epoch 10: Loss=0.554, Accuracy=80.75%\n", "Epoch 10: Loss=0.566, Accuracy=80.22%\n",
"Epoch 11: Loss=0.533, Accuracy=81.49%\n", "Epoch 11: Loss=0.540, Accuracy=80.91%\n",
"Epoch 12: Loss=0.505, Accuracy=82.45%\n", "Epoch 12: Loss=0.517, Accuracy=81.71%\n",
"Epoch 13: Loss=0.480, Accuracy=83.14%\n", "Epoch 13: Loss=0.495, Accuracy=82.49%\n",
"Epoch 14: Loss=0.453, Accuracy=84.20%\n", "Epoch 14: Loss=0.460, Accuracy=84.00%\n",
"Epoch 15: Loss=0.420, Accuracy=85.17%\n", "Epoch 15: Loss=0.436, Accuracy=84.83%\n",
"Epoch 16: Loss=0.392, Accuracy=86.41%\n", "Epoch 16: Loss=0.405, Accuracy=85.72%\n",
"Epoch 17: Loss=0.377, Accuracy=86.77%\n", "Epoch 17: Loss=0.380, Accuracy=86.55%\n",
"Epoch 18: Loss=0.343, Accuracy=87.99%\n", "Epoch 18: Loss=0.348, Accuracy=87.83%\n",
"Epoch 19: Loss=0.304, Accuracy=89.47%\n", "Epoch 19: Loss=0.322, Accuracy=88.65%\n",
"Epoch 20: Loss=0.274, Accuracy=90.54%\n", "Epoch 20: Loss=0.294, Accuracy=89.97%\n",
"Epoch 21: Loss=0.248, Accuracy=91.55%\n", "Epoch 21: Loss=0.265, Accuracy=90.71%\n",
"Epoch 22: Loss=0.215, Accuracy=92.74%\n", "Epoch 22: Loss=0.233, Accuracy=91.95%\n",
"Epoch 23: Loss=0.192, Accuracy=93.65%\n", "Epoch 23: Loss=0.210, Accuracy=92.85%\n",
"Epoch 24: Loss=0.167, Accuracy=94.75%\n", "Epoch 24: Loss=0.184, Accuracy=93.87%\n",
"Epoch 25: Loss=0.149, Accuracy=95.07%\n", "Epoch 25: Loss=0.163, Accuracy=94.46%\n",
"Epoch 26: Loss=0.128, Accuracy=95.86%\n", "Epoch 26: Loss=0.137, Accuracy=95.61%\n",
"Epoch 27: Loss=0.115, Accuracy=96.20%\n", "Epoch 27: Loss=0.118, Accuracy=96.28%\n",
"Epoch 28: Loss=0.092, Accuracy=97.10%\n", "Epoch 28: Loss=0.096, Accuracy=97.20%\n",
"Epoch 29: Loss=0.073, Accuracy=97.84%\n", "Epoch 29: Loss=0.080, Accuracy=97.70%\n",
"Epoch 30: Loss=0.060, Accuracy=98.39%\n", "Epoch 30: Loss=0.066, Accuracy=98.04%\n",
"Finished Training\n" "Finished Training\n"
] ]
} }
@@ -472,7 +472,7 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Test Accuracy: 75.11%\n" "Test Accuracy: 75.68%\n"
] ]
} }
], ],
@@ -502,14 +502,14 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Accuracy for class: Bicycle is 61.4%\n", "Accuracy for class: Bicycle is 68.8%\n",
"Accuracy for class: Bus is 61.8%\n", "Accuracy for class: Bus is 76.1%\n",
"Accuracy for class: Car is 79.5%\n", "Accuracy for class: Car is 66.5%\n",
"Accuracy for class: Motorcycle is 72.6%\n", "Accuracy for class: Motorcycle is 78.4%\n",
"Accuracy for class: NonVehicles is 98.9%\n", "Accuracy for class: NonVehicles is 98.5%\n",
"Accuracy for class: Taxi is 44.0%\n", "Accuracy for class: Taxi is 42.6%\n",
"Accuracy for class: Truck is 26.0%\n", "Accuracy for class: Truck is 41.2%\n",
"Accuracy for class: Van is 31.1%\n" "Accuracy for class: Van is 39.9%\n"
] ]
} }
], ],
+40 -40
View File
@@ -289,7 +289,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 9,
"id": "d1b7d9ca", "id": "d1b7d9ca",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -418,36 +418,36 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Epoch 1: Loss=1.374, Accuracy=60.99%\n", "Epoch 1: Loss=1.455, Accuracy=59.60%\n",
"Epoch 2: Loss=0.841, Accuracy=70.39%\n", "Epoch 2: Loss=0.872, Accuracy=69.47%\n",
"Epoch 3: Loss=0.718, Accuracy=74.55%\n", "Epoch 3: Loss=0.748, Accuracy=73.57%\n",
"Epoch 4: Loss=0.651, Accuracy=76.96%\n", "Epoch 4: Loss=0.669, Accuracy=76.44%\n",
"Epoch 5: Loss=0.595, Accuracy=78.95%\n", "Epoch 5: Loss=0.613, Accuracy=78.60%\n",
"Epoch 6: Loss=0.551, Accuracy=80.34%\n", "Epoch 6: Loss=0.575, Accuracy=79.73%\n",
"Epoch 7: Loss=0.536, Accuracy=81.03%\n", "Epoch 7: Loss=0.539, Accuracy=80.91%\n",
"Epoch 8: Loss=0.505, Accuracy=82.37%\n", "Epoch 8: Loss=0.507, Accuracy=82.19%\n",
"Epoch 9: Loss=0.478, Accuracy=82.90%\n", "Epoch 9: Loss=0.483, Accuracy=82.79%\n",
"Epoch 10: Loss=0.452, Accuracy=83.73%\n", "Epoch 10: Loss=0.461, Accuracy=83.69%\n",
"Epoch 11: Loss=0.432, Accuracy=84.58%\n", "Epoch 11: Loss=0.439, Accuracy=84.35%\n",
"Epoch 12: Loss=0.401, Accuracy=85.61%\n", "Epoch 12: Loss=0.409, Accuracy=85.46%\n",
"Epoch 13: Loss=0.385, Accuracy=86.30%\n", "Epoch 13: Loss=0.396, Accuracy=85.98%\n",
"Epoch 14: Loss=0.369, Accuracy=86.80%\n", "Epoch 14: Loss=0.369, Accuracy=86.39%\n",
"Epoch 15: Loss=0.350, Accuracy=87.43%\n", "Epoch 15: Loss=0.356, Accuracy=87.00%\n",
"Epoch 16: Loss=0.340, Accuracy=87.60%\n", "Epoch 16: Loss=0.351, Accuracy=87.15%\n",
"Epoch 17: Loss=0.321, Accuracy=87.97%\n", "Epoch 17: Loss=0.330, Accuracy=88.06%\n",
"Epoch 18: Loss=0.298, Accuracy=89.02%\n", "Epoch 18: Loss=0.307, Accuracy=88.95%\n",
"Epoch 19: Loss=0.267, Accuracy=90.22%\n", "Epoch 19: Loss=0.286, Accuracy=89.57%\n",
"Epoch 20: Loss=0.254, Accuracy=90.49%\n", "Epoch 20: Loss=0.253, Accuracy=90.44%\n",
"Epoch 21: Loss=0.237, Accuracy=91.32%\n", "Epoch 21: Loss=0.244, Accuracy=91.00%\n",
"Epoch 22: Loss=0.224, Accuracy=91.75%\n", "Epoch 22: Loss=0.233, Accuracy=91.22%\n",
"Epoch 23: Loss=0.209, Accuracy=92.18%\n", "Epoch 23: Loss=0.225, Accuracy=91.56%\n",
"Epoch 24: Loss=0.196, Accuracy=92.79%\n", "Epoch 24: Loss=0.201, Accuracy=92.63%\n",
"Epoch 25: Loss=0.185, Accuracy=93.13%\n", "Epoch 25: Loss=0.198, Accuracy=92.55%\n",
"Epoch 26: Loss=0.167, Accuracy=93.72%\n", "Epoch 26: Loss=0.178, Accuracy=93.46%\n",
"Epoch 27: Loss=0.171, Accuracy=93.74%\n", "Epoch 27: Loss=0.169, Accuracy=93.60%\n",
"Epoch 28: Loss=0.158, Accuracy=94.04%\n", "Epoch 28: Loss=0.149, Accuracy=94.44%\n",
"Epoch 29: Loss=0.148, Accuracy=94.42%\n", "Epoch 29: Loss=0.153, Accuracy=94.34%\n",
"Epoch 30: Loss=0.125, Accuracy=95.63%\n", "Epoch 30: Loss=0.135, Accuracy=95.05%\n",
"Finished Training\n" "Finished Training\n"
] ]
} }
@@ -512,7 +512,7 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Test Accuracy: 83.06%\n" "Test Accuracy: 83.30%\n"
] ]
} }
], ],
@@ -542,14 +542,14 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Accuracy for class: Bicycle is 77.6%\n", "Accuracy for class: Bicycle is 72.2%\n",
"Accuracy for class: Bus is 74.9%\n", "Accuracy for class: Bus is 83.6%\n",
"Accuracy for class: Car is 80.5%\n", "Accuracy for class: Car is 82.9%\n",
"Accuracy for class: Motorcycle is 83.3%\n", "Accuracy for class: Motorcycle is 84.2%\n",
"Accuracy for class: NonVehicles is 99.7%\n", "Accuracy for class: NonVehicles is 99.6%\n",
"Accuracy for class: Taxi is 53.4%\n", "Accuracy for class: Taxi is 52.5%\n",
"Accuracy for class: Truck is 51.6%\n", "Accuracy for class: Truck is 48.5%\n",
"Accuracy for class: Van is 45.4%\n" "Accuracy for class: Van is 45.0%\n"
] ]
} }
], ],
+620
View File
@@ -0,0 +1,620 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "7a37220a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello, World!\n"
]
}
],
"source": [
"print(\"Hello, World!\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "d318d1f0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Van: 1111 images\n",
"Taxi: 748 images\n",
"Bicycle: 1618 images\n",
"Bus: 2133 images\n",
"Car: 6781 images\n",
"Motorcycle: 2986 images\n",
"Truck: 2033 images\n",
"NonVehicles: 8968 images\n"
]
}
],
"source": [
"import os\n",
"\n",
"data_dir = '../data/raw/vehicle_classification'\n",
"\n",
"for class_name in os.listdir(data_dir):\n",
" class_path = os.path.join(data_dir, class_name)\n",
" if os.path.isdir(class_path):\n",
" count = len(os.listdir(class_path))\n",
" print(f\"{class_name}: {count} images\")"
]
},
{
"cell_type": "markdown",
"id": "64122ad4",
"metadata": {},
"source": [
"Check out sample image from dataset"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "5604ace3",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Size: (64, 64)\n",
"Mode: RGB\n"
]
},
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from PIL import Image\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# first image in first folder\n",
"first_class = os.listdir(data_dir)[0]\n",
"first_image_path = os.path.join(data_dir, first_class, os.listdir(os.path.join(data_dir, first_class))[0])\n",
"\n",
"img = Image.open(first_image_path)\n",
"print(f\"Size: {img.size}\")\n",
"print(f\"Mode: {img.mode}\")\n",
"plt.imshow(img)\n",
"plt.title(first_class)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "c19ec00a",
"metadata": {},
"source": [
"Ensure that all images are RGB, all of same resolution"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "3cedd586",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Unique sizes: {(64, 64)}\n",
"Unique modes: {'RGB'}\n"
]
}
],
"source": [
"sizes = set()\n",
"modes = set()\n",
"\n",
"for class_name in os.listdir(data_dir):\n",
" class_path = os.path.join(data_dir, class_name)\n",
" if not os.path.isdir(class_path):\n",
" continue\n",
" for img_name in os.listdir(class_path):\n",
" img = Image.open(os.path.join(class_path, img_name))\n",
" sizes.add(img.size)\n",
" modes.add(img.mode)\n",
"\n",
"print(f\"Unique sizes: {sizes}\")\n",
"print(f\"Unique modes: {modes}\")"
]
},
{
"cell_type": "markdown",
"id": "88ac961b",
"metadata": {},
"source": [
"Ensure that torch works with GPU (5080) [Credit: Claude]"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "8f556b22",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"True\n",
"NVIDIA GeForce RTX 5080\n",
"GPU works! torch.Size([1000, 1000])\n"
]
}
],
"source": [
"import torch\n",
"print(torch.cuda.is_available()) \n",
"print(torch.cuda.get_device_name(0)) \n",
"\n",
"x = torch.randn(1000, 1000).cuda()\n",
"y = x @ x\n",
"print(\"GPU works!\", y.shape)"
]
},
{
"cell_type": "markdown",
"id": "870fadbe",
"metadata": {},
"source": [
"Transform image dataset into tensors. Normalized with 0.5 mean and 0.5 STD (can be differente to use pretrained weights)."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "37793c77",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['Bicycle', 'Bus', 'Car', 'Motorcycle', 'NonVehicles', 'Taxi', 'Truck', 'Van']\n",
"26378\n"
]
}
],
"source": [
"from torchvision import datasets, transforms\n",
"from torch.utils.data import random_split, DataLoader\n",
"\n",
"transform = transforms.Compose([\n",
" transforms.ToTensor(),\n",
" transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])\n",
"])\n",
"\n",
"dataset = datasets.ImageFolder(root=data_dir, transform=transform)\n",
"\n",
"print(dataset.classes) # should print 8 classes\n",
"print(len(dataset)) # total image count"
]
},
{
"cell_type": "markdown",
"id": "ac33bc21",
"metadata": {},
"source": [
"Split 80-20 and save into 2 variables....augments the test set by rotating and lighting it differently to add training nuance."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "f68c1a25",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Train: 21102, Test: 5276\n"
]
}
],
"source": [
"import math \n",
"\n",
"train_transform = transforms.Compose([\n",
" transforms.RandomHorizontalFlip(), # randomly mirror image\n",
" transforms.RandomRotation(10), # rotate up to 10 degrees\n",
" transforms.ColorJitter(brightness=0.2, contrast=0.2), # vary lighting\n",
" transforms.ToTensor(),\n",
" transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])\n",
"])\n",
"\n",
"test_transform = transforms.Compose([\n",
" transforms.ToTensor(),\n",
" transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])\n",
"])\n",
"\n",
"train_full = datasets.ImageFolder(root=data_dir, transform=train_transform)\n",
"test_full = datasets.ImageFolder(root=data_dir, transform=test_transform)\n",
"\n",
"train_size = math.floor(len(train_full) * 0.8)\n",
"test_size = len(train_full) - train_size\n",
"\n",
"# Use same indices for both so split is consistent\n",
"indices = torch.randperm(len(train_full)).tolist()\n",
"train_indices = indices[:train_size]\n",
"test_indices = indices[train_size:]\n",
"\n",
"train_dataset = torch.utils.data.Subset(train_full, train_indices)\n",
"test_dataset = torch.utils.data.Subset(test_full, test_indices)\n",
"\n",
"print(f\"Train: {len(train_dataset)}, Test: {len(test_dataset)}\")"
]
},
{
"cell_type": "markdown",
"id": "2eede814",
"metadata": {},
"source": [
"Load the data into batches for faster loading...use 4 threads on CPU\n",
"\n",
"Shuffling train dataset so as to not overfit on one class"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "e1539eaa",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['Bicycle', 'Bus', 'Car', 'Motorcycle', 'NonVehicles', 'Taxi', 'Truck', 'Van']\n",
"8\n"
]
}
],
"source": [
"train_loader = DataLoader(train_dataset, batch_size=256, shuffle=True, num_workers=16)\n",
"test_loader = DataLoader(test_dataset, batch_size=256, shuffle=False, num_workers=16)\n",
"\n",
"classes = train_full.classes \n",
"print(classes)\n",
"print(len(classes))"
]
},
{
"cell_type": "markdown",
"id": "acebe98e",
"metadata": {},
"source": [
"MOdified tutorial arch to handle BathhNorm and Dropout (to try to prevent overfitting)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "d1b7d9ca",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Net(\n",
" (features): Sequential(\n",
" (0): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
" (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
" (2): ReLU()\n",
" (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
" (4): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
" (5): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
" (6): ReLU()\n",
" (7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
" (8): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
" (9): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
" (10): ReLU()\n",
" (11): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
" )\n",
" (classifier): Sequential(\n",
" (0): Flatten(start_dim=1, end_dim=-1)\n",
" (1): Linear(in_features=8192, out_features=512, bias=True)\n",
" (2): ReLU()\n",
" (3): Dropout(p=0.5, inplace=False)\n",
" (4): Linear(in_features=512, out_features=8, bias=True)\n",
" )\n",
")\n"
]
}
],
"source": [
"import torch\n",
"import torch.nn as nn\n",
"import torch.nn.functional as F\n",
"\n",
"class Net(nn.Module):\n",
" def __init__(self):\n",
" super(Net, self).__init__()\n",
"\n",
" self.features = nn.Sequential(\n",
" # go from 64x64 to 32x32\n",
"\n",
" # kernel size = 3x3 filter patch\n",
" #padding = 1, so 64x64 stays 64x64 after conv\n",
" nn.Conv2d(3, 32, kernel_size=3, padding=1), # 3 channel RRGB, 32 filters (recommended)\n",
"\n",
" nn.BatchNorm2d(32), # mirrors conv2d output\n",
" nn.ReLU(),\n",
" nn.MaxPool2d(2,2), # 2x2 window so halved --> 32x32\n",
"\n",
" #Go from 32x32 --> 16x16\n",
"\n",
" nn.Conv2d(32, 64, kernel_size=3, padding=1),\n",
" nn.BatchNorm2d(64),\n",
" nn.ReLU(),\n",
" nn.MaxPool2d(2,2), \n",
" \n",
" # Go from 16x 16 0 --> 8x8\n",
"\n",
" nn.Conv2d(64, 128, kernel_size=3, padding=1),\n",
" nn.BatchNorm2d(128),\n",
" nn.ReLU(),\n",
" nn.MaxPool2d(2,2), \n",
"\n",
" )\n",
"\n",
" self.classifier = nn.Sequential(\n",
" nn.Flatten(),\n",
" nn.Linear (128 * 8 *8, 512), # flattened size of 8x8 * 128, 512 is arbitrary output (recommended by sources)\n",
" nn.ReLU(),\n",
" nn.Dropout(0.5),#Randomly zero 50% of neurons --> prevent moeoorization\n",
" nn.Linear(512, len(classes)) # one score per vehicle class\n",
" )\n",
"\n",
" def forward(self, x):\n",
" x = self.features(x)\n",
" x = self.classifier(x)\n",
" return x\n",
"\n",
"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
"model = Net().to(device)\n",
"print(model)"
]
},
{
"cell_type": "markdown",
"id": "22e71032",
"metadata": {},
"source": [
"Loss fn and optimizer"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "54d11a04",
"metadata": {},
"outputs": [],
"source": [
"import torch.optim as optim\n",
"\n",
"criterion = nn.CrossEntropyLoss() # Applied softmax to convert scores --> probabilities --> penalizes model \n",
"\n",
"# Changed to adam optimizer (internal momentumn calculation)\n",
"optimizer = optim.Adam(model.parameters(), lr=0.001)"
]
},
{
"cell_type": "markdown",
"id": "572d80e3",
"metadata": {},
"source": [
"Tutorial training cell adapted to use 30 epochs "
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "374d0590",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1: Loss=1.405, Accuracy=59.91%\n",
"Epoch 2: Loss=0.880, Accuracy=69.16%\n",
"Epoch 3: Loss=0.770, Accuracy=72.99%\n",
"Epoch 4: Loss=0.714, Accuracy=75.05%\n",
"Epoch 5: Loss=0.660, Accuracy=76.92%\n",
"Epoch 6: Loss=0.629, Accuracy=78.41%\n",
"Epoch 7: Loss=0.596, Accuracy=79.03%\n",
"Epoch 8: Loss=0.588, Accuracy=79.40%\n",
"Epoch 9: Loss=0.556, Accuracy=80.52%\n",
"Epoch 10: Loss=0.543, Accuracy=81.06%\n",
"Epoch 11: Loss=0.520, Accuracy=81.85%\n",
"Epoch 12: Loss=0.513, Accuracy=81.94%\n",
"Epoch 13: Loss=0.501, Accuracy=82.56%\n",
"Epoch 14: Loss=0.485, Accuracy=82.90%\n",
"Epoch 15: Loss=0.481, Accuracy=82.92%\n",
"Epoch 16: Loss=0.469, Accuracy=83.50%\n",
"Epoch 17: Loss=0.459, Accuracy=84.02%\n",
"Epoch 18: Loss=0.453, Accuracy=83.94%\n",
"Epoch 19: Loss=0.445, Accuracy=84.24%\n",
"Epoch 20: Loss=0.434, Accuracy=84.77%\n",
"Epoch 21: Loss=0.427, Accuracy=84.97%\n",
"Epoch 22: Loss=0.412, Accuracy=85.20%\n",
"Epoch 23: Loss=0.411, Accuracy=85.15%\n",
"Epoch 24: Loss=0.402, Accuracy=85.52%\n",
"Epoch 25: Loss=0.403, Accuracy=85.32%\n",
"Epoch 26: Loss=0.393, Accuracy=85.93%\n",
"Epoch 27: Loss=0.386, Accuracy=86.07%\n",
"Epoch 28: Loss=0.380, Accuracy=86.28%\n",
"Epoch 29: Loss=0.372, Accuracy=86.65%\n",
"Epoch 30: Loss=0.362, Accuracy=87.02%\n",
"Finished Training\n"
]
}
],
"source": [
"for epoch in range(30): # 10 --> 30 epochs\n",
" running_loss = 0.0\n",
" correct = 0\n",
" total = 0\n",
"\n",
" for i, data in enumerate(train_loader, 0):\n",
" inputs, labels = data\n",
" inputs, labels = inputs.to(device), labels.to(device) # use GPU\n",
"\n",
" optimizer.zero_grad()\n",
"\n",
" outputs = model(inputs)\n",
" loss = criterion(outputs, labels)\n",
" loss.backward()\n",
" optimizer.step()\n",
"\n",
" # loss tracking\n",
" running_loss += loss.item()\n",
"\n",
" # accuracy tracking\n",
" _, predicted = torch.max(outputs, 1)\n",
" total += labels.size(0)\n",
" correct += (predicted == labels).sum().item()\n",
"\n",
" accuracy = 100 * correct / total\n",
" print(f'Epoch {epoch + 1}: Loss={running_loss / len(train_loader):.3f}, Accuracy={accuracy:.2f}%') # Credit: Claude for printing accuracy in good formatting\n",
"\n",
"print('Finished Training')"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "2bf2b9a2",
"metadata": {},
"outputs": [],
"source": [
"PATH = '../models/data-augmented.pth'\n",
"torch.save(model.state_dict(), PATH)"
]
},
{
"cell_type": "markdown",
"id": "a24dd4f0",
"metadata": {},
"source": [
"Test on test set using Pytorch tutorial method for both total and per class (maybe spot overfitting as well)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "bc158602",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Test Accuracy: 82.71%\n"
]
}
],
"source": [
"correct = 0\n",
"total = 0\n",
"\n",
"with torch.no_grad():\n",
" for data in test_loader:\n",
" images, labels = data\n",
" images, labels = images.to(device), labels.to(device)\n",
" outputs = model(images)\n",
" _, predicted = torch.max(outputs, 1)\n",
" total += labels.size(0)\n",
" correct += (predicted == labels).sum().item()\n",
"\n",
"print(f'Test Accuracy: {100 * correct / total:.2f}%')"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "8cc7ed40",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Accuracy for class: Bicycle is 68.8%\n",
"Accuracy for class: Bus is 83.2%\n",
"Accuracy for class: Car is 78.8%\n",
"Accuracy for class: Motorcycle is 90.5%\n",
"Accuracy for class: NonVehicles is 99.7%\n",
"Accuracy for class: Taxi is 49.4%\n",
"Accuracy for class: Truck is 59.2%\n",
"Accuracy for class: Van is 40.1%\n"
]
}
],
"source": [
"correct_pred = {classname: 0 for classname in dataset.classes}\n",
"total_pred = {classname: 0 for classname in dataset.classes}\n",
"\n",
"with torch.no_grad():\n",
" for data in test_loader:\n",
" images, labels = data\n",
" images, labels = images.to(device), labels.to(device)\n",
" outputs = model(images)\n",
" _, predictions = torch.max(outputs, 1)\n",
" for label, prediction in zip(labels, predictions):\n",
" if label == prediction:\n",
" correct_pred[dataset.classes[label]] += 1\n",
" total_pred[dataset.classes[label]] += 1\n",
"\n",
"for classname, correct_count in correct_pred.items():\n",
" accuracy = 100 * float(correct_count) / total_pred[classname]\n",
" print(f'Accuracy for class: {classname:10s} is {accuracy:.1f}%')"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.15"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
+690
View File
@@ -0,0 +1,690 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "7a37220a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello, World!\n"
]
}
],
"source": [
"print(\"Hello, World!\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "d318d1f0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Van: 1111 images\n",
"Taxi: 748 images\n",
"Bicycle: 1618 images\n",
"Bus: 2133 images\n",
"Car: 6781 images\n",
"Motorcycle: 2986 images\n",
"Truck: 2033 images\n",
"NonVehicles: 8968 images\n"
]
}
],
"source": [
"import os\n",
"\n",
"data_dir = '../data/raw/vehicle_classification'\n",
"\n",
"for class_name in os.listdir(data_dir):\n",
" class_path = os.path.join(data_dir, class_name)\n",
" if os.path.isdir(class_path):\n",
" count = len(os.listdir(class_path))\n",
" print(f\"{class_name}: {count} images\")"
]
},
{
"cell_type": "markdown",
"id": "64122ad4",
"metadata": {},
"source": [
"Check out sample image from dataset"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "5604ace3",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Size: (64, 64)\n",
"Mode: RGB\n"
]
},
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from PIL import Image\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# first image in first folder\n",
"first_class = os.listdir(data_dir)[0]\n",
"first_image_path = os.path.join(data_dir, first_class, os.listdir(os.path.join(data_dir, first_class))[0])\n",
"\n",
"img = Image.open(first_image_path)\n",
"print(f\"Size: {img.size}\")\n",
"print(f\"Mode: {img.mode}\")\n",
"plt.imshow(img)\n",
"plt.title(first_class)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "c19ec00a",
"metadata": {},
"source": [
"Ensure that all images are RGB, all of same resolution"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "3cedd586",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Unique sizes: {(64, 64)}\n",
"Unique modes: {'RGB'}\n"
]
}
],
"source": [
"sizes = set()\n",
"modes = set()\n",
"\n",
"for class_name in os.listdir(data_dir):\n",
" class_path = os.path.join(data_dir, class_name)\n",
" if not os.path.isdir(class_path):\n",
" continue\n",
" for img_name in os.listdir(class_path):\n",
" img = Image.open(os.path.join(class_path, img_name))\n",
" sizes.add(img.size)\n",
" modes.add(img.mode)\n",
"\n",
"print(f\"Unique sizes: {sizes}\")\n",
"print(f\"Unique modes: {modes}\")"
]
},
{
"cell_type": "markdown",
"id": "88ac961b",
"metadata": {},
"source": [
"Ensure that torch works with GPU (5080) [Credit: Claude]"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "8f556b22",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"True\n",
"NVIDIA GeForce RTX 5080\n",
"GPU works! torch.Size([1000, 1000])\n"
]
}
],
"source": [
"import torch\n",
"print(torch.cuda.is_available()) \n",
"print(torch.cuda.get_device_name(0)) \n",
"\n",
"x = torch.randn(1000, 1000).cuda()\n",
"y = x @ x\n",
"print(\"GPU works!\", y.shape)"
]
},
{
"cell_type": "markdown",
"id": "870fadbe",
"metadata": {},
"source": [
"Transform image dataset into tensors. Normalized with 0.5 mean and 0.5 STD (can be differente to use pretrained weights)."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "37793c77",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['Bicycle', 'Bus', 'Car', 'Motorcycle', 'NonVehicles', 'Taxi', 'Truck', 'Van']\n",
"26378\n"
]
}
],
"source": [
"from torchvision import datasets, transforms\n",
"from torch.utils.data import random_split, DataLoader\n",
"\n",
"transform = transforms.Compose([\n",
" transforms.ToTensor(),\n",
" transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])\n",
"])\n",
"\n",
"dataset = datasets.ImageFolder(root=data_dir, transform=transform)\n",
"\n",
"print(dataset.classes) # should print 8 classes\n",
"print(len(dataset)) # total image count"
]
},
{
"cell_type": "markdown",
"id": "ac33bc21",
"metadata": {},
"source": [
"Split 80-20 and save into 2 variables....augments the test set by rotating and lighting it differently to add training nuance."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "f68c1a25",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Train: 21102, Test: 5276\n"
]
}
],
"source": [
"import math \n",
"\n",
"train_transform = transforms.Compose([\n",
" transforms.RandomHorizontalFlip(), # randomly mirror image\n",
" transforms.RandomRotation(20), # rotate up to 10 degrees\n",
" transforms.ColorJitter(brightness=0.3, contrast=0.3), # vary lighting\n",
" transforms.ToTensor(),\n",
" transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])\n",
"])\n",
"\n",
"test_transform = transforms.Compose([\n",
" transforms.ToTensor(),\n",
" transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])\n",
"])\n",
"\n",
"train_full = datasets.ImageFolder(root=data_dir, transform=train_transform)\n",
"test_full = datasets.ImageFolder(root=data_dir, transform=test_transform)\n",
"\n",
"train_size = math.floor(len(train_full) * 0.8)\n",
"test_size = len(train_full) - train_size\n",
"\n",
"# Use same indices for both so split is consistent\n",
"indices = torch.randperm(len(train_full)).tolist()\n",
"train_indices = indices[:train_size]\n",
"test_indices = indices[train_size:]\n",
"\n",
"train_dataset = torch.utils.data.Subset(train_full, train_indices)\n",
"test_dataset = torch.utils.data.Subset(test_full, test_indices)\n",
"\n",
"print(f\"Train: {len(train_dataset)}, Test: {len(test_dataset)}\")"
]
},
{
"cell_type": "markdown",
"id": "2eede814",
"metadata": {},
"source": [
"Load the data into batches for faster loading...use 4 threads on CPU\n",
"\n",
"Shuffling train dataset so as to not overfit on one class"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "e1539eaa",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['Bicycle', 'Bus', 'Car', 'Motorcycle', 'NonVehicles', 'Taxi', 'Truck', 'Van']\n",
"8\n"
]
}
],
"source": [
"train_loader = DataLoader(train_dataset, batch_size=256, shuffle=True, num_workers=16)\n",
"test_loader = DataLoader(test_dataset, batch_size=256, shuffle=False, num_workers=16)\n",
"\n",
"classes = train_full.classes \n",
"print(classes)\n",
"print(len(classes))"
]
},
{
"cell_type": "markdown",
"id": "acebe98e",
"metadata": {},
"source": [
"MOdified tutorial arch to handle BathhNorm and Dropout (to try to prevent overfitting)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "d1b7d9ca",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Net(\n",
" (features): Sequential(\n",
" (0): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
" (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
" (2): ReLU()\n",
" (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
" (4): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
" (5): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
" (6): ReLU()\n",
" (7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
" (8): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
" (9): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
" (10): ReLU()\n",
" (11): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
" )\n",
" (classifier): Sequential(\n",
" (0): Flatten(start_dim=1, end_dim=-1)\n",
" (1): Linear(in_features=8192, out_features=512, bias=True)\n",
" (2): ReLU()\n",
" (3): Dropout(p=0.5, inplace=False)\n",
" (4): Linear(in_features=512, out_features=8, bias=True)\n",
" )\n",
")\n"
]
}
],
"source": [
"import torch\n",
"import torch.nn as nn\n",
"import torch.nn.functional as F\n",
"\n",
"class Net(nn.Module):\n",
" def __init__(self):\n",
" super(Net, self).__init__()\n",
"\n",
" self.features = nn.Sequential(\n",
" # go from 64x64 to 32x32\n",
"\n",
" # kernel size = 3x3 filter patch\n",
" #padding = 1, so 64x64 stays 64x64 after conv\n",
" nn.Conv2d(3, 32, kernel_size=3, padding=1), # 3 channel RRGB, 32 filters (recommended)\n",
"\n",
" nn.BatchNorm2d(32), # mirrors conv2d output\n",
" nn.ReLU(),\n",
" nn.MaxPool2d(2,2), # 2x2 window so halved --> 32x32\n",
"\n",
" #Go from 32x32 --> 16x16\n",
"\n",
" nn.Conv2d(32, 64, kernel_size=3, padding=1),\n",
" nn.BatchNorm2d(64),\n",
" nn.ReLU(),\n",
" nn.MaxPool2d(2,2), \n",
" \n",
" # Go from 16x 16 0 --> 8x8\n",
"\n",
" nn.Conv2d(64, 128, kernel_size=3, padding=1),\n",
" nn.BatchNorm2d(128),\n",
" nn.ReLU(),\n",
" nn.MaxPool2d(2,2), \n",
"\n",
" )\n",
"\n",
" self.classifier = nn.Sequential(\n",
" nn.Flatten(),\n",
" nn.Linear (128 * 8 *8, 512), # flattened size of 8x8 * 128, 512 is arbitrary output (recommended by sources)\n",
" nn.ReLU(),\n",
" nn.Dropout(0.5),#Randomly zero 50% of neurons --> prevent moeoorization\n",
" nn.Linear(512, len(classes)) # one score per vehicle class\n",
" )\n",
"\n",
" def forward(self, x):\n",
" x = self.features(x)\n",
" x = self.classifier(x)\n",
" return x\n",
"\n",
"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
"model = Net().to(device)\n",
"print(model)"
]
},
{
"cell_type": "markdown",
"id": "22e71032",
"metadata": {},
"source": [
"Loss fn and optimizer"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "54d11a04",
"metadata": {},
"outputs": [],
"source": [
"import torch.optim as optim\n",
"\n",
"criterion = nn.CrossEntropyLoss() # Applied softmax to convert scores --> probabilities --> penalizes model \n",
"\n",
"# Changed to adam optimizer (internal momentumn calculation)\n",
"optimizer = optim.Adam(model.parameters(), lr=0.001)"
]
},
{
"cell_type": "markdown",
"id": "572d80e3",
"metadata": {},
"source": [
"Tutorial training cell adapted to use 30 epochs "
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "374d0590",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1: Loss=1.508, Accuracy=57.21%\n",
"Epoch 2: Loss=0.984, Accuracy=65.81%\n",
"Epoch 3: Loss=0.867, Accuracy=69.43%\n",
"Epoch 4: Loss=0.787, Accuracy=72.45%\n",
"Epoch 5: Loss=0.737, Accuracy=74.33%\n",
"Epoch 6: Loss=0.719, Accuracy=74.72%\n",
"Epoch 7: Loss=0.678, Accuracy=76.07%\n",
"Epoch 8: Loss=0.666, Accuracy=76.84%\n",
"Epoch 9: Loss=0.641, Accuracy=77.40%\n",
"Epoch 10: Loss=0.622, Accuracy=78.10%\n",
"Epoch 11: Loss=0.617, Accuracy=78.24%\n",
"Epoch 12: Loss=0.611, Accuracy=78.47%\n",
"Epoch 13: Loss=0.596, Accuracy=78.80%\n",
"Epoch 14: Loss=0.589, Accuracy=78.99%\n",
"Epoch 15: Loss=0.579, Accuracy=79.79%\n",
"Epoch 16: Loss=0.572, Accuracy=79.73%\n",
"Epoch 17: Loss=0.555, Accuracy=80.47%\n",
"Epoch 18: Loss=0.556, Accuracy=80.27%\n",
"Epoch 19: Loss=0.542, Accuracy=81.20%\n",
"Epoch 20: Loss=0.522, Accuracy=81.49%\n",
"Epoch 21: Loss=0.529, Accuracy=81.22%\n",
"Epoch 22: Loss=0.513, Accuracy=81.88%\n",
"Epoch 23: Loss=0.513, Accuracy=81.66%\n",
"Epoch 24: Loss=0.511, Accuracy=81.77%\n",
"Epoch 25: Loss=0.509, Accuracy=82.22%\n",
"Epoch 26: Loss=0.493, Accuracy=82.67%\n",
"Epoch 27: Loss=0.496, Accuracy=82.43%\n",
"Epoch 28: Loss=0.483, Accuracy=83.06%\n",
"Epoch 29: Loss=0.470, Accuracy=83.32%\n",
"Epoch 30: Loss=0.473, Accuracy=83.12%\n",
"Epoch 31: Loss=0.469, Accuracy=83.45%\n",
"Epoch 32: Loss=0.464, Accuracy=83.21%\n",
"Epoch 33: Loss=0.449, Accuracy=84.09%\n",
"Epoch 34: Loss=0.457, Accuracy=83.44%\n",
"Epoch 35: Loss=0.442, Accuracy=84.20%\n",
"Epoch 36: Loss=0.441, Accuracy=84.18%\n",
"Epoch 37: Loss=0.442, Accuracy=84.15%\n",
"Epoch 38: Loss=0.434, Accuracy=84.47%\n",
"Epoch 39: Loss=0.434, Accuracy=84.32%\n",
"Epoch 40: Loss=0.430, Accuracy=84.64%\n",
"Epoch 41: Loss=0.413, Accuracy=85.00%\n",
"Epoch 42: Loss=0.412, Accuracy=84.85%\n",
"Epoch 43: Loss=0.408, Accuracy=85.42%\n",
"Epoch 44: Loss=0.406, Accuracy=85.49%\n",
"Epoch 45: Loss=0.420, Accuracy=84.76%\n",
"Epoch 46: Loss=0.399, Accuracy=85.53%\n",
"Epoch 47: Loss=0.392, Accuracy=85.81%\n",
"Epoch 48: Loss=0.395, Accuracy=85.66%\n",
"Epoch 49: Loss=0.400, Accuracy=85.58%\n",
"Epoch 50: Loss=0.376, Accuracy=86.29%\n",
"Epoch 51: Loss=0.381, Accuracy=86.35%\n",
"Epoch 52: Loss=0.383, Accuracy=86.17%\n",
"Epoch 53: Loss=0.375, Accuracy=86.05%\n",
"Epoch 54: Loss=0.372, Accuracy=86.46%\n",
"Epoch 55: Loss=0.370, Accuracy=86.57%\n",
"Epoch 56: Loss=0.372, Accuracy=86.41%\n",
"Epoch 57: Loss=0.363, Accuracy=86.85%\n",
"Epoch 58: Loss=0.375, Accuracy=86.39%\n",
"Epoch 59: Loss=0.360, Accuracy=86.89%\n",
"Epoch 60: Loss=0.353, Accuracy=86.97%\n",
"Epoch 61: Loss=0.348, Accuracy=87.36%\n",
"Epoch 62: Loss=0.346, Accuracy=87.09%\n",
"Epoch 63: Loss=0.347, Accuracy=87.38%\n",
"Epoch 64: Loss=0.343, Accuracy=87.38%\n",
"Epoch 65: Loss=0.343, Accuracy=87.31%\n",
"Epoch 66: Loss=0.335, Accuracy=87.90%\n",
"Epoch 67: Loss=0.330, Accuracy=87.83%\n",
"Epoch 68: Loss=0.325, Accuracy=88.06%\n",
"Epoch 69: Loss=0.322, Accuracy=88.07%\n",
"Epoch 70: Loss=0.323, Accuracy=88.27%\n",
"Epoch 71: Loss=0.326, Accuracy=87.77%\n",
"Epoch 72: Loss=0.313, Accuracy=88.58%\n",
"Epoch 73: Loss=0.322, Accuracy=88.25%\n",
"Epoch 74: Loss=0.317, Accuracy=88.43%\n",
"Epoch 75: Loss=0.311, Accuracy=88.54%\n",
"Epoch 76: Loss=0.303, Accuracy=88.57%\n",
"Epoch 77: Loss=0.305, Accuracy=88.83%\n",
"Epoch 78: Loss=0.303, Accuracy=88.87%\n",
"Epoch 79: Loss=0.303, Accuracy=88.74%\n",
"Epoch 80: Loss=0.296, Accuracy=89.00%\n",
"Epoch 81: Loss=0.291, Accuracy=89.44%\n",
"Epoch 82: Loss=0.291, Accuracy=89.43%\n",
"Epoch 83: Loss=0.287, Accuracy=89.10%\n",
"Epoch 84: Loss=0.290, Accuracy=89.05%\n",
"Epoch 85: Loss=0.291, Accuracy=89.09%\n",
"Epoch 86: Loss=0.284, Accuracy=89.34%\n",
"Epoch 87: Loss=0.282, Accuracy=89.40%\n",
"Epoch 88: Loss=0.283, Accuracy=89.40%\n",
"Epoch 89: Loss=0.283, Accuracy=89.61%\n",
"Epoch 90: Loss=0.272, Accuracy=89.71%\n",
"Epoch 91: Loss=0.272, Accuracy=89.84%\n",
"Epoch 92: Loss=0.276, Accuracy=89.68%\n",
"Epoch 93: Loss=0.276, Accuracy=89.78%\n",
"Epoch 94: Loss=0.262, Accuracy=90.11%\n",
"Epoch 95: Loss=0.271, Accuracy=89.81%\n",
"Epoch 96: Loss=0.267, Accuracy=89.95%\n",
"Epoch 97: Loss=0.262, Accuracy=90.14%\n",
"Epoch 98: Loss=0.259, Accuracy=90.25%\n",
"Epoch 99: Loss=0.266, Accuracy=89.97%\n",
"Epoch 100: Loss=0.255, Accuracy=90.47%\n",
"Finished Training\n"
]
}
],
"source": [
"for epoch in range(100): # 10 --> 30 epochs\n",
" running_loss = 0.0\n",
" correct = 0\n",
" total = 0\n",
"\n",
" for i, data in enumerate(train_loader, 0):\n",
" inputs, labels = data\n",
" inputs, labels = inputs.to(device), labels.to(device) # use GPU\n",
"\n",
" optimizer.zero_grad()\n",
"\n",
" outputs = model(inputs)\n",
" loss = criterion(outputs, labels)\n",
" loss.backward()\n",
" optimizer.step()\n",
"\n",
" # loss tracking\n",
" running_loss += loss.item()\n",
"\n",
" # accuracy tracking\n",
" _, predicted = torch.max(outputs, 1)\n",
" total += labels.size(0)\n",
" correct += (predicted == labels).sum().item()\n",
"\n",
" accuracy = 100 * correct / total\n",
" print(f'Epoch {epoch + 1}: Loss={running_loss / len(train_loader):.3f}, Accuracy={accuracy:.2f}%') # Credit: Claude for printing accuracy in good formatting\n",
"\n",
"print('Finished Training')"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "2bf2b9a2",
"metadata": {},
"outputs": [],
"source": [
"PATH = '../models/deeper-training.pth'\n",
"torch.save(model.state_dict(), PATH)"
]
},
{
"cell_type": "markdown",
"id": "a24dd4f0",
"metadata": {},
"source": [
"Test on test set using Pytorch tutorial method for both total and per class (maybe spot overfitting as well)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "bc158602",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Test Accuracy: 84.27%\n"
]
}
],
"source": [
"correct = 0\n",
"total = 0\n",
"\n",
"with torch.no_grad():\n",
" for data in test_loader:\n",
" images, labels = data\n",
" images, labels = images.to(device), labels.to(device)\n",
" outputs = model(images)\n",
" _, predicted = torch.max(outputs, 1)\n",
" total += labels.size(0)\n",
" correct += (predicted == labels).sum().item()\n",
"\n",
"print(f'Test Accuracy: {100 * correct / total:.2f}%')"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "8cc7ed40",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Accuracy for class: Bicycle is 76.8%\n",
"Accuracy for class: Bus is 83.2%\n",
"Accuracy for class: Car is 84.8%\n",
"Accuracy for class: Motorcycle is 84.7%\n",
"Accuracy for class: NonVehicles is 98.7%\n",
"Accuracy for class: Taxi is 45.9%\n",
"Accuracy for class: Truck is 53.8%\n",
"Accuracy for class: Van is 56.9%\n"
]
}
],
"source": [
"correct_pred = {classname: 0 for classname in dataset.classes}\n",
"total_pred = {classname: 0 for classname in dataset.classes}\n",
"\n",
"with torch.no_grad():\n",
" for data in test_loader:\n",
" images, labels = data\n",
" images, labels = images.to(device), labels.to(device)\n",
" outputs = model(images)\n",
" _, predictions = torch.max(outputs, 1)\n",
" for label, prediction in zip(labels, predictions):\n",
" if label == prediction:\n",
" correct_pred[dataset.classes[label]] += 1\n",
" total_pred[dataset.classes[label]] += 1\n",
"\n",
"for classname, correct_count in correct_pred.items():\n",
" accuracy = 100 * float(correct_count) / total_pred[classname]\n",
" print(f'Accuracy for class: {classname:10s} is {accuracy:.1f}%')"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.15"
}
},
"nbformat": 4,
"nbformat_minor": 5
}