Browse Source

Experiment with cnn model

Simon Lousky 1 month ago
parent
commit
825c0c86af

BIN
code/__pycache__/my_torch_model.cpython-37.pyc

+ 9
- 3
code/eval.py

@@ -4,7 +4,8 @@ Evaluate model performance
 import pickle
 import json
 import numpy as np
-from sklearn.metrics import accuracy_score, precision_score, recall_score, roc_auc_score
+from sklearn.metrics import accuracy_score
+import torch
 
 
 def eval_model():
@@ -15,14 +16,19 @@ def eval_model():
     # Load trained model
     with open('./data/model.pkl', 'rb') as f:
         model = pickle.load(f)
+
+    # Switch model to evaluation (inference) mode
+    model.eval()
+
     print("done.")
+
     # Divide loaded data-set into data and labels
     labels = test_data[:, 0]
-    data = test_data[:, 1:]
+    data = torch.Tensor(test_data[:, 1:].reshape([test_data.shape[0], 1, 28, 28]))
 
     # Run model on test data
     print("Running model on test data...")
-    predictions = model.predict(data)
+    predictions = model(data).max(1, keepdim=True)[1].cpu().data.numpy()
     print("done.")
 
     # Calculate metric scores

+ 21
- 0
code/my_torch_model.py

@@ -0,0 +1,21 @@
+import torch.nn as nn
+import torch.nn.functional as F
+
+class Net(nn.Module):
+    def __init__(self):
+        super(Net, self).__init__()
+        self.conv1 = nn.Conv2d(1, 20, 5, 1)
+        self.conv2 = nn.Conv2d(20, 50, 5, 1)
+        self.fc1 = nn.Linear(4*4*50, 500)
+        self.fc2 = nn.Linear(500, 10)
+
+    def forward(self, x):
+        x = F.relu(self.conv1(x))
+        x = F.max_pool2d(x, 2, 2)
+        x = F.relu(self.conv2(x))
+        x = F.max_pool2d(x, 2, 2)
+        x = x.view(-1, 4*4*50)
+        x = F.relu(self.fc1(x))
+        x = self.fc2(x)
+        return F.log_softmax(x, dim=1)
+

+ 46
- 16
code/train_model.py

@@ -4,38 +4,68 @@ Train classification model for MNIST
 import json
 import pickle
 import numpy as np
-from sklearn.svm import SVC
-from sklearn.multiclass import OneVsRestClassifier
 import time
 
+# New imports
+import torch
+import torch.utils.data
+import torch.nn.functional as F
+import torch.optim as optim
+
+from my_torch_model import Net
+
+# New function
+def train(model, device, train_loader, optimizer, epoch):
+    log_interval = 100
+    model.train()
+    for batch_idx, (data, target) in enumerate(train_loader):
+        data, target = data.to(device), target.to(device)
+        optimizer.zero_grad()
+        output = model(data)
+        loss = F.nll_loss(output, target)
+        loss.backward()
+        optimizer.step()
+        if batch_idx % log_interval == 0:
+            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
+                epoch, batch_idx * len(data), len(train_loader.dataset),
+                100. * batch_idx / len(train_loader), loss.item()))
+
 
 def train_model():
     # Measure training time
     start_time = time.time()
 
+    # Setting up network
+    print("Setting up Params...")
+    device = torch.device("cpu")
+    batch_size = 64
+    epochs = 3
+    learning_rate = 0.01
+    momentum = 0.5
+    print("done.")
+
     # Load training data
     print("Load training data...")
     train_data = np.load('./data/processed_train_data.npy')
 
-    # Choose a random sample of images from the training data.
-    # This is important since SVM training time increases quadratically with the number of training samples.
-    print("Choosing smaller sample to shorten training time...")
-    # Set a random seed so that we get the same "random" choices when we try to recreate the experiment.
-    np.random.seed(42)
-
-    num_samples = 5000
-    choice = np.random.choice(train_data.shape[0], num_samples, replace=False)
-    train_data = train_data[choice, :]
-
     # Divide loaded data-set into data and labels
-    labels = train_data[:, 0]
-    data = train_data[:, 1:]
+    labels = torch.Tensor(train_data[:, 0]).long()
+    data = torch.Tensor(train_data[:, 1:].reshape([train_data.shape[0], 1, 28, 28]))
+    torch_train_data = torch.utils.data.TensorDataset(data, labels)
+    train_loader = torch.utils.data.DataLoader(torch_train_data,
+                                               batch_size=batch_size,
+                                               shuffle=True)
     print("done.")
 
     # Define SVM classifier and train model
     print("Training model...")
-    model = OneVsRestClassifier(SVC(kernel='linear'), n_jobs=6)
-    model.fit(data, labels)
+    model = Net().to(device)
+    optimizer = optim.SGD(model.parameters(),
+                          lr=learning_rate,
+                          momentum=momentum)
+
+    for epoch in range(1, epochs + 1):
+        train(model, device, train_loader, optimizer, epoch)
     print("done.")
 
     # Save model as pkl

+ 6
- 6
dvc.lock

@@ -18,23 +18,23 @@ training:
   cmd: python code/train_model.py
   deps:
   - path: code/train_model.py
-    md5: 655c3242c17b3d0213d7ce4d9f78344d
+    md5: 085905e5edd775a1f22020afd27c9db9
   - path: data/processed_train_data.npy
     md5: 9ee0468925c998fda26d197a14d1caec
   outs:
   - path: data/model.pkl
-    md5: d72417286b48ba89f02d83ca3f9642d4
+    md5: 9478080f0fbb832aaa6fc388104934c8
   - path: metrics/train_metric.json
-    md5: 27598e27b215ebb84ec027f92fc1b0ca
+    md5: fbdffebcb183d15c4a9da68a2b3bb3e3
 eval:
   cmd: python code/eval.py
   deps:
   - path: code/eval.py
-    md5: 75c6e9b5ffa5ab5bbf83b7c3e8de188d
+    md5: 589210c86a4900cbd77631bea4db031b
   - path: data/model.pkl
-    md5: d72417286b48ba89f02d83ca3f9642d4
+    md5: 9478080f0fbb832aaa6fc388104934c8
   - path: data/processed_test_data.npy
     md5: a5257a91e73920bdd4cafd0f88105b74
   outs:
   - path: metrics/eval.json
-    md5: 42e05a4d1c5f16b21c304c269178b5a8
+    md5: 6fbeac920d67c372cd638bd7af33095d

+ 1
- 1
metrics/eval.json

@@ -1 +1 @@
-{"accuracy": 0.8583}
+{"accuracy": 0.9861}

+ 1
- 1
metrics/train_metric.json

@@ -1 +1 @@
-{"training_time": 11.965423107147217}
+{"training_time": 119.05487275123596}

+ 2
- 1
requirements.txt

@@ -1,3 +1,4 @@
+future==0.18.2
 numpy==1.15.4
 pandas==0.23.4
 python-dateutil==2.7.5
@@ -6,4 +7,4 @@ scikit-learn==0.20.2
 scipy==1.2.0
 six==1.12.0
 sklearn==0.0
-
+torch==1.5.1