Skip to content

Commit 7d0909b

Browse files
committed
Enable GPU device selection. Update trainer.
1 parent 349cec1 commit 7d0909b

2 files changed

Lines changed: 18 additions & 7 deletions

File tree

main.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
parser = argparse.ArgumentParser()
1212

1313
# MNIST or CIFAR?
14-
parser.add_argument('dataset', nargs='?', type=str, default='MNIST', help="'MNIST' or 'CIFAR'")
14+
parser.add_argument('dataset', nargs='?', type=str, default='MNIST', help="'MNIST' or 'CIFAR' (case insensitive).")
1515
# Batch size
1616
parser.add_argument('-bs', '--batch_size', type=int, default=128, help='Batch size.')
1717
# Epochs
@@ -24,10 +24,15 @@
2424
parser.add_argument('--lr_decay', type=float, default=0.96, help='Exponential learning rate decay.')
2525
# Use multiple GPUs?
2626
parser.add_argument('--multi_gpu', action='store_true', help='Flag whether to use multiple GPUs.')
27+
# Select GPU device
28+
parser.add_argument('--gpu_device', type=int, default=None, help='ID of a GPU to use when multiple GPUs are available.')
2729
# Data directory
28-
parser.add_argument('--data_path', type=str, default=DATA_PATH, help='Flag whether to use multiple GPUs.')
30+
parser.add_argument('--data_path', type=str, default=DATA_PATH, help='Path to the MNIST or CIFAR dataset. Alternatively you can set the path as an environmental variable $data.')
2931
args = parser.parse_args()
3032

33+
if args.gpu_device is not None:
34+
torch.cuda.set_device(args.gpu_device)
35+
3136
if args.multi_gpu:
3237
args.batch_size *= torch.cuda.device_count()
3338

trainer.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import torch.optim as optim
88
from torch.autograd import Variable
99
import os
10+
from numpy import prod
1011
from datetime import datetime
1112
from model import CapsuleNetwork
1213
from loss import CapsuleLoss
@@ -39,12 +40,17 @@ def __init__(self, loaders, batch_size, learning_rate, num_routing=3, lr_decay=0
3940
self.optimizer = optim.Adam(self.net.parameters(), lr=learning_rate)
4041
self.scheduler = optim.lr_scheduler.ExponentialLR(self.optimizer, gamma=lr_decay)
4142
print(8*'#', 'PyTorch Model built'.upper(), 8*'#')
43+
print('Num params:', sum([prod(p.size()) for p in self.net.parameters()]))
4244

4345
def __repr__(self):
4446
return repr(self.net)
4547

4648
def run(self, epochs, classes):
4749
print(8*'#', 'Run started'.upper(), 8*'#')
50+
eye = torch.eye(len(classes))
51+
if self.use_gpu:
52+
eye = eye.cuda()
53+
4854
for epoch in range(1, epochs+1):
4955
for phase in ['train', 'test']:
5056
print(f'{phase}ing...'.capitalize())
@@ -58,10 +64,10 @@ def run(self, epochs, classes):
5864
correct = 0; total = 0
5965
for i, (images, labels) in enumerate(self.loaders[phase]):
6066
t1 = time()
61-
# One-hot encode labels
62-
labels = torch.eye(len(classes))[labels]
6367
if self.use_gpu:
6468
images, labels = images.cuda(), labels.cuda()
69+
# One-hot encode labels
70+
labels = eye[labels]
6571

6672
images, labels = Variable(images), Variable(labels)
6773

@@ -95,8 +101,8 @@ def run(self, epochs, classes):
95101
error_rate = round((1-accuracy)*100, 2)
96102
torch.save(self.net, os.path.join(SAVE_MODEL_PATH, f'{error_rate}_{now}.pth.tar'))
97103

98-
class_correct = list(0. for i in range(10))
99-
class_total = list(0. for i in range(10))
104+
class_correct = list(0. for _ in classes)
105+
class_total = list(0. for _ in classes)
100106
for images, labels in self.loaders['test']:
101107
if self.use_gpu:
102108
images, labels = images.cuda(), labels.cuda()
@@ -110,6 +116,6 @@ def run(self, epochs, classes):
110116
class_total[label] += 1
111117

112118

113-
for i in range(10):
119+
for i in range(len(classes)):
114120
print('Accuracy of %5s : %2d %%' % (
115121
classes[i], 100 * class_correct[i] / class_total[i]))

0 commit comments

Comments
 (0)