-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpsych_dual_mnist.py
184 lines (155 loc) · 6.72 KB
/
psych_dual_mnist.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# CS 394N Neural Networks
# Final Project
# Elizabeth Liner
# Based on https://github.com/yhuag/neural-network-lab/blob/master/Feedforward%20Neural%20Network.ipynb
import torch
import torch.nn as nn
from torch.autograd import Variable
import torchvision.datasets as dsets
import torchvision.transforms as transforms
import time
import csv
import numpy
import random
def getRandom(min, max):
return random.randint(min, max)
# Initialize variables
input_size = 784 # Image size = 28x28 = 784
hidden_size = 500 # Hidden nodes
num_classes = 10 # Output classes - 0-9
num_epochs = 10 # Number of times we train on the dataset
batch_size = 100 # Size of input data for a batch
correct_learning_rate = 0.075 # Speed of convergence
cor_lr_change = correct_learning_rate * 0 # Rate change
incorrect_learning_rate = 0.025 # Speed of convergence
incor_lr_change = incorrect_learning_rate * 0 # Rate change
# Download MNIST dataset
train_dataset = dsets.MNIST(root='./data',
train=True,
transform=transforms.ToTensor(),
download=True)
test_dataset = dsets.MNIST(root='./data',
train=False,
transform=transforms.ToTensor())
# Load datasets into batches
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)
test_epoch_acc_output = []
epoch_acc_output = []
cor_lr_output = []
incor_lr_output = []
# Feedforward Neural Network Model
class FFNN(nn.Module):
def __init__(self, input_size, hidden_size, num_classes):
super(FFNN, self).__init__()
self.fc1 = nn.Linear(input_size, hidden_size)
self.relu = nn.ReLU()
self.fc2 = nn.Linear(hidden_size, num_classes)
def forward(self, x):
out = self.fc1(x)
out = self.relu(out)
out = self.fc2(out)
return out
# Create model
model = FFNN(input_size, hidden_size, num_classes)
# Loss Function and Optimizer
criterion = nn.CrossEntropyLoss()
#optimizer = torch.optim.Adam(model.parameters(), lr=correct_learning_rate)
#optimizer = torch.optim.SGD(model.parameters(), lr=correct_learning_rate)
#optimizer = torch.optim.Adadelta(model.parameters(), lr=correct_learning_rate)
optimizer = torch.optim.Adagrad(model.parameters(), lr=correct_learning_rate)
start_time = time.time()
cor_min_rate = 19995
cor_max_rate = 20005
incor_min_rate = 67
incor_max_rate = 72
# Training
for epoch in range(0, num_epochs):
train_correct = 0.
train_total = 0.
dev_correct = 0.
dev_total = 0.
correct_count = 0
incorrect_count = 0
correct_rand_ratio = getRandom(cor_min_rate, cor_max_rate)
incorrect_rand_ratio = getRandom(incor_min_rate, incor_max_rate)
for i, (images, labels) in enumerate(train_loader):
images = Variable(images.view(-1, 28*28))
labels = Variable(labels)
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
# Checking for our extra reinforcement
_, predicted = torch.max(outputs.data, 1)
train_total += labels.size(0)
current_correct = (predicted == labels).sum()
current_incorrect = batch_size - current_correct
train_correct += (predicted == labels).sum()
# Alright so what's the idea.
# 1. Dual learning rates - one for correct answers and one for incorrect answers
# 2. The learning rates are updated as we get more and more correct and incorrect answers
#
# Steps:
# Run it through, figure out correctness.
# Determine if we need to update the learning rate and update it (getRandom)
# Use the correct learning rate based on what the answer is.
ex_correct_or_incorrect = 0
if current_correct >= current_incorrect:
correct_count += current_correct
incorrect_count += current_incorrect
ex_correct_or_incorrect = 1
else:
correct_count += current_correct
incorrect_count += current_incorrect
ex_correct_or_incorrect = 0
# Update our learning rate based on our correct and incorrect responses
if correct_count >= correct_rand_ratio:
correct_learning_rate = correct_learning_rate - cor_lr_change
correct_count = 0
correct_rand_ratio = getRandom(cor_min_rate, cor_max_rate)
elif incorrect_count >= incorrect_rand_ratio:
incorrect_learning_rate = incorrect_learning_rate + incor_lr_change
incorrect_count = 0
incorrect_rand_ratio = getRandom(incor_min_rate, incor_max_rate)
for param_group in optimizer.param_groups:
if ex_correct_or_incorrect:
param_group['lr'] = correct_learning_rate
else:
param_group['lr'] = incorrect_learning_rate
optimizer.step()
# Grab test accuracy
test_correct = 0.
test_total = 0.
for test_images, test_labels in test_loader:
test_images = Variable(test_images.view(-1, 28*28))
test_outputs = model(test_images)
_, test_predicted = torch.max(test_outputs.data, 1)
test_total += test_labels.size(0)
test_correct += (test_predicted == test_labels).sum()
test_correct = test_correct.item()
test_acc = (100. * test_correct / test_total)
test_epoch_acc_output.append(test_acc)
cor_lr_output.append(correct_learning_rate)
incor_lr_output.append(incorrect_learning_rate)
e_acc = (100. * train_correct.item() / train_total)
print("Accuracy of network for this batch: %.4f %%" % (e_acc))
epoch_acc_output.append(e_acc)
end_time = time.time()
print("Training acc per epoch: ", epoch_acc_output)
print("Testing acc per epoch: ", test_epoch_acc_output)
print("Training time is", (end_time - start_time))
print("Final Correct Learning rate is", correct_learning_rate)
print("Final Incorrect Learning rate is", incorrect_learning_rate)
test_epoch_print = numpy.asarray(test_epoch_acc_output)
numpy.savetxt("test_out.csv", test_epoch_print, delimiter=",")
epoch_print = numpy.asarray(epoch_acc_output)
numpy.savetxt("train_out.csv", epoch_print, delimiter=",")
cor_lr_print = numpy.asarray(cor_lr_output)
numpy.savetxt("cor_lr_out.csv", cor_lr_print, delimiter=",")
incor_lr_print = numpy.asarray(incor_lr_output)
numpy.savetxt("incor_lr_out.csv", incor_lr_print, delimiter=",")