forge/ethyr/torch/policy.py (213 lines of code) (raw):

#Previous networks tried. Fully connected nets are much #easier to get working than conv nets. from pdb import set_trace as T import torch from torch import nn from torch.nn import functional as F from forge.ethyr.torch import utils as tu class Attention(nn.Module): def __init__(self, xDim, yDim): super().__init__() self.fc = torch.nn.Linear(2*xDim, yDim) #Compute all normalized scores def score(args, x, normalize=True, scale=False): scores = torch.matmul(args, x.transpose(0, 1)) if scale: scores = scores / (32**0.5) if normalize: scores = Attention.normalize(scores) return scores.view(1, -1) #Normalize exp def normalize(x): b = x.max() y = torch.exp(x - b) return y / y.sum() def attend(self, args, scores): attn = args * scores return torch.sum(attn, dim=0).view(1, -1) def forward(self, args, x, normalize=True): scores = Attention.score(args, x, normalize) scores = self.attend(args, scores) scores = torch.cat((scores, x), dim=1) scores = torch.nn.functional.tanh(self.fc(scores)) return scores class AttnCat(nn.Module): def __init__(self, h): super().__init__() self.fc1 = torch.nn.Linear(2*h, h) self.fc2 = torch.nn.Linear(h, 1) self.h = h def forward(self, x, args): n = args.shape[0] x = x.expand(n, self.h) xargs = torch.cat((x, args), dim=1) x = F.relu(self.fc1(xargs)) x = self.fc2(x) return x.view(1, -1) class AtnNet(nn.Module): def __init__(self, h, nattn): super().__init__() self.fc1 = torch.nn.Linear(h, nattn) def forward(self, stim, args): atn = self.fc1(stim) return atn class ArgNet(nn.Module): def __init__(self, h): super().__init__() self.attn = AttnCat(h) #Arguments: stim, action/argument embedding def forward(self, key, atn, args): atn = atn.expand_as(args) vals = torch.cat((atn, args), 1) arg = self.attn(key, vals) argIdx = classify(arg) return argIdx, argd class Env(nn.Module): def __init__(self, config): super().__init__() h = config.HIDDEN entDim = 12 + 255 self.fc1 = torch.nn.Linear(entDim+1800+2*h, h) self.embed = torch.nn.Embedding(7, 7) self.ent1 = torch.nn.Linear(entDim, 2*h) def forward(self, conv, flat, ents): tiles, nents = conv[0], conv[1] tiles = self.embed(tiles.view(-1).long()).view(-1) nents = nents.view(-1) conv = torch.cat((tiles, nents)) ents = self.ent1(ents) ents, _ = torch.max(ents, 0) x = torch.cat((conv.view(-1), flat, ents)).view(1, -1) x = torch.nn.functional.relu(self.fc1(x)) return x class Full(nn.Module): def __init__(self, h): super().__init__() self.conv1 = tu.Conv2d(8, int(h/2), 3, stride=2) self.conv2 = tu.Conv2d(int(h/2), h, 3, stride=2) self.fc1 = torch.nn.Linear(6+4*4*h + h, h) #self.fc1 = torch.nn.Linear(5+4*4*h, h) self.ent1 = torch.nn.Linear(6, h) def forward(self, conv, flat, ents): if len(conv.shape) == 3: conv = conv.view(1, *conv.shape) flat = flat.view(1, *flat.shape) x, batch = conv, conv.shape[0] x = torch.nn.functional.relu(self.conv1(x)) x = torch.nn.functional.relu(self.conv2(x)) x = x.view(batch, -1) ents = self.ent1(ents) ents, _ = torch.max(ents, 0) ents = ents.view(batch, -1) #x = torch.cat((x, flat), dim=1) x = torch.cat((x, flat, ents), dim=1) x = torch.nn.functional.relu(self.fc1(x)) return x class FC1(nn.Module): def __init__(self, h): super().__init__() #h = config.HIDDEN self.fc1 = torch.nn.Linear(12+1800, h) def forward(self, conv, flat, ents): x = torch.cat((conv.view(-1), flat)).view(1, -1) x = torch.nn.functional.relu(self.fc1(x)) return x class FC2(nn.Module): def __init__(self, config): super().__init__() h = config.HIDDEN self.fc1 = torch.nn.Linear(12+1800+2*h, h) self.ent1 = torch.nn.Linear(12, 2*h) self.embed = torch.nn.Embedding(7, 7) def forward(self, conv, flat, ents): tiles, nents = conv[0], conv[1] tiles = self.embed(tiles.view(-1).long()).view(-1) nents = nents.view(-1) conv = torch.cat((tiles, nents)) ents = self.ent1(ents) ents, _ = torch.max(ents, 0) x = torch.cat((conv.view(-1), flat, ents)).view(1, -1) x = torch.nn.functional.relu(self.fc1(x)) return x #Use this one. Nice embedding property. #They all work pretty well class FC3(nn.Module): def __init__(self, h): super().__init__() self.conv1 = tu.Conv2d(8, 8, 1) self.fc1 = tu.FCRelu(5+1800, h) def forward(self, conv, flat, ents): conv = conv.view(1, *conv.shape) x = self.conv1(conv) x = torch.cat((x.view(-1), flat)).view(1, -1) x = self.fc1(x) return x class FC4(nn.Module): def __init__(self, h): super().__init__() self.conv1 = tu.Conv2d(8, 4, 1) self.fc1 = tu.FCRelu(5+900, h) def forward(self, conv, flat, ents): conv = conv.view(1, *conv.shape) x = self.conv1(conv) x = torch.cat((x.view(-1), flat)).view(1, -1) x = self.fc1(x) return x class FCEnt(nn.Module): def __init__(self, h): super().__init__() self.fc1 = torch.nn.Linear(5+1800+h, h) self.ent1 = torch.nn.Linear(5, h) def forward(self, conv, flat, ents): ents = self.ent1(ents) ents, _ = torch.max(ents, 0) ents = ents.view(-1) x = torch.cat((conv.view(-1), flat, ents)).view(1, -1) x = torch.nn.functional.relu(self.fc1(x)) return x class FCAttention(nn.Module): def __init__(self, h): super().__init__() self.fc1 = torch.nn.Linear(5+1800+h, h) self.ent1 = torch.nn.Linear(5, h) self.attn = Attention(h, h) def forward(self, conv, flat, ents): ents = self.ent1(ents) T() ents = self.attn(ents) ents = ents.view(-1) x = torch.cat((conv.view(-1), flat, ents)).view(1, -1) x = torch.nn.functional.relu(self.fc1(x)) return x class CNN1(nn.Module): def __init__(self, h): super().__init__() self.conv1 = tu.Conv2d(8, h, 5, stride=3) self.conv2 = tu.Conv2d(h, h, 5, stride=3) self.fc1 = torch.nn.Linear(4*h+5, h) def forward(self, conv, flat, ents): x = conv.view(1, *conv.shape) x = torch.nn.functional.relu(self.conv1(x)) 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)) return x.view(1, -1) class CNN2(nn.Module): def __init__(self, h): super().__init__() self.conv1 = tu.Conv2d(8, h, 3, stride=2) self.conv2 = tu.Conv2d(h, h, 3, stride=2) self.fc1 = torch.nn.Linear(16*h+5, h) def forward(self, conv, flat, ents): x = conv.view(1, *conv.shape) x = torch.nn.functional.relu(self.conv1(x)) 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)) return x.view(1, -1) class CNN3(nn.Module): def __init__(self, h): super().__init__() self.conv1 = tu.ConvReluPool(8, h, 5) self.conv2 = tu.ConvReluPool(h, h//2, 5) self.fc1 = torch.nn.Linear(h//2*7*7+5, h) def forward(self, conv, flat, ents): x = conv.view(1, *conv.shape) x = torch.nn.functional.relu(self.conv1(x)) 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)) return x.view(1, -1)