예제 #1
0
def test_transform():
    g = create_test_heterograph()
    x = F.randn((3, 5))
    g.nodes['user'].data['h'] = x

    new_g = dgl.metapath_reachable_graph(g, ['follows', 'plays'])

    assert new_g.ntypes == ['user', 'game']
    assert new_g.number_of_edges() == 3
    assert F.asnumpy(new_g.has_edges_between([0, 0, 1], [0, 1, 1])).all()

    new_g = dgl.metapath_reachable_graph(g, ['follows'])

    assert new_g.ntypes == ['user']
    assert new_g.number_of_edges() == 2
    assert F.asnumpy(new_g.has_edges_between([0, 1], [1, 2])).all()
예제 #2
0
def train(args):
    set_random_seed(args.seed)
    device = get_device(args.device)
    data, g, feats, labels, predict_ntype, relations, neighbor_sizes, \
        pos, pos_threshold, train_mask, val_mask, test_mask = load_data(args.dataset, device)
    bgs = [g[rel] for rel in relations]  # 邻居-目标顶点二分图
    mgs = [
        dgl.add_self_loop(
            dgl.remove_self_loop(dgl.metapath_reachable_graph(g,
                                                              mp))).to(device)
        for mp in data.metapaths
    ]  # 基于元路径的邻居同构图

    model = HeCo([feat.shape[1] for feat in feats], args.num_hidden,
                 args.feat_drop, args.attn_drop, neighbor_sizes,
                 len(data.metapaths), args.tau, args.lambda_).to(device)
    optimizer = optim.Adam(model.parameters(), lr=args.lr)
    for epoch in range(args.epochs):
        model.train()
        loss = model(bgs, mgs, feats, pos)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        print('Epoch {:d} | Train Loss {:.4f}'.format(epoch, loss.item()))
    evaluate(model, mgs, feats[0], labels, data.num_classes, train_mask,
             test_mask, args.seed)
예제 #3
0
def train(args):
    set_random_seed(args.seed)
    if args.hetero:
        data = HETERO_DATASET[args.dataset]()
        g = data[0]
        gs = [
            dgl.metapath_reachable_graph(g, metapath)
            for metapath in data.metapaths
        ]
        for i in range(len(gs)):
            gs[i] = dgl.add_self_loop(dgl.remove_self_loop(gs[i]))
        ntype = data.predict_ntype
        num_classes = data.num_classes
        features = g.nodes[ntype].data['feat']
        labels = g.nodes[ntype].data['label']
        train_mask = g.nodes[ntype].data['train_mask']
        val_mask = g.nodes[ntype].data['val_mask']
        test_mask = g.nodes[ntype].data['test_mask']
    else:
        data = DATASET[args.dataset]()
        gs = data[0]
        num_classes = data.num_classes
        features = gs[0].ndata['feat']
        labels = gs[0].ndata['label']
        train_mask = gs[0].ndata['train_mask']
        val_mask = gs[0].ndata['val_mask']
        test_mask = gs[0].ndata['test_mask']

    model = HAN(len(gs), features.shape[1], args.num_hidden, num_classes,
                args.num_heads, args.dropout)
    optimizer = optim.Adam(model.parameters(),
                           lr=args.lr,
                           weight_decay=args.weight_decay)

    score = micro_macro_f1_score if args.task == 'clf' else nmi_ari_score
    if args.task == 'clf':
        metrics = 'Epoch {:d} | Train Loss {:.4f} | Train Micro-F1 {:.4f} | Train Macro-F1 {:.4f}' \
                  ' | Val Micro-F1 {:.4f} | Val Macro-F1 {:.4f}'
    else:
        metrics = 'Epoch {:d} | Train Loss {:.4f} | Train NMI {:.4f} | Train ARI {:.4f}' \
                  ' | Val NMI {:.4f} | Val ARI {:.4f}'
    for epoch in range(args.epochs):
        model.train()
        logits = model(gs, features)
        loss = F.cross_entropy(logits[train_mask], labels[train_mask])
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        train_metrics = score(logits[train_mask], labels[train_mask])
        val_metrics = score(logits[val_mask], labels[val_mask])
        print(metrics.format(epoch, loss.item(), *train_metrics, *val_metrics))

    test_metrics = evaluate(model, gs, features, labels, test_mask, score)
    if args.task == 'clf':
        print('Test Micro-F1 {:.4f} | Test Macro-F1 {:.4f}'.format(
            *test_metrics))
    else:
        print('Test NMI {:.4f} | Test ARI {:.4f}'.format(*test_metrics))
