jsuarez/Curiosity.py (63 lines of code) (raw):
class PhiNet(nn.Module):
def __init__(self, xdim, h):
super().__init__()
self.conv1 = Conv2d(8, int(h/2), 3, stride=2)
self.conv2 = Conv2d(int(h/2), h, 3, stride=2)
self.fc1 = torch.nn.Linear(5+4*4*h, h)
self.fc2 = torch.nn.Linear(h, h)
def forward(self, conv, flat):
x = torch.nn.functional.relu(self.conv1(conv))
x = torch.nn.functional.relu(self.conv2(x))
x = x.view(-1)
x = torch.cat((x, flat))
x = torch.nn.functional.relu(self.fc1(x))
x = self.fc2(x)
return x.view(1, -1)
class ForwardsNet(nn.Module):
def __init__(self, xdim, h, ydim):
super().__init__()
self.loss = torch.nn.MSELoss()
self.fc1 = torch.nn.Linear(NATN+h, h)
self.fc2 = torch.nn.Linear(h, h)
def forward(self, atn, phiPrev, phi):
atnHot = torch.zeros(NATN)
atnHot.scatter_(0, atn, 1)
atnHot = atnHot.view(1, -1)
x = torch.cat((atnHot, phiPrev), 1)
x = torch.nn.functional.relu(self.fc1(x))
x = self.fc2(x)
#Stop grads on phi
loss = self.loss(x, phi)
return loss
class BackwardsNet(nn.Module):
def __init__(self, h, ydim):
super().__init__()
self.loss = torch.nn.CrossEntropyLoss()
self.fc1 = torch.nn.Linear(2*h, h)
self.fc2 = torch.nn.Linear(h, ydim)
def forward(self, phiPrev, phi, atn):
x = torch.cat((phiPrev, phi), 1)
x = torch.nn.functional.relu(self.fc1(x))
x = self.fc2(x)
loss = self.loss(x, atn)
return loss
class CurNet(nn.Module):
def __init__(self, xdim, h, ydim):
super().__init__()
self.phi = PhiNet(xdim, h)
self.forwardsDynamics = ForwardsNet(xdim, h, ydim)
self.backwardsDynamics = BackwardsNet(h, ydim)
def forward(self, ents, entID, atn, conv, flat):
conv = conv.view(1, *conv.size())
conv = conv.permute(0, 3, 1, 2)
if entID in ents:
atn, convPrev, flatPrev = ents[entID]
phiPrev = self.phi(convPrev, flatPrev)
phi = self.phi(conv, flat)
#Stop both phi's on forward, train both on backward. Confirmed by Harri
fLoss = self.forwardsDynamics(atn, phiPrev.detach(), phi.detach())
bLoss = self.backwardsDynamics(phiPrev, phi, atn)
ri = fLoss.data[0]
li = 0.20*fLoss + 0.80*bLoss
else:
ri, li = 0, torch.tensor(0.0)
#ri, li = 0, tu.var(np.zeros(1))
ents[entID] = (atn, conv, flat)
return ri, li