-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathtrain.py
More file actions
104 lines (88 loc) · 2.82 KB
/
Copy pathtrain.py
File metadata and controls
104 lines (88 loc) · 2.82 KB
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
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
from torchvision import datasets, transforms
import os
import matplotlib.pyplot as plt
import math
from model import SparseAutoencoder
# global constants
BATCH_SIZE = 32
BETA = 3
RHO = 0.01
N_INP = 784
N_HIDDEN = 300
N_EPOCHS = 1
use_sparse = False
rho = torch.FloatTensor([RHO for _ in range(N_HIDDEN)]).unsqueeze(0)
# FashionMNIST data loading
root = './data'
if not os.path.exists(root):
os.mkdir(root)
trans = transforms.Compose([transforms.ToTensor()])
train_set = datasets.FashionMNIST(root=root, train=True, transform=trans, download=True)
test_set = datasets.FashionMNIST(root=root, train=False, transform=trans, download=True)
train_loader = torch.utils.data.DataLoader(
dataset=train_set,
batch_size=BATCH_SIZE,
shuffle=True)
test_loader = torch.utils.data.DataLoader(
dataset=test_set,
batch_size=BATCH_SIZE,
shuffle=False)
auto_encoder = SparseAutoencoder(N_INP, N_HIDDEN)
optimizer = optim.Adam(auto_encoder.parameters(), lr=1e-3)
def kl_divergence(p, q):
'''
args:
2 tensors `p` and `q`
returns:
kl divergence between the softmax of `p` and `q`
'''
p = F.softmax(p)
q = F.softmax(q)
s1 = torch.sum(p * torch.log(p / q))
s2 = torch.sum((1 - p) * torch.log((1 - p) / (1 - q)))
return s1 + s2
# set plot and view data for visualization
N_COLS = 8
N_ROWS = 4
view_data = [test_set[i][0] for i in range(N_ROWS * N_COLS)]
plt.figure(figsize=(20, 4))
for epoch in range(N_EPOCHS):
for b_index, (x, _) in enumerate(train_loader):
x = x.view(x.size()[0], -1)
x = Variable(x)
encoded, decoded = auto_encoder(x)
MSE_loss = (x - decoded) ** 2
MSE_loss = MSE_loss.view(1, -1).sum(1) / BATCH_SIZE
if use_sparse:
rho_hat = torch.sum(encoded, dim=0, keepdim=True)
sparsity_penalty = BETA * kl_divergence(rho, rho_hat)
loss = MSE_loss + sparsity_penalty
else:
loss = MSE_loss
optimizer.zero_grad()
loss.backward()
optimizer.step()
print("Epoch: [%3d], Loss: %.4f" %(epoch + 1, loss.data))
for i in range(N_ROWS * N_COLS):
# original image
r = i // N_COLS
c = i % N_COLS + 1
ax = plt.subplot(2 * N_ROWS, N_COLS, 2 * r * N_COLS + c)
plt.imshow(view_data[i].squeeze())
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
# reconstructed image
ax = plt.subplot(2 * N_ROWS, N_COLS, 2 * r * N_COLS + c + N_COLS)
x = Variable(view_data[i])
e, y = auto_encoder(x.view(1, -1))
plt.imshow(y.detach().squeeze().numpy().reshape(28, 28))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()