def set_graph(self): self.graph = {} for nname, node in self.nodes.items(): parent = node.parent for par in tolist(parent.keys()): if par in self.inputs.keys(): continue if par in self.graph.keys(): self.graph[par] =\ tolist(self.graph[par]) + [node.name] else: self.graph[par] = node.name sorted_nodes = topological_sort(self.graph) if len(self.graph) > 0: for i in xrange(len(self.nodes)): self.sorted_nodes.append(sorted_nodes.popleft()) for node in self.nodes: parent = self.nodes[node].parent for par in tolist(parent.keys()): try: self.nodes[node].parent[par] = self.inputs_dim[par] except: if self.nodes[par].nout is not None: # Assume this is FullyConnectedLayer self.nodes[node].parent[par] = self.nodes[par].nout else: # Assume this is ConvLayer try: self.nodes[node].parent[par] = self.nodes[ par].outshape except: # Assume this is MaxPool2D self.nodes[par].initialize() self.nodes[node].parent[par] = self.nodes[ par].outshape if hasattr(node, 'recurrent'): recurrent = self.nodes[node].recurrent for rec in tolist(recurrent.keys()): self.nodes[node].recurrent[rec] = self.nodes[rec].nout
def set_graph(self): self.graph = {} for nname, node in self.nodes.items(): parent = node.parent for par in tolist(parent.keys()): if par in self.inputs.keys(): continue if par in self.graph.keys(): self.graph[par] =\ tolist(self.graph[par]) + [node.name] else: self.graph[par] = node.name sorted_nodes = topological_sort(self.graph) if len(self.graph) > 0: for i in xrange(len(self.nodes)): self.sorted_nodes.append(sorted_nodes.popleft()) for node in self.nodes: parent = self.nodes[node].parent for par in tolist(parent.keys()): try: self.nodes[node].parent[par] = self.inputs_dim[par] except: if self.nodes[par].nout is not None: # Assume this is FullyConnectedLayer self.nodes[node].parent[par] = self.nodes[par].nout else: # Assume this is ConvLayer try: self.nodes[node].parent[par] = self.nodes[par].outshape except: # Assume this is MaxPool2D self.nodes[par].initialize() self.nodes[node].parent[par] = self.nodes[par].outshape if hasattr(node, 'recurrent'): recurrent = self.nodes[node].recurrent for rec in tolist(recurrent.keys()): self.nodes[node].recurrent[rec] = self.nodes[rec].nout
def scan_fn(self, *args): next_recurrence = [] sorted_nodes = topological_sort(self.graph) inputs = tolist(args[:self.nseqs]) recurrence = tolist(args[self.nseqs:self.nseqs+self.nrecur]) inputs += tolist(args[self.nseqs+self.nrecur:self.nseqs+self.noutputs]) nonseqs = tolist(args[self.nseqs+self.noutputs:]) for nname, node in self.nodes.items(): for i, (aname, arg) in enumerate(self.recur_args.items()): if node is arg: node.rec_out = recurrence[i] if len(sorted_nodes) != 0: for node in self.sorted_nodes: inp = [] parent = self.nodes[node].parent for par in parent: tok = 1 for inp2 in inputs: if par in inp2.name: inp.append(inp2) tok = 0 break if tok: inp.append(self.nodes[par].out) if self.nodes[node] in self.recur_args.values(): rec_inp = [] recurrent = self.nodes[node].recurrent for rec in recurrent: rec_inp.append(self.nodes[rec].rec_out) inp = [inp, rec_inp] self.nodes[node].out = self.nodes[node].fprop(inp) next_recurrence.append(self.nodes[node].out) else: self.nodes[node].out = self.nodes[node].fprop(inp) else: # Assume that you have only single depth (parallel) graph # Instead of Queue use for-loop to forcibly run the operation for node in self.nodes: inp = [] parent = self.nodes[node].parent for par in parent: tok = 1 for inp2 in inputs: if par in inp2.name: inp.append(inp2) tok = 0 break if tok: inp.append(self.nodes[par].out) if self.nodes[node] in self.recur_args.values(): rec_inp = [] recurrent = self.nodes[node].recurrent for rec in recurrent: rec_inp.append(self.nodes[rec].rec_out) inp = [inp, rec_inp] self.nodes[node].out = self.nodes[node].fprop(inp) next_recurrence.append(self.nodes[node].out) else: self.nodes[node].out = self.nodes[node].fprop(inp) required_outputs = [] if self.iterators is not None: for arg in self.iterators: for node in self.nodes.values(): if node is arg: required_outputs.append(node.out) if self.output_args is not None: for arg in self.output_args: for node in self.nodes.values(): if node is arg: required_outputs.append(node.out) return next_recurrence + required_outputs