Spaces:
Runtime error
Runtime error
Commit
·
aaa317a
1
Parent(s):
2855b15
updating network architecture
Browse files- MNISTModel_97.pth +3 -0
- MNISTModel_98.pth +3 -0
- app.py +5 -5
- neural_network.py +36 -33
- train_model.py +86 -0
MNISTModel_97.pth
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e8f6e5ce379e6857ca016fdc51f17e2b87926295a02e9f980bd214bd7a82e320
|
| 3 |
+
size 1745671
|
MNISTModel_98.pth
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:097d546bb4f0432bd9310f9228edb7d7304b6ecde70b2de66ae9a76ae9ecd034
|
| 3 |
+
size 1690063
|
app.py
CHANGED
|
@@ -6,20 +6,20 @@ from neural_network import MNISTNetwork
|
|
| 6 |
|
| 7 |
transform = transforms.Compose([
|
| 8 |
transforms.ToTensor(), # Convert image to tensor
|
| 9 |
-
transforms.Normalize((0.
|
| 10 |
])
|
| 11 |
|
| 12 |
# Load the trained model
|
| 13 |
-
net =
|
| 14 |
-
net.load_state_dict(torch.load('mnist_net.pth'))
|
| 15 |
LABELS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
|
| 16 |
|
| 17 |
def predict(drawing):
|
| 18 |
if drawing is None:
|
| 19 |
-
return "Draw
|
| 20 |
|
| 21 |
input_tensor = transform(drawing)
|
| 22 |
-
x = input_tensor
|
|
|
|
| 23 |
|
| 24 |
with torch.no_grad():
|
| 25 |
output = net(x)
|
|
|
|
| 6 |
|
| 7 |
transform = transforms.Compose([
|
| 8 |
transforms.ToTensor(), # Convert image to tensor
|
| 9 |
+
transforms.Normalize((0.5,), (0.5,)) # Normalize the image
|
| 10 |
])
|
| 11 |
|
| 12 |
# Load the trained model
|
| 13 |
+
net = torch.load('MNISTModel_98.pth')
|
|
|
|
| 14 |
LABELS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
|
| 15 |
|
| 16 |
def predict(drawing):
|
| 17 |
if drawing is None:
|
| 18 |
+
return "Draw a number hoe"
|
| 19 |
|
| 20 |
input_tensor = transform(drawing)
|
| 21 |
+
x = input_tensor
|
| 22 |
+
# x = input_tensor.view(input_tensor.shape[0], -1)
|
| 23 |
|
| 24 |
with torch.no_grad():
|
| 25 |
output = net(x)
|
neural_network.py
CHANGED
|
@@ -1,39 +1,42 @@
|
|
| 1 |
-
import torch
|
| 2 |
-
import torch.nn
|
|
|
|
| 3 |
|
| 4 |
-
class MNISTNetwork(nn.Module):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
|
| 6 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
super().__init__()
|
| 8 |
-
self.
|
| 9 |
-
self.
|
| 10 |
-
self.
|
| 11 |
-
self.
|
| 12 |
-
|
| 13 |
def forward(self, x):
|
| 14 |
-
x = F.relu(self.
|
| 15 |
-
x = F.
|
| 16 |
-
x = F.relu(self.
|
| 17 |
-
x =
|
|
|
|
|
|
|
|
|
|
| 18 |
return F.log_softmax(x, dim=1)
|
| 19 |
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
# class MNISTNetwork(nn.Module):
|
| 23 |
-
# def __init__(self):
|
| 24 |
-
# super().__init__()
|
| 25 |
-
# self.conv1 = nn.Conv2d(1, 32, kernel_size=5, padding=2)
|
| 26 |
-
# self.conv2 = nn.Conv2d(32, 64, kernel_size=5, padding=2)
|
| 27 |
-
# self.fc1 = nn.Linear(64*7*7, 1024)
|
| 28 |
-
# self.fc2 = nn.Linear(1024, 10)
|
| 29 |
-
|
| 30 |
-
# def forward(self, x):
|
| 31 |
-
# x = nn.functional.relu(self.conv1(x))
|
| 32 |
-
# x = nn.functional.max_pool2d(x, 2)
|
| 33 |
-
# x = nn.functional.relu(self.conv2(x))
|
| 34 |
-
# x = nn.functional.max_pool2d(x, 2)
|
| 35 |
-
# x = x.view(-1, 64*7*7)
|
| 36 |
-
# x = nn.functional.relu(self.fc1(x))
|
| 37 |
-
# x = nn.functional.dropout(x, training=self.training)
|
| 38 |
-
# x = self.fc2(x)
|
| 39 |
-
# return nn.functional.log_softmax(x, dim=1)
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
import torch.nn as nn
|
| 3 |
+
import torch.nn.functional as F
|
| 4 |
|
| 5 |
+
# class MNISTNetwork(nn.Module):
|
| 6 |
+
# # achieved 97 percent accuracy
|
| 7 |
+
# def __init__(self):
|
| 8 |
+
# super().__init__()
|
| 9 |
+
# self.layer1 = nn.Linear(784, 400)
|
| 10 |
+
# self.layer2 = nn.Linear(400, 256)
|
| 11 |
+
# self.layer3 = nn.Linear(256, 64)
|
| 12 |
+
# self.layer4 = nn.Linear(64, 32)
|
| 13 |
+
# self.layer5 = nn.Linear(32, 10)
|
| 14 |
|
| 15 |
+
# def forward(self, x):
|
| 16 |
+
# x = x.view(-1, 28*28)
|
| 17 |
+
# x = torch.relu(self.layer1(x))
|
| 18 |
+
# x = torch.relu(self.layer2(x))
|
| 19 |
+
# x = torch.relu(self.layer3(x))
|
| 20 |
+
# x = torch.relu(self.layer4(x))
|
| 21 |
+
# x = torch.relu(self.layer5(x))
|
| 22 |
+
# return F.log_softmax(x, dim=1)
|
| 23 |
+
|
| 24 |
+
class MNISTNetwork(nn.Module):
|
| 25 |
+
# achieved 98.76 percent accuracy
|
| 26 |
+
def __init__(self):
|
| 27 |
super().__init__()
|
| 28 |
+
self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)
|
| 29 |
+
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
|
| 30 |
+
self.fc1 = nn.Linear(64*7*7, 128)
|
| 31 |
+
self.fc2 = nn.Linear(128, 10)
|
| 32 |
+
|
| 33 |
def forward(self, x):
|
| 34 |
+
x = F.relu(self.conv1(x))
|
| 35 |
+
x = F.max_pool2d(x, 2)
|
| 36 |
+
x = F.relu(self.conv2(x))
|
| 37 |
+
x = F.max_pool2d(x, 2)
|
| 38 |
+
x = x.view(-1, 64*7*7)
|
| 39 |
+
x = F.relu(self.fc1(x))
|
| 40 |
+
x = self.fc2(x)
|
| 41 |
return F.log_softmax(x, dim=1)
|
| 42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
train_model.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
import torchvision
|
| 3 |
+
import multiprocessing, prettytable
|
| 4 |
+
import torchvision.transforms as transforms
|
| 5 |
+
from neural_network import MNISTNetwork
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
# hyperparameters
|
| 9 |
+
BATCH_SIZE = 64
|
| 10 |
+
NUM_WORKERS = 2
|
| 11 |
+
EPOCH = 12
|
| 12 |
+
LEARNING_RATE = 0.01
|
| 13 |
+
MOMENTUM = 0.5
|
| 14 |
+
LOSS = torch.nn.CrossEntropyLoss()
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
## Step 1: define our transforms
|
| 18 |
+
transform = transforms.Compose(
|
| 19 |
+
[
|
| 20 |
+
transforms.ToTensor(),
|
| 21 |
+
transforms.Normalize((0.5), (0.5))
|
| 22 |
+
]
|
| 23 |
+
)
|
| 24 |
+
|
| 25 |
+
## Step 2: get our datasets
|
| 26 |
+
full_ds = torchvision.datasets.MNIST(root='./data', train=True, download=False, transform=transform)
|
| 27 |
+
train_ds, valid_ds = torch.utils.data.random_split(full_ds, [50000, 10000])
|
| 28 |
+
test_ds = torchvision.datasets.MNIST(root='./data', train=False, download=False, transform=transform)
|
| 29 |
+
|
| 30 |
+
## Step 3: create our dataloaders
|
| 31 |
+
train_dl = torch.utils.data.DataLoader(train_ds, num_workers=NUM_WORKERS, shuffle=True, batch_size=BATCH_SIZE)
|
| 32 |
+
valid_dl = torch.utils.data.DataLoader(valid_ds, num_workers=NUM_WORKERS, shuffle=False, batch_size=BATCH_SIZE)
|
| 33 |
+
test_dl = torch.utils.data.DataLoader(test_ds, num_workers=NUM_WORKERS, shuffle=False, batch_size=BATCH_SIZE)
|
| 34 |
+
|
| 35 |
+
## Step 4: define our model and optimizer
|
| 36 |
+
model = MNISTNetwork()
|
| 37 |
+
criteron = LOSS # define our loss function
|
| 38 |
+
optimizer = torch.optim.SGD(model.parameters(), lr=LEARNING_RATE, momentum=MOMENTUM)
|
| 39 |
+
|
| 40 |
+
## define our table
|
| 41 |
+
table = prettytable.PrettyTable()
|
| 42 |
+
table.field_names = ['Epoch', 'Training Loss', 'Validation Accuracy']
|
| 43 |
+
|
| 44 |
+
if __name__ == "__main__":
|
| 45 |
+
multiprocessing.freeze_support()
|
| 46 |
+
## begin training process
|
| 47 |
+
for e in range(EPOCH):
|
| 48 |
+
model.train()
|
| 49 |
+
running_loss = 0.0
|
| 50 |
+
for inputs, labels in train_dl:
|
| 51 |
+
optimizer.zero_grad()
|
| 52 |
+
outputs = model(inputs)
|
| 53 |
+
loss = criteron(outputs, labels)
|
| 54 |
+
loss.backward()
|
| 55 |
+
optimizer.step()
|
| 56 |
+
running_loss += loss.item()
|
| 57 |
+
train_loss = round(running_loss/len(train_dl), 4)
|
| 58 |
+
|
| 59 |
+
# evaluate on the test set
|
| 60 |
+
model.eval()
|
| 61 |
+
with torch.no_grad():
|
| 62 |
+
total, correct = 0, 0
|
| 63 |
+
for inputs, labels in valid_dl:
|
| 64 |
+
outputs = model(inputs)
|
| 65 |
+
_, predicted = torch.max(outputs.data, 1)
|
| 66 |
+
total += labels.size(0)
|
| 67 |
+
correct += (predicted == labels).sum().item()
|
| 68 |
+
val_acc = round((correct/total)*100, 3)
|
| 69 |
+
table.add_row([e, train_loss, val_acc])
|
| 70 |
+
print(f'Training Loss: {train_loss}, Validation Accuracy: {val_acc}')
|
| 71 |
+
|
| 72 |
+
print(table)
|
| 73 |
+
# evaluate on test set
|
| 74 |
+
model.eval()
|
| 75 |
+
with torch.no_grad():
|
| 76 |
+
total, correct = 0, 0
|
| 77 |
+
for inputs, labels in test_dl:
|
| 78 |
+
outputs = model(inputs)
|
| 79 |
+
_, predicted = torch.max(outputs.data, 1)
|
| 80 |
+
total += labels.size(0)
|
| 81 |
+
correct += (predicted == labels).sum().item()
|
| 82 |
+
test_acc = round((correct/total)*100, 3)
|
| 83 |
+
|
| 84 |
+
print(f'Test Accuracy: {test_acc}')
|
| 85 |
+
torch.save(model, 'MNISTModel.pth')
|
| 86 |
+
|