예제 #4
0
    def forward(self, g, h):
        semantic_embeddings = {'movie': [], 'actor': [], 'director': []}
        if self._cached_graph is None or self._cached_graph is not g:
            self._cached_graph = g
            self._cached_coalesced_graph.clear()
            for meta_path in self.meta_paths:
                if len(meta_path) > 1:
                    self._cached_coalesced_graph[
                        meta_path] = dgl.metapath_reachable_graph(
                            g, meta_path
                        )  # return a homogeneous or unidirectional bipartite graphs
                elif len(meta_path) == 1:
                    if meta_path in {
                        ('am', ),
                    }:
                        print('******************am**********************')
                        self._cached_coalesced_graph[
                            meta_path] = dgl.edge_type_subgraph(
                                g, [('actor', 'am', 'movie')])
                    elif meta_path in {('dm', )}:
                        print('******************dm**********************')
                        self._cached_coalesced_graph[
                            meta_path] = dgl.edge_type_subgraph(
                                g, [('director', 'dm', 'movie')])

        for i, meta_path in enumerate(self.meta_paths):
            new_g = self._cached_coalesced_graph[meta_path]
            if new_g.is_homogeneous:
                ntype = new_g.ntypes[0]
                semantic_embeddings[ntype].append(self.hsmg_layers[i](
                    new_g, h[ntype]).flatten(1))
            else:
                if meta_path in {
                    ('am', ),
                }:
                    h_ = (h['actor'], h['movie'])
                    semantic_embeddings['movie'].append(self.hsmg_layers[i](
                        new_g, h_))
                elif meta_path in {('dm', )}:
                    h_ = (h['director'], h['movie'])
                    semantic_embeddings['movie'].append(self.hsmg_layers[i](
                        new_g, h_))

        embedings = {}
        for ntype in semantic_embeddings.keys():
            if ntype == 'movie':
                semantic_embeddings[ntype] = torch.stack(
                    semantic_embeddings[ntype], dim=1)
                embedings[ntype] = self.semantic_attention_m(
                    semantic_embeddings[ntype])
            # elif ntype=='actor' and semantic_embeddings[ntype]:
            #     semantic_embeddings[ntype] = torch.stack(semantic_embeddings[ntype], dim=1)
            #     embedings[ntype] = self.semantic_attention_a(semantic_embeddings[ntype])
            # elif ntype=='director' and semantic_embeddings[ntype]:
            #     semantic_embeddings[ntype] = torch.stack(semantic_embeddings[ntype], dim=1)
            #     embedings[ntype] = self.semantic_attention_d(semantic_embeddings[ntype])
        return embedings
예제 #5
0
    def forward(self, g, h):
        semantic_embeddings = []

        if self._cached_graph is None or self._cached_graph is not g:  # 第一次,建立一张metapath下的异构图
            self._cached_graph = g
            self._cached_coalesced_graph.clear()
            for meta_path in self.meta_paths:
                self._cached_coalesced_graph[meta_path] = dgl.metapath_reachable_graph(
                        g, meta_path)  # 构建异构图的邻居;
        # self._cached_coalesced_graph 多个metapath下的异构图
        for i, meta_path in enumerate(self.meta_paths):
            new_g = self._cached_coalesced_graph[meta_path]  # meta-path下的节点邻居图
            semantic_embeddings.append(self.gat_layers[i](new_g, h).flatten(1))   # 图attention
        semantic_embeddings = torch.stack(semantic_embeddings, dim=1)                  # (N, M, D * K)

        return self.semantic_attention(semantic_embeddings)                            # (N, D * K)
예제 #6
0
    def forward(self, g, h):
        semantic_embeddings = []
        #obtain metapath reachable graph
        if self._cached_graph is None or self._cached_graph is not g:
            self._cached_graph = g
            self._cached_coalesced_graph.clear()
            for meta_path_pattern in self.meta_path_patterns:
                self._cached_coalesced_graph[
                    meta_path_pattern] = dgl.metapath_reachable_graph(
                        g, meta_path_pattern)

        for i, meta_path_pattern in enumerate(self.meta_path_patterns):
            new_g = self._cached_coalesced_graph[meta_path_pattern]
            semantic_embeddings.append(self.gat_layers[i](new_g, h).flatten(1))
        semantic_embeddings = torch.stack(semantic_embeddings,
                                          dim=1)  # (N, M, D * K)

        return self.semantic_attention(semantic_embeddings)  # (N, D * K)
예제 #7
0
파일: model.py 프로젝트: junxincai/HMSG
    def forward(self, g, h):
        semantic_embeddings = {'user':[], 'item':[]}
        if self._cached_graph is None or self._cached_graph is not g:
            self._cached_graph = g
            self._cached_coalesced_graph.clear()
            for meta_path in self.meta_paths:
                if len(meta_path) > 1:
                    self._cached_coalesced_graph[meta_path] = dgl.metapath_reachable_graph(g, meta_path)  # return a homogeneous or unidirectional bipartite graphs
                elif len(meta_path) == 1:
                    if meta_path in {('ui',)}:
                        print('******************ui**********************')
                        self._cached_coalesced_graph[meta_path] = dgl.edge_type_subgraph(g, [('user', 'ui', 'item')])
                    elif meta_path in {('iu',)}:
                        print('******************iu**********************')
                        self._cached_coalesced_graph[meta_path] = dgl.edge_type_subgraph(g, [('item', 'iu', 'user')])

        for i, meta_path in enumerate(self.meta_paths):
            new_g = self._cached_coalesced_graph[meta_path]
            if new_g.is_homogeneous:
                ntype = new_g.ntypes[0]
                if ntype == 'user':
                    h_ = h['user']
                elif ntype == 'item':
                    h_ = h['item']
                semantic_embeddings[ntype].append(self.gat_layers[i](new_g, h_).flatten(1))

            else:  
                if meta_path in {('ui',), }:
                    semantic_embeddings['item'].append(self.gat_layers[i](new_g, (h['user'], h['item'])))
                elif meta_path in {('iu',)}:
                    semantic_embeddings['user'].append(self.gat_layers[i](new_g, (h['item'], h['user'])))

        embedings = {}
        for ntype in semantic_embeddings.keys():
            if ntype=='user':
                semantic_embeddings[ntype] = torch.stack(semantic_embeddings[ntype], dim=1) 
                embedings[ntype] = self.semantic_attention_u(semantic_embeddings[ntype])  
            elif ntype=='item' and semantic_embeddings[ntype]:
                semantic_embeddings[ntype] = torch.stack(semantic_embeddings[ntype], dim=1) 
                embedings[ntype] = self.semantic_attention_i(semantic_embeddings[ntype])
        return embedings