-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmain.py
146 lines (112 loc) · 3.97 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# ================================================================ #
# LSTM Neural Networks #
# ================================================================ #
import torch
import torch.nn as nn
import torchvision.datasets
import torchvision.transforms as transforms
# Hyper parameters
import tqdm
batch_size = 100
num_epochs = 10
learning_rate = 0.1
input_dim = 28
hidden_dim = 100
sequence_dim = 28
layer_dim = 1
output_dim = 10
# Device Configuration
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# ================================================================ #
# Data Loading Process #
# ================================================================ #
# Dataset
train_dataset = torchvision.datasets.MNIST(
root='./data',
train=True,
transform=transforms.ToTensor(),
download=True
)
test_dataset = torchvision.datasets.MNIST(
root='./data',
train=False,
transform=transforms.ToTensor(),
download=True
)
# Data Loader
train_loader = torch.utils.data.DataLoader(
dataset=train_dataset,
batch_size=batch_size,
shuffle=True
)
test_loader = torch.utils.data.DataLoader(
dataset=test_dataset,
batch_size=batch_size,
shuffle=False
)
# ================================================================ #
# Create Model Class #
# ================================================================ #
class LSTMModel(nn.Module):
def __init__(self, input_dim, hidden_dim, layer_dim, output_dim):
super(LSTMModel, self).__init__()
# Hidden dimensions
self.hidden_dim = hidden_dim
# Number of hidden layers
self.layer_dim = layer_dim
self.lstm = nn.LSTM(input_dim, hidden_dim, layer_dim, batch_first=True)
# Readout layer
self.fc = nn.Linear(hidden_dim, output_dim)
def forward(self, x):
# Initialize hidden state with zeros
h0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).to(device)
# Initialize cell state
c0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).to(device)
out, (hn, cn) = self.lstm(x, (h0.detach(), c0.detach()))
out = self.fc(out[:, -1, :])
# out.size() --> 100, 10
return out
model = LSTMModel(input_dim, hidden_dim, layer_dim, output_dim).to(device)
# Loss function
loss_fn = nn.CrossEntropyLoss()
# Optimizer
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
# ================================================================ #
# Train and Test #
# ================================================================ #
# Train the model
iter = 0
print('TRAINING STARTED.\n')
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
images = images.view(-1, sequence_dim, input_dim).to(device)
labels = labels.to(device)
outputs = model(images)
loss = loss_fn(outputs, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
iter += 1
if iter % 500 == 0:
# Calculate Loss
print(f'Epoch: {epoch + 1}/{num_epochs}\t Iteration: {iter}\t Loss: {loss.item():.2f}')
# Test the model
model.eval()
print('\nCALCULATING ACCURACY...\n')
with torch.no_grad():
correct = 0
total = 0
progress = tqdm.tqdm(test_loader, total=len(test_loader))
# Iterate through test dataset
for images, labels in progress:
images = images.view(-1, sequence_dim, input_dim).to(device)
labels = labels.to(device)
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
# Total number of labels
total += labels.size(0)
# Total correct predictions
correct += (predicted == labels).sum().item()
accuracy = 100 * correct / total
# Print Accuracy
print(f'Accuracy: {accuracy}')