簡體   English   中英

如何從有向圖實現 PyTorch NN

[英]How to implement a PyTorch NN from a directed graph

我是 Pytorch 的新手並自學,我想創建接受有向圖的 ANN。 我還想將每個連接的預定義權重和偏差傳遞給它,但現在願意忽略它。

我對這些條件的動機是我正在嘗試實現NEAT算法,該算法基本上使用遺傳算法來進化網絡。

例如,讓graph = dict{'1':[[], [4, 7]], '2':[[], [6]], '3':[[], [6]], '4':[[1, 7], []], '5':[[7], []], '6':[[2, 3], [7]], '7':[[1, 6], [4, 5]]}表示有向圖。

示例圖

我的想法是:

class Net(torch.nn.Module):
    def __init__(self, graph):
        super(Net, self).__init__()
        self.graph = graph
        self.walk_graph()

    def walk_graph(self):
        graph_remaining = copy.deepcopy(self.graph)
        done = False  # Has every node/connection been processed?
        while not done:
            processed = []  # list of tuples, of a node and the nodes it outputs to
            for node_id in graph_remaining.keys():
                if len(graph_remaining[node_id][0]) == 0:  # if current node has no incoming connections
                    try:
                        # if current node has been processed, but waited for others to finish
                        if callable(getattr(self, 'layer{}'.format(node_id))):
                            D_in = len(eval('self.layer{}'.format(node_id)).in_features)
                            D_out = len(eval('self.layer{}'.format(node_id)).out_features)
                            setattr(self, 'layer{}'.format(node_id), torch.nn.Linear(D_in, D_out))
                        cat_list = [] # list of input tensors
                        for i in self.graph[node_id][0]: # search the entire graph for inputs
                            cat_list.append(globals()['out_{}'.format(i)]) # add incoming tensor to list
                        # create concatenated tensor for incoming tensors
                        # I'm not confident about this
                        globals()['in_{}'.format(node_id)] = torch.cat(cat_list, len(cat_list))
                    except AttributeError:  # if the current node hasn't been waiting
                        try:
                            setattr(self, 'layer{}'.format(node_id), torch.nn.Linear(len(self.graph[node_id][0]), len(self.graph[node_id][1])))
                        except ZeroDivisionError:  # Input/Output nodes have zero inputs/outputs in the graph
                            setattr(self, 'layer{}'.format(node_id), torch.nn.Linear(1, 1))
                    globals()['out_{}'.format(node_id)] = getattr(self, 'layer' + node_id)(globals()['in_{}'.format(node_id)])
                    processed.append((node_id, graph_remaining[node_id][1]))

            for node_id, out_list in processed:
                for out_id in out_list:
                    try:
                        graph_remaining[str(out_id)][0].remove(int(node_id))
                    except ValueError:
                        pass
                try:
                    del graph_remaining[node_id]
                except KeyError:
                    pass

            done = True
            for node_id in self.graph.keys():
                if len(graph_remaining[node_id][0]) != 0 or len(graph_remaining[node_id][1]) != 0:
                    done = False
        return None

我在這方面有點超出我的舒適區,但是如果您有更好的主意,或者可以指出這是如何存在致命缺陷的,我會全力以赴。 我知道我缺少轉發功能,可以使用一些有關如何重組的建議。

由於您不打算對網絡進行任何實際訓練,因此在這種情況下,PyTorch 可能不是您的最佳選擇。

NEAT 是關於重組和變異神經網絡——包括它們的結構、它們的權重和偏差——從而獲得更好的結果。 PyTorch 通常是一個深度學習框架,這意味着您定義網絡的結構(或架構),然后使用隨機梯度下降等算法更新權重和偏差以提高性能。 因此,PyTorch 基於神經網絡的模塊和子模塊工作,如全連接層、卷積層等。

這種差異的問題在於,NEAT 不僅要求您存儲比 PyTorch 支持的更多關於單個節點的信息(例如它們用於重組的 ID 等),而且它也不太適合“分層” ” 深度學習框架的方法。

在我看來,您最好自己通過網絡實現前向傳遞。 如果您不確定如何做到這一點,這個視頻給出了一個很好的解釋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM